aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2010-08-15 20:26:49 -0400
committerMike Frysinger <vapier@gentoo.org>2010-08-15 20:26:49 -0400
commit4c1eee83e412298d5c3019f386540ce0af0badc7 (patch)
tree6bc9c62b4de7548131f1b9a286761065806b8f66 /libsandbox
parentlibsandbox: don't swallow SIGCHLD notifications (diff)
downloadsandbox-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')
-rw-r--r--libsandbox/canonicalize.c8
-rw-r--r--libsandbox/libsandbox.c11
2 files changed, 17 insertions, 2 deletions
diff --git a/libsandbox/canonicalize.c b/libsandbox/canonicalize.c
index 2166ac9..2bef6b1 100644
--- a/libsandbox/canonicalize.c
+++ b/libsandbox/canonicalize.c
@@ -76,8 +76,14 @@ erealpath(const char *name, char *resolved)
if (resolved == NULL) {
rpath = xmalloc(path_max);
- } else
+ } else {
+ /* We can't handle resolving a buffer inline, so demand
+ * separate read and write strings.
+ */
+ if (name == resolved)
+ sb_abort();
rpath = resolved;
+ }
rpath_limit = rpath + path_max;
recover = NULL;
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;