aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c24
1 files changed, 9 insertions, 15 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 7f325df5e014..c6e91c3dc2a1 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -747,7 +747,7 @@ static int exec_mmap(struct mm_struct *mm)
747static int de_thread(struct task_struct *tsk) 747static int de_thread(struct task_struct *tsk)
748{ 748{
749 struct signal_struct *sig = tsk->signal; 749 struct signal_struct *sig = tsk->signal;
750 struct sighand_struct *newsighand, *oldsighand = tsk->sighand; 750 struct sighand_struct *oldsighand = tsk->sighand;
751 spinlock_t *lock = &oldsighand->siglock; 751 spinlock_t *lock = &oldsighand->siglock;
752 struct task_struct *leader = NULL; 752 struct task_struct *leader = NULL;
753 int count; 753 int count;
@@ -761,10 +761,6 @@ static int de_thread(struct task_struct *tsk)
761 return 0; 761 return 0;
762 } 762 }
763 763
764 newsighand = kmem_cache_alloc(sighand_cachep, GFP_KERNEL);
765 if (!newsighand)
766 return -ENOMEM;
767
768 if (thread_group_empty(tsk)) 764 if (thread_group_empty(tsk))
769 goto no_thread_group; 765 goto no_thread_group;
770 766
@@ -781,7 +777,6 @@ static int de_thread(struct task_struct *tsk)
781 */ 777 */
782 spin_unlock_irq(lock); 778 spin_unlock_irq(lock);
783 read_unlock(&tasklist_lock); 779 read_unlock(&tasklist_lock);
784 kmem_cache_free(sighand_cachep, newsighand);
785 return -EAGAIN; 780 return -EAGAIN;
786 } 781 }
787 782
@@ -899,17 +894,16 @@ no_thread_group:
899 if (leader) 894 if (leader)
900 release_task(leader); 895 release_task(leader);
901 896
902 if (atomic_read(&oldsighand->count) == 1) { 897 if (atomic_read(&oldsighand->count) != 1) {
903 /* 898 struct sighand_struct *newsighand;
904 * Now that we nuked the rest of the thread group,
905 * it turns out we are not sharing sighand any more either.
906 * So we can just keep it.
907 */
908 kmem_cache_free(sighand_cachep, newsighand);
909 } else {
910 /* 899 /*
911 * Move our state over to newsighand and switch it in. 900 * This ->sighand is shared with the CLONE_SIGHAND
901 * but not CLONE_THREAD task, switch to the new one.
912 */ 902 */
903 newsighand = kmem_cache_alloc(sighand_cachep, GFP_KERNEL);
904 if (!newsighand)
905 return -ENOMEM;
906
913 atomic_set(&newsighand->count, 1); 907 atomic_set(&newsighand->count, 1);
914 memcpy(newsighand->action, oldsighand->action, 908 memcpy(newsighand->action, oldsighand->action,
915 sizeof(newsighand->action)); 909 sizeof(newsighand->action));