aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2010-08-16 22:10:45 -0400
committerMike Frysinger <vapier@gentoo.org>2010-08-16 22:10:45 -0400
commitef2d8c1f96a176eba0e5eb265d8163824311a2fe (patch)
tree3794d0a834cf26ee3e60fcd8f1aab3a44f975990
parenttests: check rmdir functionality (diff)
downloadsandbox-2.3.tar.gz
sandbox-2.3.tar.bz2
sandbox-2.3.zip
libsandbox: tempish mkdir hack for broken symlinksv2.3
Some gnulib tests that are bundled with multiple GNU packages stress the POSIX correctness of mkdir behavior across broken symlinks. While this specific behavior under ssandbox doesn't really matter (as packages don't create broken symlinks and then need this errno value), it isn't really feasible to patch all the random packages. So add a smallish hack for now to keep them happy until something better can be formulated. URL: http://bugs.gentoo.org/297026 Reported-by: Diego E. Pettenò <flameeyes@gentoo.org> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-rw-r--r--libsandbox/wrapper-funcs/mkdirat_pre_check.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/libsandbox/wrapper-funcs/mkdirat_pre_check.c b/libsandbox/wrapper-funcs/mkdirat_pre_check.c
index ea9ff9a..c999e46 100644
--- a/libsandbox/wrapper-funcs/mkdirat_pre_check.c
+++ b/libsandbox/wrapper-funcs/mkdirat_pre_check.c
@@ -29,10 +29,25 @@ bool sb_mkdirat_pre_check(const char *func, const char *pathname, int dirfd)
*/
struct stat st;
if (0 == lstat(canonic, &st)) {
+ int new_errno;
if (is_env_on(ENV_SANDBOX_DEBUG))
SB_EINFO("EARLY FAIL", " %s(%s[%s]) @ lstat: %s\n",
func, pathname, canonic, strerror(errno));
- errno = EEXIST;
+
+ new_errno = EEXIST;
+
+ /* Hmm, is this a broken symlink we're trying to extend ? */
+ if (S_ISLNK(st.st_mode) && stat(pathname, &st) != 0) {
+ /* XXX: This awful hack should probably be turned into a
+ * common func that does a better job. For now, we have
+ * enough crap to catch gnulib tests #297026.
+ */
+ char *parent = strrchr(pathname, '/');
+ if (parent && (strcmp(parent, "/.") == 0 || strcmp(parent, "/..") == 0))
+ new_errno = ENOENT;
+ }
+
+ errno = new_errno;
return false;
}