aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2009-03-11 11:40:54 -0400
committerMike Frysinger <vapier@gentoo.org>2009-03-11 11:41:00 -0400
commitf97f3d9a39e86b6de3fda3dc0f8470907bbb0ce8 (patch)
treed5cab4a48b7eee349ecaa1f9d551edcfbd53ee66 /tests
parentlibsandbox: add more exec wrappers (diff)
downloadsandbox-f97f3d9a39e86b6de3fda3dc0f8470907bbb0ce8.tar.gz
sandbox-f97f3d9a39e86b6de3fda3dc0f8470907bbb0ce8.tar.bz2
sandbox-f97f3d9a39e86b6de3fda3dc0f8470907bbb0ce8.zip
libsandbox: do not restore errno in resolve_path() error path
If resolve_path() was unable to resolve things, then do not restore the errno value as we use this to signal higher layers. This should make the getcwd tests behave better. URL: http://bugs.gentoo.org/261936 Signed-off-by: Mike Frysinger <vapier@gentoo.org> Reported-by: Ryan Hill <dirtyepic@gentoo.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.am4
-rw-r--r--tests/getcwd-gnulib_tst.c119
-rw-r--r--tests/script-5.sh10
-rw-r--r--tests/script.at1
4 files changed, 133 insertions, 1 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7fecbcb..12f0999 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -49,6 +49,7 @@ check_PROGRAMS = \
utimensat-0 \
utimes-0 \
\
+ getcwd-gnulib_tst \
libsigsegv_tst \
sb_printf_tst
@@ -65,7 +66,8 @@ dist_check_SCRIPTS = \
script-1.sh \
script-2.sh \
script-3.sh \
- script-4.sh
+ script-4.sh \
+ script-5.sh
sb_printf_tst_CFLAGS = -I$(top_srcdir)/libsbutil -I$(top_srcdir)/libsbutil/include
sb_printf_tst_LDADD = $(top_builddir)/libsbutil/libsbutil.la
diff --git a/tests/getcwd-gnulib_tst.c b/tests/getcwd-gnulib_tst.c
new file mode 100644
index 0000000..416fa01
--- /dev/null
+++ b/tests/getcwd-gnulib_tst.c
@@ -0,0 +1,119 @@
+/* This comes from gnulib: gnulib/m4/getcwd-path-max.m4
+ * On glibc systems, we currently exit(1). Sandbox should not get in the
+ * way of this, nor should it crash.
+ */
+
+#include "tests.h"
+
+#ifndef S_IRWXU
+# define S_IRWXU 0700
+#endif
+
+/* The length of this name must be 8. */
+#define DIR_NAME "confdir3"
+#define DIR_NAME_LEN 8
+#define DIR_NAME_SIZE (DIR_NAME_LEN + 1)
+
+/* The length of "../". */
+#define DOTDOTSLASH_LEN 3
+
+/* Leftover bytes in the buffer, to work around library or OS bugs. */
+#define BUF_SLOP 20
+
+int
+main ()
+{
+ char buf[PATH_MAX * (DIR_NAME_SIZE / DOTDOTSLASH_LEN + 1)
+ + DIR_NAME_SIZE + BUF_SLOP];
+ char *cwd = getcwd (buf, PATH_MAX);
+ size_t initial_cwd_len;
+ size_t cwd_len;
+ int fail = 0;
+ size_t n_chdirs = 0;
+
+ if (cwd == NULL)
+ exit (1);
+
+ cwd_len = initial_cwd_len = strlen (cwd);
+
+ while (1)
+ {
+ size_t dotdot_max = PATH_MAX * (DIR_NAME_SIZE / DOTDOTSLASH_LEN);
+ char *c = NULL;
+
+ cwd_len += DIR_NAME_SIZE;
+ /* If mkdir or chdir fails, it could be that this system cannot create
+ any file with an absolute name longer than PATH_MAX, such as cygwin.
+ If so, leave fail as 0, because the current working directory can't
+ be too long for getcwd if it can't even be created. For other
+ errors, be pessimistic and consider that as a failure, too. */
+ if (mkdir (DIR_NAME, S_IRWXU) < 0 || chdir (DIR_NAME) < 0)
+ {
+ if (! (errno == ERANGE || ENAMETOOLONG == errno))
+ fail = 2;
+ break;
+ }
+
+ if (PATH_MAX <= cwd_len && cwd_len < PATH_MAX + DIR_NAME_SIZE)
+ {
+ c = getcwd (buf, PATH_MAX);
+ if (!c && errno == ENOENT)
+ {
+ fail = 1;
+ break;
+ }
+ if (c || ! (errno == ERANGE || ENAMETOOLONG == errno))
+ {
+ fail = 2;
+ break;
+ }
+ }
+
+ if (dotdot_max <= cwd_len - initial_cwd_len)
+ {
+ if (dotdot_max + DIR_NAME_SIZE < cwd_len - initial_cwd_len)
+ break;
+ c = getcwd (buf, cwd_len + 1);
+ if (!c)
+ {
+ if (! (errno == ERANGE || errno == ENOENT
+ || ENAMETOOLONG == errno))
+ {
+ fail = 2;
+ break;
+ }
+ if (AT_FDCWD || errno == ERANGE || errno == ENOENT)
+ {
+ fail = 1;
+ break;
+ }
+ }
+ }
+
+ if (c && strlen (c) != cwd_len)
+ {
+ fail = 2;
+ break;
+ }
+ ++n_chdirs;
+ }
+
+ /* Leaving behind such a deep directory is not polite.
+ So clean up here, right away, even though the driving
+ shell script would also clean up. */
+ {
+ size_t i;
+
+ /* Try rmdir first, in case the chdir failed. */
+ rmdir (DIR_NAME);
+ for (i = 0; i <= n_chdirs; i++)
+ {
+ if (chdir ("..") < 0)
+ break;
+ if (rmdir (DIR_NAME) != 0)
+ break;
+ }
+ }
+
+ exit (fail);
+}
diff --git a/tests/script-5.sh b/tests/script-5.sh
new file mode 100644
index 0000000..96ea0a9
--- /dev/null
+++ b/tests/script-5.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+# make sure extra long paths don't cause sandbox to shit itself
+# (actual exit status is irrelevant as it depends on host libc)
+
+addwrite $PWD
+getcwd-gnulib_tst
+case $? in
+ 0|1|2) exit 0;; # test may exit with these values
+ *) echo "someone get a diaper"; exit 1;;
+esac
diff --git a/tests/script.at b/tests/script.at
index b344be9..2290505 100644
--- a/tests/script.at
+++ b/tests/script.at
@@ -3,3 +3,4 @@ SB_CHECK(1)
SB_CHECK(2, [hi])
SB_CHECK(3, [OK])
SB_CHECK(4)
+SB_CHECK(5)