diff options
Diffstat (limited to 'kernel/sys.c')
-rw-r--r-- | kernel/sys.c | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index a0c1a29a507f..c7675c1bfdf2 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -1381,7 +1381,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) | |||
1381 | 1381 | ||
1382 | if (p->real_parent == group_leader) { | 1382 | if (p->real_parent == group_leader) { |
1383 | err = -EPERM; | 1383 | err = -EPERM; |
1384 | if (p->signal->session != group_leader->signal->session) | 1384 | if (process_session(p) != process_session(group_leader)) |
1385 | goto out; | 1385 | goto out; |
1386 | err = -EACCES; | 1386 | err = -EACCES; |
1387 | if (p->did_exec) | 1387 | if (p->did_exec) |
@@ -1397,16 +1397,13 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) | |||
1397 | goto out; | 1397 | goto out; |
1398 | 1398 | ||
1399 | if (pgid != pid) { | 1399 | if (pgid != pid) { |
1400 | struct task_struct *p; | 1400 | struct task_struct *g = |
1401 | find_task_by_pid_type(PIDTYPE_PGID, pgid); | ||
1401 | 1402 | ||
1402 | do_each_task_pid(pgid, PIDTYPE_PGID, p) { | 1403 | if (!g || process_session(g) != process_session(group_leader)) |
1403 | if (p->signal->session == group_leader->signal->session) | 1404 | goto out; |
1404 | goto ok_pgid; | ||
1405 | } while_each_task_pid(pgid, PIDTYPE_PGID, p); | ||
1406 | goto out; | ||
1407 | } | 1405 | } |
1408 | 1406 | ||
1409 | ok_pgid: | ||
1410 | err = security_task_setpgid(p, pgid); | 1407 | err = security_task_setpgid(p, pgid); |
1411 | if (err) | 1408 | if (err) |
1412 | goto out; | 1409 | goto out; |
@@ -1459,7 +1456,7 @@ asmlinkage long sys_getpgrp(void) | |||
1459 | asmlinkage long sys_getsid(pid_t pid) | 1456 | asmlinkage long sys_getsid(pid_t pid) |
1460 | { | 1457 | { |
1461 | if (!pid) | 1458 | if (!pid) |
1462 | return current->signal->session; | 1459 | return process_session(current); |
1463 | else { | 1460 | else { |
1464 | int retval; | 1461 | int retval; |
1465 | struct task_struct *p; | 1462 | struct task_struct *p; |
@@ -1471,7 +1468,7 @@ asmlinkage long sys_getsid(pid_t pid) | |||
1471 | if (p) { | 1468 | if (p) { |
1472 | retval = security_task_getsid(p); | 1469 | retval = security_task_getsid(p); |
1473 | if (!retval) | 1470 | if (!retval) |
1474 | retval = p->signal->session; | 1471 | retval = process_session(p); |
1475 | } | 1472 | } |
1476 | read_unlock(&tasklist_lock); | 1473 | read_unlock(&tasklist_lock); |
1477 | return retval; | 1474 | return retval; |
@@ -1484,7 +1481,6 @@ asmlinkage long sys_setsid(void) | |||
1484 | pid_t session; | 1481 | pid_t session; |
1485 | int err = -EPERM; | 1482 | int err = -EPERM; |
1486 | 1483 | ||
1487 | mutex_lock(&tty_mutex); | ||
1488 | write_lock_irq(&tasklist_lock); | 1484 | write_lock_irq(&tasklist_lock); |
1489 | 1485 | ||
1490 | /* Fail if I am already a session leader */ | 1486 | /* Fail if I am already a session leader */ |
@@ -1504,12 +1500,15 @@ asmlinkage long sys_setsid(void) | |||
1504 | 1500 | ||
1505 | group_leader->signal->leader = 1; | 1501 | group_leader->signal->leader = 1; |
1506 | __set_special_pids(session, session); | 1502 | __set_special_pids(session, session); |
1503 | |||
1504 | spin_lock(&group_leader->sighand->siglock); | ||
1507 | group_leader->signal->tty = NULL; | 1505 | group_leader->signal->tty = NULL; |
1508 | group_leader->signal->tty_old_pgrp = 0; | 1506 | group_leader->signal->tty_old_pgrp = 0; |
1507 | spin_unlock(&group_leader->sighand->siglock); | ||
1508 | |||
1509 | err = process_group(group_leader); | 1509 | err = process_group(group_leader); |
1510 | out: | 1510 | out: |
1511 | write_unlock_irq(&tasklist_lock); | 1511 | write_unlock_irq(&tasklist_lock); |
1512 | mutex_unlock(&tty_mutex); | ||
1513 | return err; | 1512 | return err; |
1514 | } | 1513 | } |
1515 | 1514 | ||