Skip to content

Commit 0216915

Browse files
committed
exec: Factor unshare_sighand out of de_thread and call it separately
This makes the code clearer and makes it easier to implement a mutex that is not taken over any locations that may block indefinitely waiting for userspace. Signed-off-by: "Eric W. Biederman" <[email protected]> Reviewed-by: Bernd Edlinger <[email protected]> Reviewed-by: Kees Cook <[email protected]> Acked-by: Christian Brauner <[email protected]> Reviewed-by: Kirill Tkhai <[email protected]> Signed-off-by: Bernd Edlinger <[email protected]> Signed-off-by: Eric W. Biederman <[email protected]>
1 parent 2ca7be7 commit 0216915

File tree

1 file changed

+26
-13
lines changed

1 file changed

+26
-13
lines changed

fs/exec.c

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,6 +1194,23 @@ static int de_thread(struct task_struct *tsk)
11941194
flush_itimer_signals();
11951195
#endif
11961196

1197+
BUG_ON(!thread_group_leader(tsk));
1198+
return 0;
1199+
1200+
killed:
1201+
/* protects against exit_notify() and __exit_signal() */
1202+
read_lock(&tasklist_lock);
1203+
sig->group_exit_task = NULL;
1204+
sig->notify_count = 0;
1205+
read_unlock(&tasklist_lock);
1206+
return -EAGAIN;
1207+
}
1208+
1209+
1210+
static int unshare_sighand(struct task_struct *me)
1211+
{
1212+
struct sighand_struct *oldsighand = me->sighand;
1213+
11971214
if (refcount_read(&oldsighand->count) != 1) {
11981215
struct sighand_struct *newsighand;
11991216
/*
@@ -1210,23 +1227,13 @@ static int de_thread(struct task_struct *tsk)
12101227

12111228
write_lock_irq(&tasklist_lock);
12121229
spin_lock(&oldsighand->siglock);
1213-
rcu_assign_pointer(tsk->sighand, newsighand);
1230+
rcu_assign_pointer(me->sighand, newsighand);
12141231
spin_unlock(&oldsighand->siglock);
12151232
write_unlock_irq(&tasklist_lock);
12161233

12171234
__cleanup_sighand(oldsighand);
12181235
}
1219-
1220-
BUG_ON(!thread_group_leader(tsk));
12211236
return 0;
1222-
1223-
killed:
1224-
/* protects against exit_notify() and __exit_signal() */
1225-
read_lock(&tasklist_lock);
1226-
sig->group_exit_task = NULL;
1227-
sig->notify_count = 0;
1228-
read_unlock(&tasklist_lock);
1229-
return -EAGAIN;
12301237
}
12311238

12321239
char *__get_task_comm(char *buf, size_t buf_size, struct task_struct *tsk)
@@ -1264,13 +1271,19 @@ int flush_old_exec(struct linux_binprm * bprm)
12641271
int retval;
12651272

12661273
/*
1267-
* Make sure we have a private signal table and that
1268-
* we are unassociated from the previous thread group.
1274+
* Make this the only thread in the thread group.
12691275
*/
12701276
retval = de_thread(me);
12711277
if (retval)
12721278
goto out;
12731279

1280+
/*
1281+
* Make the signal table private.
1282+
*/
1283+
retval = unshare_sighand(me);
1284+
if (retval)
1285+
goto out;
1286+
12741287
/*
12751288
* Must be called _before_ exec_mmap() as bprm->mm is
12761289
* not visibile until then. This also enables the update

0 commit comments

Comments
 (0)