diff options
-rw-r--r-- | ipc/sem.c | 1 | ||||
-rw-r--r-- | kernel/fork.c | 29 |
2 files changed, 12 insertions, 18 deletions
@@ -1250,6 +1250,7 @@ void exit_sem(struct task_struct *tsk) | |||
1250 | undo_list = tsk->sysvsem.undo_list; | 1250 | undo_list = tsk->sysvsem.undo_list; |
1251 | if (!undo_list) | 1251 | if (!undo_list) |
1252 | return; | 1252 | return; |
1253 | tsk->sysvsem.undo_list = NULL; | ||
1253 | 1254 | ||
1254 | if (!atomic_dec_and_test(&undo_list->refcnt)) | 1255 | if (!atomic_dec_and_test(&undo_list->refcnt)) |
1255 | return; | 1256 | return; |
diff --git a/kernel/fork.c b/kernel/fork.c index 156db96ff754..01666979beac 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1669,18 +1669,6 @@ static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp | |||
1669 | } | 1669 | } |
1670 | 1670 | ||
1671 | /* | 1671 | /* |
1672 | * Unsharing of semundo for tasks created with CLONE_SYSVSEM is not | ||
1673 | * supported yet | ||
1674 | */ | ||
1675 | static int unshare_semundo(unsigned long unshare_flags, struct sem_undo_list **new_ulistp) | ||
1676 | { | ||
1677 | if (unshare_flags & CLONE_SYSVSEM) | ||
1678 | return -EINVAL; | ||
1679 | |||
1680 | return 0; | ||
1681 | } | ||
1682 | |||
1683 | /* | ||
1684 | * unshare allows a process to 'unshare' part of the process | 1672 | * unshare allows a process to 'unshare' part of the process |
1685 | * context which was originally shared using clone. copy_* | 1673 | * context which was originally shared using clone. copy_* |
1686 | * functions used by do_fork() cannot be used here directly | 1674 | * functions used by do_fork() cannot be used here directly |
@@ -1695,8 +1683,8 @@ asmlinkage long sys_unshare(unsigned long unshare_flags) | |||
1695 | struct sighand_struct *new_sigh = NULL; | 1683 | struct sighand_struct *new_sigh = NULL; |
1696 | struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL; | 1684 | struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL; |
1697 | struct files_struct *fd, *new_fd = NULL; | 1685 | struct files_struct *fd, *new_fd = NULL; |
1698 | struct sem_undo_list *new_ulist = NULL; | ||
1699 | struct nsproxy *new_nsproxy = NULL; | 1686 | struct nsproxy *new_nsproxy = NULL; |
1687 | int do_sysvsem = 0; | ||
1700 | 1688 | ||
1701 | check_unshare_flags(&unshare_flags); | 1689 | check_unshare_flags(&unshare_flags); |
1702 | 1690 | ||
@@ -1708,6 +1696,8 @@ asmlinkage long sys_unshare(unsigned long unshare_flags) | |||
1708 | CLONE_NEWNET)) | 1696 | CLONE_NEWNET)) |
1709 | goto bad_unshare_out; | 1697 | goto bad_unshare_out; |
1710 | 1698 | ||
1699 | if (unshare_flags & CLONE_SYSVSEM) | ||
1700 | do_sysvsem = 1; | ||
1711 | if ((err = unshare_thread(unshare_flags))) | 1701 | if ((err = unshare_thread(unshare_flags))) |
1712 | goto bad_unshare_out; | 1702 | goto bad_unshare_out; |
1713 | if ((err = unshare_fs(unshare_flags, &new_fs))) | 1703 | if ((err = unshare_fs(unshare_flags, &new_fs))) |
@@ -1718,13 +1708,17 @@ asmlinkage long sys_unshare(unsigned long unshare_flags) | |||
1718 | goto bad_unshare_cleanup_sigh; | 1708 | goto bad_unshare_cleanup_sigh; |
1719 | if ((err = unshare_fd(unshare_flags, &new_fd))) | 1709 | if ((err = unshare_fd(unshare_flags, &new_fd))) |
1720 | goto bad_unshare_cleanup_vm; | 1710 | goto bad_unshare_cleanup_vm; |
1721 | if ((err = unshare_semundo(unshare_flags, &new_ulist))) | ||
1722 | goto bad_unshare_cleanup_fd; | ||
1723 | if ((err = unshare_nsproxy_namespaces(unshare_flags, &new_nsproxy, | 1711 | if ((err = unshare_nsproxy_namespaces(unshare_flags, &new_nsproxy, |
1724 | new_fs))) | 1712 | new_fs))) |
1725 | goto bad_unshare_cleanup_semundo; | 1713 | goto bad_unshare_cleanup_fd; |
1726 | 1714 | ||
1727 | if (new_fs || new_mm || new_fd || new_ulist || new_nsproxy) { | 1715 | if (new_fs || new_mm || new_fd || do_sysvsem || new_nsproxy) { |
1716 | if (do_sysvsem) { | ||
1717 | /* | ||
1718 | * CLONE_SYSVSEM is equivalent to sys_exit(). | ||
1719 | */ | ||
1720 | exit_sem(current); | ||
1721 | } | ||
1728 | 1722 | ||
1729 | if (new_nsproxy) { | 1723 | if (new_nsproxy) { |
1730 | switch_task_namespaces(current, new_nsproxy); | 1724 | switch_task_namespaces(current, new_nsproxy); |
@@ -1760,7 +1754,6 @@ asmlinkage long sys_unshare(unsigned long unshare_flags) | |||
1760 | if (new_nsproxy) | 1754 | if (new_nsproxy) |
1761 | put_nsproxy(new_nsproxy); | 1755 | put_nsproxy(new_nsproxy); |
1762 | 1756 | ||
1763 | bad_unshare_cleanup_semundo: | ||
1764 | bad_unshare_cleanup_fd: | 1757 | bad_unshare_cleanup_fd: |
1765 | if (new_fd) | 1758 | if (new_fd) |
1766 | put_files_struct(new_fd); | 1759 | put_files_struct(new_fd); |