@@ -1053,7 +1053,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
10531053unsigned long stack_size ,
10541054int __user * child_tidptr ,
10551055struct pid * pid ,
1056- int trace )
1056+ int trace ,
1057+ int proctrace )
10571058{
10581059int retval ;
10591060struct task_struct * p ;
@@ -1358,6 +1359,11 @@ static struct task_struct *copy_process(unsigned long clone_flags,
13581359
13591360if (likely (p -> pid )) {
13601361ptrace_init_task (p , (clone_flags & CLONE_PTRACE ) || trace );
1362+ if (proctrace && proctrace_event_enabled (current , proctrace )) {
1363+ // stop it
1364+ sigaddset (& p -> pending .signal , SIGSTOP );
1365+ set_tsk_thread_flag (p , TIF_SIGPENDING );
1366+ }
13611367
13621368if (thread_group_leader (p )) {
13631369if (is_child_reaper (pid ))
@@ -1456,7 +1462,7 @@ struct task_struct * __cpuinit fork_idle(int cpu)
14561462struct pt_regs regs ;
14571463
14581464task = copy_process (CLONE_VM , 0 , idle_regs (& regs ), 0 , NULL ,
1459- & init_struct_pid , 0 );
1465+ & init_struct_pid , 0 , 0 );
14601466if (!IS_ERR (task )) {
14611467init_idle_pids (task -> pids );
14621468init_idle (task , cpu );
@@ -1480,6 +1486,7 @@ long do_fork(unsigned long clone_flags,
14801486{
14811487struct task_struct * p ;
14821488int trace = 0 ;
1489+ int proctrace_event = 0 ;
14831490long nr ;
14841491
14851492/*
@@ -1504,19 +1511,27 @@ long do_fork(unsigned long clone_flags,
15041511 * for the type of forking is enabled.
15051512 */
15061513if (likely (user_mode (regs )) && !(clone_flags & CLONE_UNTRACED )) {
1507- if (clone_flags & CLONE_VFORK )
1514+ if (clone_flags & CLONE_VFORK ) {
15081515trace = PTRACE_EVENT_VFORK ;
1509- else if ((clone_flags & CSIGNAL ) != SIGCHLD )
1516+ proctrace_event = PROCTRACE_VFORK ;
1517+ } else if ((clone_flags & CSIGNAL ) != SIGCHLD ) {
15101518trace = PTRACE_EVENT_CLONE ;
1511- else
1519+ proctrace_event = PROCTRACE_CLONE ;
1520+ } else {
15121521trace = PTRACE_EVENT_FORK ;
1522+ proctrace_event = PROCTRACE_FORK ;
1523+ }
15131524
15141525if (likely (!ptrace_event_enabled (current , trace )))
15151526trace = 0 ;
1527+
1528+ if (likely (!proctrace_event_enabled (current , proctrace_event )))
1529+ proctrace_event = 0 ;
1530+
15161531}
15171532
15181533p = copy_process (clone_flags , stack_start , regs , stack_size ,
1519- child_tidptr , NULL , trace );
1534+ child_tidptr , NULL , trace , proctrace_event );
15201535/*
15211536 * Do this prior waking up the new thread - the thread pointer
15221537 * might get invalid after that point, if the thread exits quickly.
@@ -1552,11 +1567,15 @@ long do_fork(unsigned long clone_flags,
15521567if (unlikely (trace ))
15531568ptrace_event (trace , nr );
15541569
1570+ if (unlikely (proctrace_event ))
1571+ proctrace_send_event (proctrace_event , nr );
1572+
15551573if (clone_flags & CLONE_VFORK ) {
15561574freezer_do_not_count ();
15571575wait_for_completion (& vfork );
15581576freezer_count ();
15591577ptrace_event (PTRACE_EVENT_VFORK_DONE , nr );
1578+ proctrace_send_event (PROCTRACE_VFORK_DONE , nr );
15601579}
15611580} else {
15621581nr = PTR_ERR (p );
0 commit comments