mknod: take sanity checks on mode into the very beginning
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 19 Jul 2012 21:17:26 +0000 (01:17 +0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 29 Jul 2012 17:24:14 +0000 (21:24 +0400)
Note that applying umask can't affect their results.  While
that affects errno in cases like
mknod("/no_such_directory/a", 030000)
yielding -EINVAL (due to impossible mode_t) instead of
-ENOENT (due to inexistent directory), IMO that makes a lot
more sense, POSIX allows to return either and any software
that relies on getting -ENOENT instead of -EINVAL in that
case deserves everything it gets.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/namei.c

index 5bc6f3d..cf362dc 100644 (file)
@@ -2964,8 +2964,9 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
        struct path path;
        int error;
 
-       if (S_ISDIR(mode))
-               return -EPERM;
+       error = may_mknod(mode);
+       if (error)
+               return error;
 
        dentry = user_path_create(dfd, filename, &path, 0);
        if (IS_ERR(dentry))
@@ -2973,9 +2974,6 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
 
        if (!IS_POSIXACL(path.dentry->d_inode))
                mode &= ~current_umask();
-       error = may_mknod(mode);
-       if (error)
-               goto out_dput;
        error = mnt_want_write(path.mnt);
        if (error)
                goto out_dput;