]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - kernel/sys.c
Merge tags 'for-linus' and 'for-next' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-linux.git] / kernel / sys.c
index 7ff6d1b10cecac8e66583f3bc233fd6fcb445b5c..8a94b4eabcaa291e6315858deba48a0269363fb9 100644 (file)
@@ -1396,8 +1396,7 @@ int do_prlimit(struct task_struct *tsk, unsigned int resource,
                                !capable(CAP_SYS_RESOURCE))
                        retval = -EPERM;
                if (!retval)
-                       retval = security_task_setrlimit(tsk->group_leader,
-                                       resource, new_rlim);
+                       retval = security_task_setrlimit(tsk, resource, new_rlim);
                if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) {
                        /*
                         * The caller is asking for an immediate RLIMIT_CPU
@@ -1432,25 +1431,26 @@ out:
 }
 
 /* rcu lock must be held */
-static int check_prlimit_permission(struct task_struct *task)
+static int check_prlimit_permission(struct task_struct *task,
+                                   unsigned int flags)
 {
        const struct cred *cred = current_cred(), *tcred;
+       bool id_match;
 
        if (current == task)
                return 0;
 
        tcred = __task_cred(task);
-       if (uid_eq(cred->uid, tcred->euid) &&
-           uid_eq(cred->uid, tcred->suid) &&
-           uid_eq(cred->uid, tcred->uid)  &&
-           gid_eq(cred->gid, tcred->egid) &&
-           gid_eq(cred->gid, tcred->sgid) &&
-           gid_eq(cred->gid, tcred->gid))
-               return 0;
-       if (ns_capable(tcred->user_ns, CAP_SYS_RESOURCE))
-               return 0;
+       id_match = (uid_eq(cred->uid, tcred->euid) &&
+                   uid_eq(cred->uid, tcred->suid) &&
+                   uid_eq(cred->uid, tcred->uid)  &&
+                   gid_eq(cred->gid, tcred->egid) &&
+                   gid_eq(cred->gid, tcred->sgid) &&
+                   gid_eq(cred->gid, tcred->gid));
+       if (!id_match && !ns_capable(tcred->user_ns, CAP_SYS_RESOURCE))
+               return -EPERM;
 
-       return -EPERM;
+       return security_task_prlimit(cred, tcred, flags);
 }
 
 SYSCALL_DEFINE4(prlimit64, pid_t, pid, unsigned int, resource,
@@ -1460,12 +1460,17 @@ SYSCALL_DEFINE4(prlimit64, pid_t, pid, unsigned int, resource,
        struct rlimit64 old64, new64;
        struct rlimit old, new;
        struct task_struct *tsk;
+       unsigned int checkflags = 0;
        int ret;
 
+       if (old_rlim)
+               checkflags |= LSM_PRLIMIT_READ;
+
        if (new_rlim) {
                if (copy_from_user(&new64, new_rlim, sizeof(new64)))
                        return -EFAULT;
                rlim64_to_rlim(&new64, &new);
+               checkflags |= LSM_PRLIMIT_WRITE;
        }
 
        rcu_read_lock();
@@ -1474,7 +1479,7 @@ SYSCALL_DEFINE4(prlimit64, pid_t, pid, unsigned int, resource,
                rcu_read_unlock();
                return -ESRCH;
        }
-       ret = check_prlimit_permission(tsk);
+       ret = check_prlimit_permission(tsk, checkflags);
        if (ret) {
                rcu_read_unlock();
                return ret;