diff options
author | Mike Frysinger <vapier@gentoo.org> | 2010-08-15 20:26:49 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2010-08-15 20:26:49 -0400 |
commit | 4c1eee83e412298d5c3019f386540ce0af0badc7 (patch) | |
tree | 6bc9c62b4de7548131f1b9a286761065806b8f66 /libsandbox/libsandbox.c | |
parent | libsandbox: don't swallow SIGCHLD notifications (diff) | |
download | sandbox-4c1eee83e412298d5c3019f386540ce0af0badc7.tar.gz sandbox-4c1eee83e412298d5c3019f386540ce0af0badc7.tar.bz2 sandbox-4c1eee83e412298d5c3019f386540ce0af0badc7.zip |
libsandbox: avoid passing same buffer to erealpath
The erealpath function modifies the storage buffer given to it in place
and can misbehave if both the source and destination buffers point to the
same storage in memory. So fix the one case where we were doing this in
the canonicalize() function and add some run time checks to make sure this
doesn't crop up again.
URL: http://bugs.gentoo.org/292050
Reported-by: Hongjiu Zhang <voidprayer@gmail.com>
Reported-by: Fredric Johansson <johansson_fredric@hotmail.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'libsandbox/libsandbox.c')
-rw-r--r-- | libsandbox/libsandbox.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/libsandbox/libsandbox.c b/libsandbox/libsandbox.c index fd3d2ea..f3d98dd 100644 --- a/libsandbox/libsandbox.c +++ b/libsandbox/libsandbox.c @@ -155,6 +155,12 @@ int canonicalize(const char *path, char *resolved_path) return 0; } + /* We can't handle resolving a buffer inline (erealpath), + * so demand separate read and write strings. + */ + if (path == resolved_path) + sb_abort(); + retval = erealpath(path, resolved_path); if ((NULL == retval) && (path[0] != '/')) { @@ -168,10 +174,13 @@ int canonicalize(const char *path, char *resolved_path) if (NULL == egetcwd(resolved_path, SB_PATH_MAX - 2)) return -1; + char *copy = xstrdup(resolved_path); size_t len = strlen(resolved_path); snprintf(resolved_path + len, SB_PATH_MAX - len, "/%s", path); - if (NULL == erealpath(resolved_path, resolved_path)) { + char *ret = erealpath(resolved_path, resolved_path); + free(copy); + if (ret == NULL) { if (errno_is_too_long()) { /* The resolved path is too long for the buffer to hold */ return -1; |