userns: Teach security_path_chown to take kuids and kgids
Eric W. Biederman [Fri, 1 Jun 2012 22:14:19 +0000 (16:14 -0600)]
Don't make the security modules deal with raw user space uid and
gids instead pass in a kuid_t and a kgid_t so that security modules
only have to deal with internal kernel uids and gids.

Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: James Morris <james.l.morris@oracle.com>
Cc: John Johansen <john.johansen@canonical.com>
Cc: Kentaro Takeda <takedakn@nttdata.co.jp>
Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>

fs/open.c
include/linux/security.h
security/apparmor/lsm.c
security/capability.c
security/security.c
security/tomoyo/tomoyo.c

index f3d96e7..2b25739 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -534,7 +534,7 @@ static int chown_common(struct path *path, uid_t user, gid_t group)
                newattrs.ia_valid |=
                        ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
        mutex_lock(&inode->i_mutex);
-       error = security_path_chown(path, user, group);
+       error = security_path_chown(path, uid, gid);
        if (!error)
                error = notify_change(path->dentry, &newattrs);
        mutex_unlock(&inode->i_mutex);
index 4e5a73c..ebb92cb 100644 (file)
@@ -1437,7 +1437,7 @@ struct security_operations {
        int (*path_rename) (struct path *old_dir, struct dentry *old_dentry,
                            struct path *new_dir, struct dentry *new_dentry);
        int (*path_chmod) (struct path *path, umode_t mode);
-       int (*path_chown) (struct path *path, uid_t uid, gid_t gid);
+       int (*path_chown) (struct path *path, kuid_t uid, kgid_t gid);
        int (*path_chroot) (struct path *path);
 #endif
 
@@ -2832,7 +2832,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
 int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
                         struct path *new_dir, struct dentry *new_dentry);
 int security_path_chmod(struct path *path, umode_t mode);
-int security_path_chown(struct path *path, uid_t uid, gid_t gid);
+int security_path_chown(struct path *path, kuid_t uid, kgid_t gid);
 int security_path_chroot(struct path *path);
 #else  /* CONFIG_SECURITY_PATH */
 static inline int security_path_unlink(struct path *dir, struct dentry *dentry)
@@ -2888,7 +2888,7 @@ static inline int security_path_chmod(struct path *path, umode_t mode)
        return 0;
 }
 
-static inline int security_path_chown(struct path *path, uid_t uid, gid_t gid)
+static inline int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
 {
        return 0;
 }
index 8ea39aa..8c2a7f6 100644 (file)
@@ -352,7 +352,7 @@ static int apparmor_path_chmod(struct path *path, umode_t mode)
        return common_perm_mnt_dentry(OP_CHMOD, path->mnt, path->dentry, AA_MAY_CHMOD);
 }
 
-static int apparmor_path_chown(struct path *path, uid_t uid, gid_t gid)
+static int apparmor_path_chown(struct path *path, kuid_t uid, kgid_t gid)
 {
        struct path_cond cond =  { path->dentry->d_inode->i_uid,
                                   path->dentry->d_inode->i_mode
index 61095df..a40aac6 100644 (file)
@@ -284,7 +284,7 @@ static int cap_path_chmod(struct path *path, umode_t mode)
        return 0;
 }
 
-static int cap_path_chown(struct path *path, uid_t uid, gid_t gid)
+static int cap_path_chown(struct path *path, kuid_t uid, kgid_t gid)
 {
        return 0;
 }
index 860aeb3..f9a2f2e 100644 (file)
@@ -434,7 +434,7 @@ int security_path_chmod(struct path *path, umode_t mode)
        return security_ops->path_chmod(path, mode);
 }
 
-int security_path_chown(struct path *path, uid_t uid, gid_t gid)
+int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
 {
        if (unlikely(IS_PRIVATE(path->dentry->d_inode)))
                return 0;
index c2d04a5..d88eb3a 100644 (file)
@@ -373,13 +373,15 @@ static int tomoyo_path_chmod(struct path *path, umode_t mode)
  *
  * Returns 0 on success, negative value otherwise.
  */
-static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid)
+static int tomoyo_path_chown(struct path *path, kuid_t uid, kgid_t gid)
 {
        int error = 0;
-       if (uid != (uid_t) -1)
-               error = tomoyo_path_number_perm(TOMOYO_TYPE_CHOWN, path, uid);
-       if (!error && gid != (gid_t) -1)
-               error = tomoyo_path_number_perm(TOMOYO_TYPE_CHGRP, path, gid);
+       if (uid_valid(uid))
+               error = tomoyo_path_number_perm(TOMOYO_TYPE_CHOWN, path,
+                                               from_kuid(&init_user_ns, uid));
+       if (!error && gid_valid(gid))
+               error = tomoyo_path_number_perm(TOMOYO_TYPE_CHGRP, path,
+                                               from_kgid(&init_user_ns, gid));
        return error;
 }