@@ -1888,27 +1888,47 @@ int get_syscall(struct __test_metadata *_metadata, pid_t tracee)
18881888}
18891889
18901890/* Architecture-specific syscall changing routine. */
1891- void change_syscall (struct __test_metadata * _metadata ,
1892- pid_t tracee , int syscall , int result )
1891+ void __change_syscall (struct __test_metadata * _metadata ,
1892+ pid_t tracee , long * syscall , long * ret )
18931893{
18941894 ARCH_REGS orig , regs ;
18951895
1896+ /* Do not get/set registers if we have nothing to do. */
1897+ if (!syscall && !ret )
1898+ return ;
1899+
18961900 EXPECT_EQ (0 , ARCH_GETREGS (regs )) {
18971901 return ;
18981902 }
18991903 orig = regs ;
19001904
1901- SYSCALL_NUM_SET (regs , syscall );
1905+ if (syscall )
1906+ SYSCALL_NUM_SET (regs , * syscall );
19021907
1903- /* If syscall is skipped, change return value. */
1904- if (syscall == -1 )
1905- SYSCALL_RET_SET (regs , result );
1908+ if (ret )
1909+ SYSCALL_RET_SET (regs , * ret );
19061910
19071911 /* Flush any register changes made. */
19081912 if (memcmp (& orig , & regs , sizeof (orig )) != 0 )
19091913 EXPECT_EQ (0 , ARCH_SETREGS (regs ));
19101914}
19111915
1916+ /* Change only syscall number. */
1917+ void change_syscall_nr (struct __test_metadata * _metadata ,
1918+ pid_t tracee , long syscall )
1919+ {
1920+ __change_syscall (_metadata , tracee , & syscall , NULL );
1921+ }
1922+
1923+ /* Change syscall return value (and set syscall number to -1). */
1924+ void change_syscall_ret (struct __test_metadata * _metadata ,
1925+ pid_t tracee , long ret )
1926+ {
1927+ long syscall = -1 ;
1928+
1929+ __change_syscall (_metadata , tracee , & syscall , & ret );
1930+ }
1931+
19121932void tracer_seccomp (struct __test_metadata * _metadata , pid_t tracee ,
19131933 int status , void * args )
19141934{
@@ -1924,17 +1944,17 @@ void tracer_seccomp(struct __test_metadata *_metadata, pid_t tracee,
19241944 case 0x1002 :
19251945 /* change getpid to getppid. */
19261946 EXPECT_EQ (__NR_getpid , get_syscall (_metadata , tracee ));
1927- change_syscall (_metadata , tracee , __NR_getppid , 0 );
1947+ change_syscall_nr (_metadata , tracee , __NR_getppid );
19281948 break ;
19291949 case 0x1003 :
19301950 /* skip gettid with valid return code. */
19311951 EXPECT_EQ (__NR_gettid , get_syscall (_metadata , tracee ));
1932- change_syscall (_metadata , tracee , -1 , 45000 );
1952+ change_syscall_ret (_metadata , tracee , 45000 );
19331953 break ;
19341954 case 0x1004 :
19351955 /* skip openat with error. */
19361956 EXPECT_EQ (__NR_openat , get_syscall (_metadata , tracee ));
1937- change_syscall (_metadata , tracee , -1 , - ESRCH );
1957+ change_syscall_ret (_metadata , tracee , - ESRCH );
19381958 break ;
19391959 case 0x1005 :
19401960 /* do nothing (allow getppid) */
@@ -1961,6 +1981,8 @@ void tracer_ptrace(struct __test_metadata *_metadata, pid_t tracee,
19611981 int ret ;
19621982 unsigned long msg ;
19631983 static bool entry ;
1984+ long syscall_nr_val , syscall_ret_val ;
1985+ long * syscall_nr = NULL , * syscall_ret = NULL ;
19641986 FIXTURE_DATA (TRACE_syscall ) * self = args ;
19651987
19661988 /*
@@ -1987,17 +2009,30 @@ void tracer_ptrace(struct __test_metadata *_metadata, pid_t tracee,
19872009 else
19882010 return ;
19892011
2012+ syscall_nr = & syscall_nr_val ;
2013+ syscall_ret = & syscall_ret_val ;
2014+
2015+ /* Now handle the actual rewriting cases. */
19902016 switch (self -> syscall_nr ) {
19912017 case __NR_getpid :
1992- change_syscall (_metadata , tracee , __NR_getppid , 0 );
2018+ syscall_nr_val = __NR_getppid ;
2019+ /* Never change syscall return for this case. */
2020+ syscall_ret = NULL ;
19932021 break ;
19942022 case __NR_gettid :
1995- change_syscall (_metadata , tracee , -1 , 45000 );
2023+ syscall_nr_val = -1 ;
2024+ syscall_ret_val = 45000 ;
19962025 break ;
19972026 case __NR_openat :
1998- change_syscall (_metadata , tracee , -1 , - ESRCH );
2027+ syscall_nr_val = -1 ;
2028+ syscall_ret_val = - ESRCH ;
19992029 break ;
2030+ default :
2031+ /* Unhandled, do nothing. */
2032+ return ;
20002033 }
2034+
2035+ __change_syscall (_metadata , tracee , syscall_nr , syscall_ret );
20012036}
20022037
20032038FIXTURE_VARIANT (TRACE_syscall ) {
0 commit comments