@@ -774,8 +774,15 @@ void *kill_thread(void *data)
774774 return (void * )SIBLING_EXIT_UNKILLED ;
775775}
776776
777+ enum kill_t {
778+ KILL_THREAD ,
779+ KILL_PROCESS ,
780+ RET_UNKNOWN
781+ };
782+
777783/* Prepare a thread that will kill itself or both of us. */
778- void kill_thread_or_group (struct __test_metadata * _metadata , bool kill_process )
784+ void kill_thread_or_group (struct __test_metadata * _metadata ,
785+ enum kill_t kill_how )
779786{
780787 pthread_t thread ;
781788 void * status ;
@@ -791,11 +798,12 @@ void kill_thread_or_group(struct __test_metadata *_metadata, bool kill_process)
791798 .len = (unsigned short )ARRAY_SIZE (filter_thread ),
792799 .filter = filter_thread ,
793800 };
801+ int kill = kill_how == KILL_PROCESS ? SECCOMP_RET_KILL_PROCESS : 0xAAAAAAAAA ;
794802 struct sock_filter filter_process [] = {
795803 BPF_STMT (BPF_LD |BPF_W |BPF_ABS ,
796804 offsetof(struct seccomp_data , nr )),
797805 BPF_JUMP (BPF_JMP |BPF_JEQ |BPF_K , __NR_prctl , 0 , 1 ),
798- BPF_STMT (BPF_RET |BPF_K , SECCOMP_RET_KILL_PROCESS ),
806+ BPF_STMT (BPF_RET |BPF_K , kill ),
799807 BPF_STMT (BPF_RET |BPF_K , SECCOMP_RET_ALLOW ),
800808 };
801809 struct sock_fprog prog_process = {
@@ -808,13 +816,15 @@ void kill_thread_or_group(struct __test_metadata *_metadata, bool kill_process)
808816 }
809817
810818 ASSERT_EQ (0 , seccomp (SECCOMP_SET_MODE_FILTER , 0 ,
811- kill_process ? & prog_process : & prog_thread ));
819+ kill_how == KILL_THREAD ? & prog_thread
820+ : & prog_process ));
812821
813822 /*
814823 * Add the KILL_THREAD rule again to make sure that the KILL_PROCESS
815824 * flag cannot be downgraded by a new filter.
816825 */
817- ASSERT_EQ (0 , seccomp (SECCOMP_SET_MODE_FILTER , 0 , & prog_thread ));
826+ if (kill_how == KILL_PROCESS )
827+ ASSERT_EQ (0 , seccomp (SECCOMP_SET_MODE_FILTER , 0 , & prog_thread ));
818828
819829 /* Start a thread that will exit immediately. */
820830 ASSERT_EQ (0 , pthread_create (& thread , NULL , kill_thread , (void * )false));
@@ -842,7 +852,7 @@ TEST(KILL_thread)
842852 child_pid = fork ();
843853 ASSERT_LE (0 , child_pid );
844854 if (child_pid == 0 ) {
845- kill_thread_or_group (_metadata , false );
855+ kill_thread_or_group (_metadata , KILL_THREAD );
846856 _exit (38 );
847857 }
848858
@@ -861,7 +871,7 @@ TEST(KILL_process)
861871 child_pid = fork ();
862872 ASSERT_LE (0 , child_pid );
863873 if (child_pid == 0 ) {
864- kill_thread_or_group (_metadata , true );
874+ kill_thread_or_group (_metadata , KILL_PROCESS );
865875 _exit (38 );
866876 }
867877
@@ -872,6 +882,27 @@ TEST(KILL_process)
872882 ASSERT_EQ (SIGSYS , WTERMSIG (status ));
873883}
874884
885+ TEST (KILL_unknown )
886+ {
887+ int status ;
888+ pid_t child_pid ;
889+
890+ child_pid = fork ();
891+ ASSERT_LE (0 , child_pid );
892+ if (child_pid == 0 ) {
893+ kill_thread_or_group (_metadata , RET_UNKNOWN );
894+ _exit (38 );
895+ }
896+
897+ ASSERT_EQ (child_pid , waitpid (child_pid , & status , 0 ));
898+
899+ /* If the entire process was killed, we'll see SIGSYS. */
900+ EXPECT_TRUE (WIFSIGNALED (status )) {
901+ TH_LOG ("Unknown SECCOMP_RET is only killing the thread?" );
902+ }
903+ ASSERT_EQ (SIGSYS , WTERMSIG (status ));
904+ }
905+
875906/* TODO(wad) add 64-bit versus 32-bit arg tests. */
876907TEST (arg_out_of_range )
877908{
0 commit comments