diff options
Diffstat (limited to 'kernel/sys.c')
| -rw-r--r-- | kernel/sys.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index 7ef7f6054c28..0b6ec0e7936f 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
| @@ -1372,18 +1372,29 @@ asmlinkage long sys_getsid(pid_t pid) | |||
| 1372 | asmlinkage long sys_setsid(void) | 1372 | asmlinkage long sys_setsid(void) |
| 1373 | { | 1373 | { |
| 1374 | struct task_struct *group_leader = current->group_leader; | 1374 | struct task_struct *group_leader = current->group_leader; |
| 1375 | struct pid *pid; | 1375 | pid_t session; |
| 1376 | int err = -EPERM; | 1376 | int err = -EPERM; |
| 1377 | 1377 | ||
| 1378 | mutex_lock(&tty_mutex); | 1378 | mutex_lock(&tty_mutex); |
| 1379 | write_lock_irq(&tasklist_lock); | 1379 | write_lock_irq(&tasklist_lock); |
| 1380 | 1380 | ||
| 1381 | pid = find_pid(PIDTYPE_PGID, group_leader->pid); | 1381 | /* Fail if I am already a session leader */ |
| 1382 | if (pid) | 1382 | if (group_leader->signal->leader) |
| 1383 | goto out; | ||
| 1384 | |||
| 1385 | session = group_leader->pid; | ||
| 1386 | /* Fail if a process group id already exists that equals the | ||
| 1387 | * proposed session id. | ||
| 1388 | * | ||
| 1389 | * Don't check if session id == 1 because kernel threads use this | ||
| 1390 | * session id and so the check will always fail and make it so | ||
| 1391 | * init cannot successfully call setsid. | ||
| 1392 | */ | ||
| 1393 | if (session > 1 && find_task_by_pid_type(PIDTYPE_PGID, session)) | ||
| 1383 | goto out; | 1394 | goto out; |
| 1384 | 1395 | ||
| 1385 | group_leader->signal->leader = 1; | 1396 | group_leader->signal->leader = 1; |
| 1386 | __set_special_pids(group_leader->pid, group_leader->pid); | 1397 | __set_special_pids(session, session); |
| 1387 | group_leader->signal->tty = NULL; | 1398 | group_leader->signal->tty = NULL; |
| 1388 | group_leader->signal->tty_old_pgrp = 0; | 1399 | group_leader->signal->tty_old_pgrp = 0; |
| 1389 | err = process_group(group_leader); | 1400 | err = process_group(group_leader); |
