Hi Tycho, I love your patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.17-rc5] [cannot apply to next-20180517] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Tycho-Andersen/seccomp-trap-to-userspace/20180519-071527 config: i386-randconfig-a1-05181545 (attached as .config) compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4 reproduce: # save the attached .config to linux build tree make ARCH=i386 All error/warnings (new ones prefixed by >>): kernel/seccomp.c: In function '__seccomp_filter': kernel/seccomp.c:891:46: warning: passing argument 2 of 'seccomp_do_user_notification' makes integer from pointer without a cast seccomp_do_user_notification(this_syscall, match, sd); ^ kernel/seccomp.c:802:13: note: expected 'u32' but argument is of type 'struct seccomp_filter *' static void seccomp_do_user_notification(int this_syscall, ^ >> kernel/seccomp.c:891:53: warning: passing argument 3 of 'seccomp_do_user_notification' from incompatible pointer type seccomp_do_user_notification(this_syscall, match, sd); ^ kernel/seccomp.c:802:13: note: expected 'struct seccomp_filter *' but argument is of type 'const struct seccomp_data *' static void seccomp_do_user_notification(int this_syscall, ^ kernel/seccomp.c:891:3: error: too few arguments to function 'seccomp_do_user_notification' seccomp_do_user_notification(this_syscall, match, sd); ^ kernel/seccomp.c:802:13: note: declared here static void seccomp_do_user_notification(int this_syscall, ^ kernel/seccomp.c: In function 'seccomp_set_mode_filter': >> kernel/seccomp.c:1036:3: error: implicit declaration of function 'get_unused_fd_flags' [-Werror=implicit-function-declaration] listener = get_unused_fd_flags(O_RDWR); ^ >> kernel/seccomp.c:1042:3: error: implicit declaration of function 'init_listener' [-Werror=implicit-function-declaration] listener_f = init_listener(current, prepared); ^ kernel/seccomp.c:1042:14: warning: assignment makes pointer from integer without a cast listener_f = init_listener(current, prepared); ^ >> kernel/seccomp.c:1044:4: error: implicit declaration of function 'put_unused_fd' [-Werror=implicit-function-declaration] put_unused_fd(listener); ^ >> kernel/seccomp.c:1077:4: error: implicit declaration of function 'fput' [-Werror=implicit-function-declaration] fput(listener_f); ^ >> kernel/seccomp.c:1080:4: error: implicit declaration of function 'fd_install' [-Werror=implicit-function-declaration] fd_install(listener, listener_f); ^ cc1: some warnings being treated as errors vim +/get_unused_fd_flags +1036 kernel/seccomp.c 812 813 #ifdef CONFIG_SECCOMP_FILTER 814 static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd, 815 const bool recheck_after_trace) 816 { 817 u32 filter_ret, action; 818 struct seccomp_filter *match = NULL; 819 int data; 820 821 /* 822 * Make sure that any changes to mode from another thread have 823 * been seen after TIF_SECCOMP was seen. 824 */ 825 rmb(); 826 827 filter_ret = seccomp_run_filters(sd, &match); 828 data = filter_ret & SECCOMP_RET_DATA; 829 action = filter_ret & SECCOMP_RET_ACTION_FULL; 830 831 switch (action) { 832 case SECCOMP_RET_ERRNO: 833 /* Set low-order bits as an errno, capped at MAX_ERRNO. */ 834 if (data > MAX_ERRNO) 835 data = MAX_ERRNO; 836 syscall_set_return_value(current, task_pt_regs(current), 837 -data, 0); 838 goto skip; 839 840 case SECCOMP_RET_TRAP: 841 /* Show the handler the original registers. */ 842 syscall_rollback(current, task_pt_regs(current)); 843 /* Let the filter pass back 16 bits of data. */ 844 seccomp_send_sigsys(this_syscall, data); 845 goto skip; 846 847 case SECCOMP_RET_TRACE: 848 /* We've been put in this state by the ptracer already. */ 849 if (recheck_after_trace) 850 return 0; 851 852 /* ENOSYS these calls if there is no tracer attached. */ 853 if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP)) { 854 syscall_set_return_value(current, 855 task_pt_regs(current), 856 -ENOSYS, 0); 857 goto skip; 858 } 859 860 /* Allow the BPF to provide the event message */ 861 ptrace_event(PTRACE_EVENT_SECCOMP, data); 862 /* 863 * The delivery of a fatal signal during event 864 * notification may silently skip tracer notification, 865 * which could leave us with a potentially unmodified 866 * syscall that the tracer would have liked to have 867 * changed. Since the process is about to die, we just 868 * force the syscall to be skipped and let the signal 869 * kill the process and correctly handle any tracer exit 870 * notifications. 871 */ 872 if (fatal_signal_pending(current)) 873 goto skip; 874 /* Check if the tracer forced the syscall to be skipped. */ 875 this_syscall = syscall_get_nr(current, task_pt_regs(current)); 876 if (this_syscall < 0) 877 goto skip; 878 879 /* 880 * Recheck the syscall, since it may have changed. This 881 * intentionally uses a NULL struct seccomp_data to force 882 * a reload of all registers. This does not goto skip since 883 * a skip would have already been reported. 884 */ 885 if (__seccomp_filter(this_syscall, NULL, true)) 886 return -1; 887 888 return 0; 889 890 case SECCOMP_RET_USER_NOTIF: > 891 seccomp_do_user_notification(this_syscall, match, sd); 892 goto skip; 893 case SECCOMP_RET_LOG: 894 seccomp_log(this_syscall, 0, action, true); 895 return 0; 896 897 case SECCOMP_RET_ALLOW: 898 /* 899 * Note that the "match" filter will always be NULL for 900 * this action since SECCOMP_RET_ALLOW is the starting 901 * state in seccomp_run_filters(). 902 */ 903 return 0; 904 905 case SECCOMP_RET_KILL_THREAD: 906 case SECCOMP_RET_KILL_PROCESS: 907 default: 908 seccomp_log(this_syscall, SIGSYS, action, true); 909 /* Dump core only if this is the last remaining thread. */ 910 if (action == SECCOMP_RET_KILL_PROCESS || 911 get_nr_threads(current) == 1) { 912 siginfo_t info; 913 914 /* Show the original registers in the dump. */ 915 syscall_rollback(current, task_pt_regs(current)); 916 /* Trigger a manual coredump since do_exit skips it. */ 917 seccomp_init_siginfo(&info, this_syscall, data); 918 do_coredump(&info); 919 } 920 if (action == SECCOMP_RET_KILL_PROCESS) 921 do_group_exit(SIGSYS); 922 else 923 do_exit(SIGSYS); 924 } 925 926 unreachable(); 927 928 skip: 929 seccomp_log(this_syscall, 0, action, match ? match->log : false); 930 return -1; 931 } 932 #else 933 static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd, 934 const bool recheck_after_trace) 935 { 936 BUG(); 937 } 938 #endif 939 940 int __secure_computing(const struct seccomp_data *sd) 941 { 942 int mode = current->seccomp.mode; 943 int this_syscall; 944 945 if (IS_ENABLED(CONFIG_CHECKPOINT_RESTORE) && 946 unlikely(current->ptrace & PT_SUSPEND_SECCOMP)) 947 return 0; 948 949 this_syscall = sd ? sd->nr : 950 syscall_get_nr(current, task_pt_regs(current)); 951 952 switch (mode) { 953 case SECCOMP_MODE_STRICT: 954 __secure_computing_strict(this_syscall); /* may call do_exit */ 955 return 0; 956 case SECCOMP_MODE_FILTER: 957 return __seccomp_filter(this_syscall, sd, false); 958 default: 959 BUG(); 960 } 961 } 962 #endif /* CONFIG_HAVE_ARCH_SECCOMP_FILTER */ 963 964 long prctl_get_seccomp(void) 965 { 966 return current->seccomp.mode; 967 } 968 969 /** 970 * seccomp_set_mode_strict: internal function for setting strict seccomp 971 * 972 * Once current->seccomp.mode is non-zero, it may not be changed. 973 * 974 * Returns 0 on success or -EINVAL on failure. 975 */ 976 static long seccomp_set_mode_strict(void) 977 { 978 const unsigned long seccomp_mode = SECCOMP_MODE_STRICT; 979 long ret = -EINVAL; 980 981 spin_lock_irq(¤t->sighand->siglock); 982 983 if (!seccomp_may_assign_mode(seccomp_mode)) 984 goto out; 985 986 #ifdef TIF_NOTSC 987 disable_TSC(); 988 #endif 989 seccomp_assign_mode(current, seccomp_mode); 990 ret = 0; 991 992 out: 993 spin_unlock_irq(¤t->sighand->siglock); 994 995 return ret; 996 } 997 998 #ifdef CONFIG_SECCOMP_FILTER 999 #ifdef CONFIG_SECCOMP_USER_NOTIFICATION 1000 static struct file *init_listener(struct task_struct *, 1001 struct seccomp_filter *); 1002 #endif 1003 1004 /** 1005 * seccomp_set_mode_filter: internal function for setting seccomp filter 1006 * @flags: flags to change filter behavior 1007 * @filter: struct sock_fprog containing filter 1008 * 1009 * This function may be called repeatedly to install additional filters. 1010 * Every filter successfully installed will be evaluated (in reverse order) 1011 * for each system call the task makes. 1012 * 1013 * Once current->seccomp.mode is non-zero, it may not be changed. 1014 * 1015 * Returns 0 on success or -EINVAL on failure. 1016 */ 1017 static long seccomp_set_mode_filter(unsigned int flags, 1018 const char __user *filter) 1019 { 1020 const unsigned long seccomp_mode = SECCOMP_MODE_FILTER; 1021 struct seccomp_filter *prepared = NULL; 1022 long ret = -EINVAL; 1023 int listener = 0; 1024 struct file *listener_f = NULL; 1025 1026 /* Validate flags. */ 1027 if (flags & ~SECCOMP_FILTER_FLAG_MASK) 1028 return -EINVAL; 1029 1030 /* Prepare the new filter before holding any locks. */ 1031 prepared = seccomp_prepare_user_filter(filter); 1032 if (IS_ERR(prepared)) 1033 return PTR_ERR(prepared); 1034 1035 if (flags & SECCOMP_FILTER_FLAG_GET_LISTENER) { > 1036 listener = get_unused_fd_flags(O_RDWR); 1037 if (listener < 0) { 1038 ret = listener; 1039 goto out_free; 1040 } 1041 > 1042 listener_f = init_listener(current, prepared); 1043 if (IS_ERR(listener_f)) { > 1044 put_unused_fd(listener); 1045 ret = PTR_ERR(listener_f); 1046 goto out_free; 1047 } 1048 } 1049 1050 /* 1051 * Make sure we cannot change seccomp or nnp state via TSYNC 1052 * while another thread is in the middle of calling exec. 1053 */ 1054 if (flags & SECCOMP_FILTER_FLAG_TSYNC && 1055 mutex_lock_killable(¤t->signal->cred_guard_mutex)) 1056 goto out_put_fd; 1057 1058 spin_lock_irq(¤t->sighand->siglock); 1059 1060 if (!seccomp_may_assign_mode(seccomp_mode)) 1061 goto out; 1062 1063 ret = seccomp_attach_filter(flags, prepared); 1064 if (ret) 1065 goto out; 1066 /* Do not free the successfully attached filter. */ 1067 prepared = NULL; 1068 1069 seccomp_assign_mode(current, seccomp_mode); 1070 out: 1071 spin_unlock_irq(¤t->sighand->siglock); 1072 if (flags & SECCOMP_FILTER_FLAG_TSYNC) 1073 mutex_unlock(¤t->signal->cred_guard_mutex); 1074 out_put_fd: 1075 if (flags & SECCOMP_FILTER_FLAG_GET_LISTENER) { 1076 if (ret < 0) { > 1077 fput(listener_f); 1078 put_unused_fd(listener); 1079 } else { > 1080 fd_install(listener, listener_f); 1081 ret = listener; 1082 } 1083 } 1084 out_free: 1085 seccomp_filter_free(prepared); 1086 return ret; 1087 } 1088 #else 1089 static inline long seccomp_set_mode_filter(unsigned int flags, 1090 const char __user *filter) 1091 { 1092 return -EINVAL; 1093 } 1094 #endif 1095 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation