aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index 291c9700be75..d252be2d3de5 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1344,13 +1344,24 @@ int kill_proc_info(int sig, struct siginfo *info, pid_t pid)
1344 return error; 1344 return error;
1345} 1345}
1346 1346
1347static int kill_as_cred_perm(const struct cred *cred,
1348 struct task_struct *target)
1349{
1350 const struct cred *pcred = __task_cred(target);
1351 if (cred->user_ns != pcred->user_ns)
1352 return 0;
1353 if (cred->euid != pcred->suid && cred->euid != pcred->uid &&
1354 cred->uid != pcred->suid && cred->uid != pcred->uid)
1355 return 0;
1356 return 1;
1357}
1358
1347/* like kill_pid_info(), but doesn't use uid/euid of "current" */ 1359/* like kill_pid_info(), but doesn't use uid/euid of "current" */
1348int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid, 1360int kill_pid_info_as_cred(int sig, struct siginfo *info, struct pid *pid,
1349 uid_t uid, uid_t euid, u32 secid) 1361 const struct cred *cred, u32 secid)
1350{ 1362{
1351 int ret = -EINVAL; 1363 int ret = -EINVAL;
1352 struct task_struct *p; 1364 struct task_struct *p;
1353 const struct cred *pcred;
1354 unsigned long flags; 1365 unsigned long flags;
1355 1366
1356 if (!valid_signal(sig)) 1367 if (!valid_signal(sig))
@@ -1362,10 +1373,7 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid,
1362 ret = -ESRCH; 1373 ret = -ESRCH;
1363 goto out_unlock; 1374 goto out_unlock;
1364 } 1375 }
1365 pcred = __task_cred(p); 1376 if (si_fromuser(info) && !kill_as_cred_perm(cred, p)) {
1366 if (si_fromuser(info) &&
1367 euid != pcred->suid && euid != pcred->uid &&
1368 uid != pcred->suid && uid != pcred->uid) {
1369 ret = -EPERM; 1377 ret = -EPERM;
1370 goto out_unlock; 1378 goto out_unlock;
1371 } 1379 }
@@ -1384,7 +1392,7 @@ out_unlock:
1384 rcu_read_unlock(); 1392 rcu_read_unlock();
1385 return ret; 1393 return ret;
1386} 1394}
1387EXPORT_SYMBOL_GPL(kill_pid_info_as_uid); 1395EXPORT_SYMBOL_GPL(kill_pid_info_as_cred);
1388 1396
1389/* 1397/*
1390 * kill_something_info() interprets pid in interesting ways just like kill(2). 1398 * kill_something_info() interprets pid in interesting ways just like kill(2).