[v6,2/5] seccomp: make get_nth_filter available outside of CHECKPOINT_RESTORE

Submitted by Tycho Andersen on Sept. 6, 2018, 3:28 p.m.

Details

Message ID 20180906152859.7810-3-tycho@tycho.ws
State New
Series "seccomp trap to userspace"
Headers show

Commit Message

Tycho Andersen Sept. 6, 2018, 3:28 p.m.
In the next commit we'll use this same mnemonic to get a listener for the
nth filter, so we need it available outside of CHECKPOINT_RESTORE in the
USER_NOTIFICATION case as well.

v2: new in v2
v3: no changes
v4: no changes
v5: switch to CHECKPOINT_RESTORE || USER_NOTIFICATION to avoid warning when
    only CONFIG_SECCOMP_FILTER is enabled.

Signed-off-by: Tycho Andersen <tycho@tycho.ws>
CC: Kees Cook <keescook@chromium.org>
CC: Andy Lutomirski <luto@amacapital.net>
CC: Oleg Nesterov <oleg@redhat.com>
CC: Eric W. Biederman <ebiederm@xmission.com>
CC: "Serge E. Hallyn" <serge@hallyn.com>
CC: Christian Brauner <christian.brauner@ubuntu.com>
CC: Tyler Hicks <tyhicks@canonical.com>
CC: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
---
 kernel/seccomp.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index a09eb5c05f68..ed786655186d 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -1188,7 +1188,8 @@  long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter)
 	return do_seccomp(op, 0, uargs);
 }
 
-#if defined(CONFIG_SECCOMP_FILTER) && defined(CONFIG_CHECKPOINT_RESTORE)
+#if defined(CONFIG_CHECKPOINT_RESTORE) || \
+	defined(CONFIG_SECCOMP_USER_NOTIFICATION)
 static struct seccomp_filter *get_nth_filter(struct task_struct *task,
 					     unsigned long filter_off)
 {
@@ -1235,6 +1236,7 @@  static struct seccomp_filter *get_nth_filter(struct task_struct *task,
 	return filter;
 }
 
+#if defined(CONFIG_CHECKPOINT_RESTORE)
 long seccomp_get_filter(struct task_struct *task, unsigned long filter_off,
 			void __user *data)
 {
@@ -1307,7 +1309,8 @@  long seccomp_get_metadata(struct task_struct *task,
 	__put_seccomp_filter(filter);
 	return ret;
 }
-#endif
+#endif /* CONFIG_CHECKPOINT_RESTORE */
+#endif /* CONFIG_SECCOMP_FILTER */
 
 #ifdef CONFIG_SYSCTL
 

Comments

kbuild test robot Sept. 11, 2018, 10:25 a.m.
Hi Tycho,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.19-rc3]
[cannot apply to next-20180910]
[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/20180907-130604
config: sparc64-allyesconfig (attached as .config)
compiler: sparc64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=7.2.0 make.cross ARCH=sparc64 

All errors (new ones prefixed by >>):

   kernel/seccomp.c: In function 'get_nth_filter':
>> kernel/seccomp.c:1211:2: error: implicit declaration of function '__get_seccomp_filter'; did you mean 'get_seccomp_filter'? [-Werror=implicit-function-declaration]
     __get_seccomp_filter(orig);
     ^~~~~~~~~~~~~~~~~~~~
     get_seccomp_filter
>> kernel/seccomp.c:1215:45: error: dereferencing pointer to incomplete type 'struct seccomp_filter'
     for (filter = orig; filter; filter = filter->prev)
                                                ^~
>> kernel/seccomp.c:1235:2: error: implicit declaration of function '__put_seccomp_filter'; did you mean 'put_seccomp_filter'? [-Werror=implicit-function-declaration]
     __put_seccomp_filter(orig);
     ^~~~~~~~~~~~~~~~~~~~
     put_seccomp_filter
   kernel/seccomp.c: At top level:
>> kernel/seccomp.c:1240:6: error: redefinition of 'seccomp_get_filter'
    long seccomp_get_filter(struct task_struct *task, unsigned long filter_off,
         ^~~~~~~~~~~~~~~~~~
   In file included from include/linux/sched.h:21:0,
                    from include/linux/audit.h:26,
                    from kernel/seccomp.c:18:
   include/linux/seccomp.h:103:20: note: previous definition of 'seccomp_get_filter' was here
    static inline long seccomp_get_filter(struct task_struct *task,
                       ^~~~~~~~~~~~~~~~~~
   kernel/seccomp.c: In function 'seccomp_get_filter':
>> kernel/seccomp.c:1266:13: error: dereferencing pointer to incomplete type 'struct sock_fprog_kern'
     ret = fprog->len;
                ^~
>> kernel/seccomp.c:1270:40: error: implicit declaration of function 'bpf_classic_proglen' [-Werror=implicit-function-declaration]
     if (copy_to_user(data, fprog->filter, bpf_classic_proglen(fprog)))
                                           ^~~~~~~~~~~~~~~~~~~
   kernel/seccomp.c: At top level:
>> kernel/seccomp.c:1278:6: error: redefinition of 'seccomp_get_metadata'
    long seccomp_get_metadata(struct task_struct *task,
         ^~~~~~~~~~~~~~~~~~~~
   In file included from include/linux/sched.h:21:0,
                    from include/linux/audit.h:26,
                    from kernel/seccomp.c:18:
   include/linux/seccomp.h:108:20: note: previous definition of 'seccomp_get_metadata' was here
    static inline long seccomp_get_metadata(struct task_struct *task,
                       ^~~~~~~~~~~~~~~~~~~~
   kernel/seccomp.c:1791:21: warning: 'init_listener' defined but not used [-Wunused-function]
    static struct file *init_listener(struct task_struct *task,
                        ^~~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +1211 kernel/seccomp.c

f8e529ed Tycho Andersen 2015-10-27  1190  
4f037b54 Tycho Andersen 2018-09-06  1191  #if defined(CONFIG_CHECKPOINT_RESTORE) || \
4f037b54 Tycho Andersen 2018-09-06  1192  	defined(CONFIG_SECCOMP_USER_NOTIFICATION)
f06eae83 Tycho Andersen 2017-10-11  1193  static struct seccomp_filter *get_nth_filter(struct task_struct *task,
f06eae83 Tycho Andersen 2017-10-11  1194  					     unsigned long filter_off)
f8e529ed Tycho Andersen 2015-10-27  1195  {
f06eae83 Tycho Andersen 2017-10-11  1196  	struct seccomp_filter *orig, *filter;
f06eae83 Tycho Andersen 2017-10-11  1197  	unsigned long count;
f8e529ed Tycho Andersen 2015-10-27  1198  
f06eae83 Tycho Andersen 2017-10-11  1199  	/*
f06eae83 Tycho Andersen 2017-10-11  1200  	 * Note: this is only correct because the caller should be the (ptrace)
f06eae83 Tycho Andersen 2017-10-11  1201  	 * tracer of the task, otherwise lock_task_sighand is needed.
f06eae83 Tycho Andersen 2017-10-11  1202  	 */
f8e529ed Tycho Andersen 2015-10-27  1203  	spin_lock_irq(&task->sighand->siglock);
f06eae83 Tycho Andersen 2017-10-11  1204  
f8e529ed Tycho Andersen 2015-10-27  1205  	if (task->seccomp.mode != SECCOMP_MODE_FILTER) {
f06eae83 Tycho Andersen 2017-10-11  1206  		spin_unlock_irq(&task->sighand->siglock);
f06eae83 Tycho Andersen 2017-10-11  1207  		return ERR_PTR(-EINVAL);
f8e529ed Tycho Andersen 2015-10-27  1208  	}
f8e529ed Tycho Andersen 2015-10-27  1209  
f06eae83 Tycho Andersen 2017-10-11  1210  	orig = task->seccomp.filter;
f06eae83 Tycho Andersen 2017-10-11 @1211  	__get_seccomp_filter(orig);
f06eae83 Tycho Andersen 2017-10-11  1212  	spin_unlock_irq(&task->sighand->siglock);
f06eae83 Tycho Andersen 2017-10-11  1213  
f06eae83 Tycho Andersen 2017-10-11  1214  	count = 0;
f06eae83 Tycho Andersen 2017-10-11 @1215  	for (filter = orig; filter; filter = filter->prev)
f8e529ed Tycho Andersen 2015-10-27  1216  		count++;
f8e529ed Tycho Andersen 2015-10-27  1217  
f8e529ed Tycho Andersen 2015-10-27  1218  	if (filter_off >= count) {
f06eae83 Tycho Andersen 2017-10-11  1219  		filter = ERR_PTR(-ENOENT);
f8e529ed Tycho Andersen 2015-10-27  1220  		goto out;
f8e529ed Tycho Andersen 2015-10-27  1221  	}
f8e529ed Tycho Andersen 2015-10-27  1222  
f06eae83 Tycho Andersen 2017-10-11  1223  	count -= filter_off;
f06eae83 Tycho Andersen 2017-10-11  1224  	for (filter = orig; filter && count > 1; filter = filter->prev)
f8e529ed Tycho Andersen 2015-10-27  1225  		count--;
f8e529ed Tycho Andersen 2015-10-27  1226  
f8e529ed Tycho Andersen 2015-10-27  1227  	if (WARN_ON(count != 1 || !filter)) {
f06eae83 Tycho Andersen 2017-10-11  1228  		filter = ERR_PTR(-ENOENT);
f8e529ed Tycho Andersen 2015-10-27  1229  		goto out;
f8e529ed Tycho Andersen 2015-10-27  1230  	}
f8e529ed Tycho Andersen 2015-10-27  1231  
f06eae83 Tycho Andersen 2017-10-11  1232  	__get_seccomp_filter(filter);
f06eae83 Tycho Andersen 2017-10-11  1233  
f06eae83 Tycho Andersen 2017-10-11  1234  out:
f06eae83 Tycho Andersen 2017-10-11 @1235  	__put_seccomp_filter(orig);
f06eae83 Tycho Andersen 2017-10-11  1236  	return filter;
f06eae83 Tycho Andersen 2017-10-11  1237  }
f06eae83 Tycho Andersen 2017-10-11  1238  
4f037b54 Tycho Andersen 2018-09-06  1239  #if defined(CONFIG_CHECKPOINT_RESTORE)
f06eae83 Tycho Andersen 2017-10-11 @1240  long seccomp_get_filter(struct task_struct *task, unsigned long filter_off,
f06eae83 Tycho Andersen 2017-10-11  1241  			void __user *data)
f06eae83 Tycho Andersen 2017-10-11  1242  {
f06eae83 Tycho Andersen 2017-10-11  1243  	struct seccomp_filter *filter;
f06eae83 Tycho Andersen 2017-10-11  1244  	struct sock_fprog_kern *fprog;
f06eae83 Tycho Andersen 2017-10-11  1245  	long ret;
f06eae83 Tycho Andersen 2017-10-11  1246  
f06eae83 Tycho Andersen 2017-10-11  1247  	if (!capable(CAP_SYS_ADMIN) ||
f06eae83 Tycho Andersen 2017-10-11  1248  	    current->seccomp.mode != SECCOMP_MODE_DISABLED) {
f06eae83 Tycho Andersen 2017-10-11  1249  		return -EACCES;
f06eae83 Tycho Andersen 2017-10-11  1250  	}
f06eae83 Tycho Andersen 2017-10-11  1251  
f06eae83 Tycho Andersen 2017-10-11  1252  	filter = get_nth_filter(task, filter_off);
f06eae83 Tycho Andersen 2017-10-11  1253  	if (IS_ERR(filter))
f06eae83 Tycho Andersen 2017-10-11  1254  		return PTR_ERR(filter);
f06eae83 Tycho Andersen 2017-10-11  1255  
f8e529ed Tycho Andersen 2015-10-27  1256  	fprog = filter->prog->orig_prog;
f8e529ed Tycho Andersen 2015-10-27  1257  	if (!fprog) {
470bf1f2 Mickaël Salaün 2016-03-24  1258  		/* This must be a new non-cBPF filter, since we save
f8e529ed Tycho Andersen 2015-10-27  1259  		 * every cBPF filter's orig_prog above when
f8e529ed Tycho Andersen 2015-10-27  1260  		 * CONFIG_CHECKPOINT_RESTORE is enabled.
f8e529ed Tycho Andersen 2015-10-27  1261  		 */
f8e529ed Tycho Andersen 2015-10-27  1262  		ret = -EMEDIUMTYPE;
f8e529ed Tycho Andersen 2015-10-27  1263  		goto out;
f8e529ed Tycho Andersen 2015-10-27  1264  	}
f8e529ed Tycho Andersen 2015-10-27  1265  
f8e529ed Tycho Andersen 2015-10-27 @1266  	ret = fprog->len;
f8e529ed Tycho Andersen 2015-10-27  1267  	if (!data)
f8e529ed Tycho Andersen 2015-10-27  1268  		goto out;
f8e529ed Tycho Andersen 2015-10-27  1269  
f8e529ed Tycho Andersen 2015-10-27 @1270  	if (copy_to_user(data, fprog->filter, bpf_classic_proglen(fprog)))
f8e529ed Tycho Andersen 2015-10-27  1271  		ret = -EFAULT;
f8e529ed Tycho Andersen 2015-10-27  1272  
f8e529ed Tycho Andersen 2015-10-27  1273  out:
66a733ea Oleg Nesterov  2017-09-27  1274  	__put_seccomp_filter(filter);
f8e529ed Tycho Andersen 2015-10-27  1275  	return ret;
f8e529ed Tycho Andersen 2015-10-27  1276  }
f8e529ed Tycho Andersen 2015-10-27  1277  
26500475 Tycho Andersen 2017-10-11 @1278  long seccomp_get_metadata(struct task_struct *task,
26500475 Tycho Andersen 2017-10-11  1279  			  unsigned long size, void __user *data)
26500475 Tycho Andersen 2017-10-11  1280  {
26500475 Tycho Andersen 2017-10-11  1281  	long ret;
26500475 Tycho Andersen 2017-10-11  1282  	struct seccomp_filter *filter;
26500475 Tycho Andersen 2017-10-11  1283  	struct seccomp_metadata kmd = {};
26500475 Tycho Andersen 2017-10-11  1284  
26500475 Tycho Andersen 2017-10-11  1285  	if (!capable(CAP_SYS_ADMIN) ||
26500475 Tycho Andersen 2017-10-11  1286  	    current->seccomp.mode != SECCOMP_MODE_DISABLED) {
26500475 Tycho Andersen 2017-10-11  1287  		return -EACCES;
26500475 Tycho Andersen 2017-10-11  1288  	}
26500475 Tycho Andersen 2017-10-11  1289  
26500475 Tycho Andersen 2017-10-11  1290  	size = min_t(unsigned long, size, sizeof(kmd));
26500475 Tycho Andersen 2017-10-11  1291  
63bb0045 Tycho Andersen 2018-02-20  1292  	if (size < sizeof(kmd.filter_off))
63bb0045 Tycho Andersen 2018-02-20  1293  		return -EINVAL;
63bb0045 Tycho Andersen 2018-02-20  1294  
63bb0045 Tycho Andersen 2018-02-20  1295  	if (copy_from_user(&kmd.filter_off, data, sizeof(kmd.filter_off)))
26500475 Tycho Andersen 2017-10-11  1296  		return -EFAULT;
26500475 Tycho Andersen 2017-10-11  1297  
26500475 Tycho Andersen 2017-10-11  1298  	filter = get_nth_filter(task, kmd.filter_off);
26500475 Tycho Andersen 2017-10-11  1299  	if (IS_ERR(filter))
26500475 Tycho Andersen 2017-10-11  1300  		return PTR_ERR(filter);
26500475 Tycho Andersen 2017-10-11  1301  
26500475 Tycho Andersen 2017-10-11  1302  	if (filter->log)
26500475 Tycho Andersen 2017-10-11  1303  		kmd.flags |= SECCOMP_FILTER_FLAG_LOG;
26500475 Tycho Andersen 2017-10-11  1304  
26500475 Tycho Andersen 2017-10-11  1305  	ret = size;
26500475 Tycho Andersen 2017-10-11  1306  	if (copy_to_user(data, &kmd, size))
26500475 Tycho Andersen 2017-10-11  1307  		ret = -EFAULT;
26500475 Tycho Andersen 2017-10-11  1308  
26500475 Tycho Andersen 2017-10-11  1309  	__put_seccomp_filter(filter);
f8e529ed Tycho Andersen 2015-10-27  1310  	return ret;
f8e529ed Tycho Andersen 2015-10-27  1311  }
4f037b54 Tycho Andersen 2018-09-06  1312  #endif /* CONFIG_CHECKPOINT_RESTORE */
4f037b54 Tycho Andersen 2018-09-06  1313  #endif /* CONFIG_SECCOMP_FILTER */
8e5f1ad1 Tyler Hicks    2017-08-11  1314  

:::::: The code at line 1211 was first introduced by commit
:::::: f06eae831f0c1fc5b982ea200daf552810e1dd55 seccomp: hoist out filter resolving logic

:::::: TO: Tycho Andersen <tycho@docker.com>
:::::: CC: Kees Cook <keescook@chromium.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation