aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'libsandbox/wrapper-funcs')
-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;
}