diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index e09a4a8ae25fd..5127fb510d519 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -1256,6 +1256,9 @@ INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3, static const int PR_SCHED_CORE = 62; static const int PR_SCHED_CORE_GET = 0; static const int PR_GET_PDEATHSIG = 2; + static const int PR_SET_SECCOMP = 22; + + static const int SECCOMP_MODE_FILTER = 2; if (option == PR_SET_VMA && arg2 == 0UL) { char *name = (char *)arg5; COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); @@ -1274,6 +1277,9 @@ INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3, COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)(arg5), sizeof(u64)); } else if (res != -1 && option == PR_GET_PDEATHSIG) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)(arg2), sizeof(int)); + } else if (res != -1 && option == PR_SET_SECCOMP && + arg2 == SECCOMP_MODE_FILTER) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)(arg3), struct_sock_fprog_sz); } return res; } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp index 6d61d276d77e3..5eeb2a89efa8c 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -117,15 +117,16 @@ typedef struct user_fpregs elf_fpregset_t; #if SANITIZER_LINUX #if SANITIZER_GLIBC #include -#include -#include -#include -#include -#include -#if HAVE_RPC_XDR_H -# include -#endif -#include +# include +# include +# include +# include +# include +# include +# if HAVE_RPC_XDR_H +# include +# endif +# include #else #include #include @@ -531,9 +532,10 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned struct_audio_buf_info_sz = sizeof(struct audio_buf_info); unsigned struct_ppp_stats_sz = sizeof(struct ppp_stats); -#endif // SANITIZER_GLIBC + unsigned struct_sock_fprog_sz = sizeof(struct sock_fprog); +# endif // SANITIZER_GLIBC -#if !SANITIZER_ANDROID && !SANITIZER_APPLE +# if !SANITIZER_ANDROID && !SANITIZER_APPLE unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req); unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req); #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 34bfef1f7ef45..ca03841ccc198 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -1050,7 +1050,8 @@ extern unsigned struct_serial_struct_sz; extern unsigned struct_sockaddr_ax25_sz; extern unsigned struct_unimapdesc_sz; extern unsigned struct_unimapinit_sz; -#endif // SANITIZER_LINUX && !SANITIZER_ANDROID +extern unsigned struct_sock_fprog_sz; +# endif // SANITIZER_LINUX && !SANITIZER_ANDROID extern const unsigned long __sanitizer_bufsiz; diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp index cbff02d66efa7..dab1d1b48f868 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp @@ -4,6 +4,8 @@ #include #include +#include +#include #include #include #include @@ -78,5 +80,13 @@ int main() { } } + sock_filter f[] = {{.code = (BPF_LD | BPF_W | BPF_ABS), + .k = (uint32_t)(SKF_AD_OFF | SKF_AD_CPU)}, + {.code = (BPF_RET | BPF_A), .k = 0}}; + sock_fprog pr = {.len = 2, .filter = f}; + + res = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &pr); + assert(res == -1); + return 0; }