userns: Unbreak the unprivileged remount tests
authorEric W. Biederman <ebiederm@xmission.com>
Tue, 2 Dec 2014 19:56:30 +0000 (13:56 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 8 Jan 2015 17:58:17 +0000 (09:58 -0800)
commit db86da7cb76f797a1a8b445166a15cb922c6ff85 upstream.

A security fix in caused the way the unprivileged remount tests were
using user namespaces to break.  Tweak the way user namespaces are
being used so the test works again.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
tools/testing/selftests/mount/unprivileged-remount-test.c

index 9669d375625a34610179a4ccd38965c75882cdd3..517785052f1c37a4c368810c5c88d35119c9cab0 100644 (file)
@@ -53,17 +53,14 @@ static void die(char *fmt, ...)
        exit(EXIT_FAILURE);
 }
 
-static void write_file(char *filename, char *fmt, ...)
+static void vmaybe_write_file(bool enoent_ok, char *filename, char *fmt, va_list ap)
 {
        char buf[4096];
        int fd;
        ssize_t written;
        int buf_len;
-       va_list ap;
 
-       va_start(ap, fmt);
        buf_len = vsnprintf(buf, sizeof(buf), fmt, ap);
-       va_end(ap);
        if (buf_len < 0) {
                die("vsnprintf failed: %s\n",
                    strerror(errno));
@@ -74,6 +71,8 @@ static void write_file(char *filename, char *fmt, ...)
 
        fd = open(filename, O_WRONLY);
        if (fd < 0) {
+               if ((errno == ENOENT) && enoent_ok)
+                       return;
                die("open of %s failed: %s\n",
                    filename, strerror(errno));
        }
@@ -92,6 +91,26 @@ static void write_file(char *filename, char *fmt, ...)
        }
 }
 
+static void maybe_write_file(char *filename, char *fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+       vmaybe_write_file(true, filename, fmt, ap);
+       va_end(ap);
+
+}
+
+static void write_file(char *filename, char *fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+       vmaybe_write_file(false, filename, fmt, ap);
+       va_end(ap);
+
+}
+
 static int read_mnt_flags(const char *path)
 {
        int ret;
@@ -144,13 +163,10 @@ static void create_and_enter_userns(void)
                        strerror(errno));
        }
 
+       maybe_write_file("/proc/self/setgroups", "deny");
        write_file("/proc/self/uid_map", "0 %d 1", uid);
        write_file("/proc/self/gid_map", "0 %d 1", gid);
 
-       if (setgroups(0, NULL) != 0) {
-               die("setgroups failed: %s\n",
-                       strerror(errno));
-       }
        if (setgid(0) != 0) {
                die ("setgid(0) failed %s\n",
                        strerror(errno));