Change directory to "/" after --chroot operation.
Thanks to Steve Grubb for suggesting this. He wrote:
=========
I was reviewing something recently and discovered a problem in capsh. The capsh
program has a --chroot command line option. Inspecting the code shows that it does not
do a chdir("/") after calling chroot. This means that '.' is outside the chroot.
Additional info:
http://cwe.mitre.org/data/definitions/243.html
=========
Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
diff --git a/libcap/cap_proc.c b/libcap/cap_proc.c
index 6040c02..8ecb57a 100644
--- a/libcap/cap_proc.c
+++ b/libcap/cap_proc.c
@@ -4,6 +4,8 @@
* This file deals with getting and setting capabilities on processes.
*/
+#include <sys/prctl.h>
+
#include "libcap.h"
cap_t cap_get_proc(void)
diff --git a/progs/capsh.c b/progs/capsh.c
index 4c32279..52336d7 100644
--- a/progs/capsh.c
+++ b/progs/capsh.c
@@ -278,10 +278,16 @@
perror("unable to lower CAP_SYS_CHROOT");
exit(1);
}
+ /*
+ * Given we are now in a new directory tree, its good practice
+ * to start off in a sane location
+ */
+ status = chdir("/");
+
cap_free(orig);
if (status != 0) {
- fprintf(stderr, "Unable to chroot to [%s]", argv[i]+9);
+ fprintf(stderr, "Unable to chroot/chdir to [%s]", argv[i]+9);
exit(1);
}
} else if (!memcmp("--secbits=", argv[i], 10)) {
diff --git a/progs/quicktest.sh b/progs/quicktest.sh
index 5959da9..be3fa7d 100755
--- a/progs/quicktest.sh
+++ b/progs/quicktest.sh
@@ -21,6 +21,7 @@
echo -n "EXPECT FAILURE: "
try_capsh "$@"
if [ $? -eq 1 ]; then
+ echo "[WHICH MEANS A PASS!]"
return 0
else
echo "Undesired result - aborting"
@@ -132,3 +133,8 @@
# Max lockdown
pass_capsh --keep=1 --user=nobody --caps=cap_setpcap=ep \
--drop=all --secbits=0x2f --caps= --print
+
+# Verify we can chroot
+pass_capsh --chroot=$(/bin/pwd)
+pass_capsh --chroot=$(/bin/pwd) ==
+fail_capsh --chroot=$(/bin/pwd) -- -c "echo oops"