diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 24 |
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 | ||
1347 | static 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" */ |
1348 | int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid, | 1360 | int 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 | } |
1387 | EXPORT_SYMBOL_GPL(kill_pid_info_as_uid); | 1395 | EXPORT_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). |