Merge tag 'drm-next-2020-12-24' of git://anongit.freedesktop.org/drm/drm
[linux-2.6-microblaze.git] / security / commoncap.c
index 0ca31c8..bacc111 100644 (file)
@@ -473,7 +473,7 @@ static bool validheader(size_t size, const struct vfs_cap_data *cap)
  *
  * If all is ok, we return the new size, on error return < 0.
  */
-int cap_convert_nscap(struct dentry *dentry, void **ivalue, size_t size)
+int cap_convert_nscap(struct dentry *dentry, const void **ivalue, size_t size)
 {
        struct vfs_ns_cap_data *nscap;
        uid_t nsrootid;
@@ -516,7 +516,6 @@ int cap_convert_nscap(struct dentry *dentry, void **ivalue, size_t size)
        nscap->magic_etc = cpu_to_le32(nsmagic);
        memcpy(&nscap->data, &cap->data, sizeof(__le32) * 2 * VFS_CAP_U32);
 
-       kvfree(*ivalue);
        *ivalue = nscap;
        return newsize;
 }
@@ -647,7 +646,8 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data
  * its xattrs and, if present, apply them to the proposed credentials being
  * constructed by execve().
  */
-static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_fcap)
+static int get_file_caps(struct linux_binprm *bprm, struct file *file,
+                        bool *effective, bool *has_fcap)
 {
        int rc = 0;
        struct cpu_vfs_cap_data vcaps;
@@ -657,7 +657,7 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_f
        if (!file_caps_enabled)
                return 0;
 
-       if (!mnt_may_suid(bprm->file->f_path.mnt))
+       if (!mnt_may_suid(file->f_path.mnt))
                return 0;
 
        /*
@@ -665,10 +665,10 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_f
         * explicit that capability bits are limited to s_user_ns and its
         * descendants.
         */
-       if (!current_in_userns(bprm->file->f_path.mnt->mnt_sb->s_user_ns))
+       if (!current_in_userns(file->f_path.mnt->mnt_sb->s_user_ns))
                return 0;
 
-       rc = get_vfs_caps_from_disk(bprm->file->f_path.dentry, &vcaps);
+       rc = get_vfs_caps_from_disk(file->f_path.dentry, &vcaps);
        if (rc < 0) {
                if (rc == -EINVAL)
                        printk(KERN_NOTICE "Invalid argument reading file caps for %s\n",
@@ -797,26 +797,27 @@ static inline bool nonroot_raised_pE(struct cred *new, const struct cred *old,
 }
 
 /**
- * cap_bprm_set_creds - Set up the proposed credentials for execve().
+ * cap_bprm_creds_from_file - Set up the proposed credentials for execve().
  * @bprm: The execution parameters, including the proposed creds
+ * @file: The file to pull the credentials from
  *
  * Set up the proposed credentials for a new execution context being
  * constructed by execve().  The proposed creds in @bprm->cred is altered,
  * which won't take effect immediately.  Returns 0 if successful, -ve on error.
  */
-int cap_bprm_set_creds(struct linux_binprm *bprm)
+int cap_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file)
 {
+       /* Process setpcap binaries and capabilities for uid 0 */
        const struct cred *old = current_cred();
        struct cred *new = bprm->cred;
        bool effective = false, has_fcap = false, is_setid;
        int ret;
        kuid_t root_uid;
 
-       new->cap_ambient = old->cap_ambient;
        if (WARN_ON(!cap_ambient_invariant_ok(old)))
                return -EPERM;
 
-       ret = get_file_caps(bprm, &effective, &has_fcap);
+       ret = get_file_caps(bprm, file, &effective, &has_fcap);
        if (ret < 0)
                return ret;
 
@@ -885,12 +886,11 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
                return -EPERM;
 
        /* Check for privilege-elevated exec. */
-       bprm->cap_elevated = 0;
        if (is_setid ||
            (!__is_real(root_uid, new) &&
             (effective ||
              __cap_grew(permitted, ambient, new))))
-               bprm->cap_elevated = 1;
+               bprm->secureexec = 1;
 
        return 0;
 }
@@ -1347,7 +1347,7 @@ static struct security_hook_list capability_hooks[] __lsm_ro_after_init = {
        LSM_HOOK_INIT(ptrace_traceme, cap_ptrace_traceme),
        LSM_HOOK_INIT(capget, cap_capget),
        LSM_HOOK_INIT(capset, cap_capset),
-       LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds),
+       LSM_HOOK_INIT(bprm_creds_from_file, cap_bprm_creds_from_file),
        LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv),
        LSM_HOOK_INIT(inode_killpriv, cap_inode_killpriv),
        LSM_HOOK_INIT(inode_getsecurity, cap_inode_getsecurity),