aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2012-12-24 19:41:49 -0500
committerMike Frysinger <vapier@gentoo.org>2012-12-24 19:50:59 -0500
commitdd726dcc6a95355d0e0cc949018d9c8aefc89a02 (patch)
tree29a1e76cb27599cc6d7504d41a4c100226375217
parentlibsandbox: handle open(O_NOFOLLOW) (diff)
downloadsandbox-dd726dcc6a95355d0e0cc949018d9c8aefc89a02.tar.gz
sandbox-dd726dcc6a95355d0e0cc949018d9c8aefc89a02.tar.bz2
sandbox-dd726dcc6a95355d0e0cc949018d9c8aefc89a02.zip
libsandbox: reject "" paths with *at funcs before checking the dirfd
When it comes to processing errors, an empty path is checked before an invalid dirfd. Make sure sandbox matches that behavior for the random testsuites out there that look for this. URL: https://bugs.gentoo.org/346929 Reported-by: Marien Zwart <marienz@gentoo.org> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-rw-r--r--libsandbox/wrapper-funcs/__pre_check.c2
-rw-r--r--libsandbox/wrapper-funcs/mkdirat_pre_check.c17
-rw-r--r--libsandbox/wrapper-funcs/openat_pre_check.c15
-rw-r--r--libsandbox/wrapper-funcs/unlinkat_pre_check.c17
-rw-r--r--libsandbox/wrappers.h2
-rwxr-xr-xtests/mkdirat-3.sh7
-rw-r--r--tests/mkdirat.at1
-rwxr-xr-xtests/openat-2.sh9
-rw-r--r--tests/openat.at1
-rwxr-xr-xtests/unlinkat-4.sh7
-rw-r--r--tests/unlinkat.at1
11 files changed, 44 insertions, 35 deletions
diff --git a/libsandbox/wrapper-funcs/__pre_check.c b/libsandbox/wrapper-funcs/__pre_check.c
index 2d5711f..28ad91f 100644
--- a/libsandbox/wrapper-funcs/__pre_check.c
+++ b/libsandbox/wrapper-funcs/__pre_check.c
@@ -20,3 +20,5 @@
#if SB_NR_UNLINK != SB_NR_UNDEF && SB_NR_UNLINKAT == SB_NR_UNDEF
# include "unlinkat_pre_check.c"
#endif
+
+#include "__pre_at_check.c"
diff --git a/libsandbox/wrapper-funcs/mkdirat_pre_check.c b/libsandbox/wrapper-funcs/mkdirat_pre_check.c
index 77a65df..0b48d1f 100644
--- a/libsandbox/wrapper-funcs/mkdirat_pre_check.c
+++ b/libsandbox/wrapper-funcs/mkdirat_pre_check.c
@@ -1,27 +1,20 @@
/*
* mkdir*() pre-check.
*
- * Copyright 1999-2009 Gentoo Foundation
+ * Copyright 1999-2012 Gentoo Foundation
* Licensed under the GPL-2
*/
bool sb_mkdirat_pre_check(const char *func, const char *pathname, int dirfd)
{
char canonic[SB_PATH_MAX];
- char dirfd_path[SB_PATH_MAX];
save_errno();
- /* Expand the dirfd path first */
- switch (resolve_dirfd_path(dirfd, pathname, dirfd_path, sizeof(dirfd_path))) {
- case -1:
- sb_debug_dyn("EARLY FAIL: %s(%s) @ resolve_dirfd_path: %s\n",
- func, pathname, strerror(errno));
- return false;
- case 0:
- pathname = dirfd_path;
- break;
- }
+ /* Check incoming args against common *at issues */
+ char dirfd_path[SB_PATH_MAX];
+ if (!sb_common_at_pre_check(func, &pathname, dirfd, dirfd_path, sizeof(dirfd_path)))
+ return false;
/* Then break down any relative/symlink paths */
if (-1 == canonicalize(pathname, canonic))
diff --git a/libsandbox/wrapper-funcs/openat_pre_check.c b/libsandbox/wrapper-funcs/openat_pre_check.c
index 0127708..5fd5eaa 100644
--- a/libsandbox/wrapper-funcs/openat_pre_check.c
+++ b/libsandbox/wrapper-funcs/openat_pre_check.c
@@ -1,7 +1,7 @@
/*
* open*() pre-check.
*
- * Copyright 1999-2009 Gentoo Foundation
+ * Copyright 1999-2012 Gentoo Foundation
* Licensed under the GPL-2
*/
@@ -15,17 +15,10 @@ bool sb_openat_pre_check(const char *func, const char *pathname, int dirfd, int
save_errno();
- /* Expand the dirfd path first */
+ /* Check incoming args against common *at issues */
char dirfd_path[SB_PATH_MAX];
- switch (resolve_dirfd_path(dirfd, pathname, dirfd_path, sizeof(dirfd_path))) {
- case -1:
- sb_debug_dyn("EARLY FAIL: %s(%s) @ resolve_dirfd_path: %s\n",
- func, pathname, strerror(errno));
- return false;
- case 0:
- pathname = dirfd_path;
- break;
- }
+ if (!sb_common_at_pre_check(func, &pathname, dirfd, dirfd_path, sizeof(dirfd_path)))
+ return false;
/* Doesn't exist -> skip permission checks */
struct stat st;
diff --git a/libsandbox/wrapper-funcs/unlinkat_pre_check.c b/libsandbox/wrapper-funcs/unlinkat_pre_check.c
index 9f5e7d7..c004d15 100644
--- a/libsandbox/wrapper-funcs/unlinkat_pre_check.c
+++ b/libsandbox/wrapper-funcs/unlinkat_pre_check.c
@@ -1,27 +1,20 @@
/*
* unlink*() pre-check.
*
- * Copyright 1999-2009 Gentoo Foundation
+ * Copyright 1999-2012 Gentoo Foundation
* Licensed under the GPL-2
*/
bool sb_unlinkat_pre_check(const char *func, const char *pathname, int dirfd)
{
char canonic[SB_PATH_MAX];
- char dirfd_path[SB_PATH_MAX];
save_errno();
- /* Expand the dirfd path first */
- switch (resolve_dirfd_path(dirfd, pathname, dirfd_path, sizeof(dirfd_path))) {
- case -1:
- sb_debug_dyn("EARLY FAIL: %s(%s) @ resolve_dirfd_path: %s\n",
- func, pathname, strerror(errno));
- return false;
- case 0:
- pathname = dirfd_path;
- break;
- }
+ /* Check incoming args against common *at issues */
+ char dirfd_path[SB_PATH_MAX];
+ if (!sb_common_at_pre_check(func, &pathname, dirfd, dirfd_path, sizeof(dirfd_path)))
+ return false;
/* Then break down any relative/symlink paths */
if (-1 == canonicalize(pathname, canonic))
diff --git a/libsandbox/wrappers.h b/libsandbox/wrappers.h
index 5b97787..0aa58bb 100644
--- a/libsandbox/wrappers.h
+++ b/libsandbox/wrappers.h
@@ -28,5 +28,7 @@ attribute_hidden bool sb_mkdirat_pre_check (const char *func, const char *pathn
attribute_hidden bool sb_openat_pre_check (const char *func, const char *pathname, int dirfd, int flags);
attribute_hidden bool sb_openat64_pre_check (const char *func, const char *pathname, int dirfd, int flags);
attribute_hidden bool sb_unlinkat_pre_check (const char *func, const char *pathname, int dirfd);
+attribute_hidden bool sb_common_at_pre_check(const char *func, const char **pathname, int dirfd,
+ char *dirfd_path, size_t dirfd_path_len);
#endif
diff --git a/tests/mkdirat-3.sh b/tests/mkdirat-3.sh
new file mode 100755
index 0000000..fe20579
--- /dev/null
+++ b/tests/mkdirat-3.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# verify mkdirat("") returns ENOENT in various ways #346929
+
+set -e
+mkdirat-0 -1,ENOENT .:O_DIRECTORY '' 0
+
+mkdirat-0 -1,ENOENT -3 '' 0
diff --git a/tests/mkdirat.at b/tests/mkdirat.at
index d364b4b..eec4638 100644
--- a/tests/mkdirat.at
+++ b/tests/mkdirat.at
@@ -1,2 +1,3 @@
SB_CHECK(1)
SB_CHECK(2)
+SB_CHECK(3)
diff --git a/tests/openat-2.sh b/tests/openat-2.sh
new file mode 100755
index 0000000..b615c2d
--- /dev/null
+++ b/tests/openat-2.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+# verify openat("") returns ENOENT in various ways #346929
+
+set -e
+openat-0 -1,ENOENT .:O_DIRECTORY '' O_RDONLY 0
+openat-0 -1,ENOENT .:O_DIRECTORY '' 'O_CREAT|O_WRONLY' 0
+
+openat-0 -1,ENOENT -3 '' O_RDONLY 0
+openat-0 -1,ENOENT -3 '' 'O_CREAT|O_WRONLY' 0
diff --git a/tests/openat.at b/tests/openat.at
index 081d7d2..d364b4b 100644
--- a/tests/openat.at
+++ b/tests/openat.at
@@ -1 +1,2 @@
SB_CHECK(1)
+SB_CHECK(2)
diff --git a/tests/unlinkat-4.sh b/tests/unlinkat-4.sh
new file mode 100755
index 0000000..4b23107
--- /dev/null
+++ b/tests/unlinkat-4.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+# verify unlinkat("") returns ENOENT in various ways #346929
+
+set -e
+unlinkat-0 -1,ENOENT .:O_DIRECTORY '' 0
+
+unlinkat-0 -1,ENOENT -3 '' 0
diff --git a/tests/unlinkat.at b/tests/unlinkat.at
index eec4638..1909650 100644
--- a/tests/unlinkat.at
+++ b/tests/unlinkat.at
@@ -1,3 +1,4 @@
SB_CHECK(1)
SB_CHECK(2)
SB_CHECK(3)
+SB_CHECK(4)