VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
09c434b8a0047 (Thomas Gleixner               2019-05-19 13:08:20 +0100   1) // SPDX-License-Identifier: GPL-2.0-only
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700   2) /*
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800   3)  * binfmt_misc.c
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700   4)  *
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800   5)  * Copyright (C) 1997 Richard Günther
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700   6)  *
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800   7)  * binfmt_misc detects binaries via a magic or filename extension and invokes
34962fb8070cb (Mauro Carvalho Chehab         2018-05-08 15:14:57 -0300   8)  * a specified wrapper. See Documentation/admin-guide/binfmt-misc.rst for more details.
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700   9)  */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  10) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800  11) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800  12) 
6ceafb880c218 (Rasmus Villemoes              2015-04-16 12:44:56 -0700  13) #include <linux/kernel.h>
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  14) #include <linux/module.h>
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  15) #include <linux/init.h>
589ee62844e04 (Ingo Molnar                   2017-02-04 00:16:44 +0100  16) #include <linux/sched/mm.h>
b502bd1152472 (Muthu Kumar                   2012-03-23 15:01:50 -0700  17) #include <linux/magic.h>
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  18) #include <linux/binfmts.h>
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  19) #include <linux/slab.h>
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  20) #include <linux/ctype.h>
8d82e180b51f8 (Andy Shevchenko               2013-04-30 15:27:33 -0700  21) #include <linux/string_helpers.h>
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  22) #include <linux/file.h>
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  23) #include <linux/pagemap.h>
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  24) #include <linux/namei.h>
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  25) #include <linux/mount.h>
bc99a664e9be2 (David Howells                 2019-03-25 16:38:28 +0000  26) #include <linux/fs_context.h>
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  27) #include <linux/syscalls.h>
6e2c10a12a217 (Akinobu Mita                  2008-07-23 21:29:15 -0700  28) #include <linux/fs.h>
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800  29) #include <linux/uaccess.h>
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  30) 
948b701a607f1 (James Bottomley               2016-02-17 16:51:16 -0800  31) #include "internal.h"
948b701a607f1 (James Bottomley               2016-02-17 16:51:16 -0800  32) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800  33) #ifdef DEBUG
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800  34) # define USE_DEBUG 1
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800  35) #else
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800  36) # define USE_DEBUG 0
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800  37) #endif
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  38) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  39) enum {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  40) 	VERBOSE_STATUS = 1 /* make it zero to save 400 bytes kernel memory */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  41) };
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  42) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  43) static LIST_HEAD(entries);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  44) static int enabled = 1;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  45) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  46) enum {Enabled, Magic};
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800  47) #define MISC_FMT_PRESERVE_ARGV0 (1 << 31)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800  48) #define MISC_FMT_OPEN_BINARY (1 << 30)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800  49) #define MISC_FMT_CREDENTIALS (1 << 29)
948b701a607f1 (James Bottomley               2016-02-17 16:51:16 -0800  50) #define MISC_FMT_OPEN_FILE (1 << 28)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  51) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  52) typedef struct {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  53) 	struct list_head list;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  54) 	unsigned long flags;		/* type, status, etc. */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  55) 	int offset;			/* offset of magic */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  56) 	int size;			/* size of magic/mask */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  57) 	char *magic;			/* magic or filename extension */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  58) 	char *mask;			/* mask, NULL for exact match */
50097f74934e3 (Oleg Nesterov                 2017-10-03 16:15:58 -0700  59) 	const char *interpreter;	/* filename of interpreter */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  60) 	char *name;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  61) 	struct dentry *dentry;
948b701a607f1 (James Bottomley               2016-02-17 16:51:16 -0800  62) 	struct file *interp_file;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  63) } Node;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  64) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  65) static DEFINE_RWLOCK(entries_lock);
1f5ce9e93aa96 (Trond Myklebust               2006-06-09 09:34:16 -0400  66) static struct file_system_type bm_fs_type;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  67) static struct vfsmount *bm_mnt;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  68) static int entry_count;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  69) 
bbaecc088245e (Mike Frysinger                2014-10-13 15:52:03 -0700  70) /*
bbaecc088245e (Mike Frysinger                2014-10-13 15:52:03 -0700  71)  * Max length of the register string.  Determined by:
bbaecc088245e (Mike Frysinger                2014-10-13 15:52:03 -0700  72)  *  - 7 delimiters
bbaecc088245e (Mike Frysinger                2014-10-13 15:52:03 -0700  73)  *  - name:   ~50 bytes
bbaecc088245e (Mike Frysinger                2014-10-13 15:52:03 -0700  74)  *  - type:   1 byte
bbaecc088245e (Mike Frysinger                2014-10-13 15:52:03 -0700  75)  *  - offset: 3 bytes (has to be smaller than BINPRM_BUF_SIZE)
bbaecc088245e (Mike Frysinger                2014-10-13 15:52:03 -0700  76)  *  - magic:  128 bytes (512 in escaped form)
bbaecc088245e (Mike Frysinger                2014-10-13 15:52:03 -0700  77)  *  - mask:   128 bytes (512 in escaped form)
bbaecc088245e (Mike Frysinger                2014-10-13 15:52:03 -0700  78)  *  - interp: ~50 bytes
bbaecc088245e (Mike Frysinger                2014-10-13 15:52:03 -0700  79)  *  - flags:  5 bytes
bbaecc088245e (Mike Frysinger                2014-10-13 15:52:03 -0700  80)  * Round that up a bit, and then back off to hold the internal data
bbaecc088245e (Mike Frysinger                2014-10-13 15:52:03 -0700  81)  * (like struct Node).
bbaecc088245e (Mike Frysinger                2014-10-13 15:52:03 -0700  82)  */
bbaecc088245e (Mike Frysinger                2014-10-13 15:52:03 -0700  83) #define MAX_REGISTER_LENGTH 1920
bbaecc088245e (Mike Frysinger                2014-10-13 15:52:03 -0700  84) 
bbaecc088245e (Mike Frysinger                2014-10-13 15:52:03 -0700  85) /*
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  86)  * Check if we support the binfmt
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  87)  * if we do, return the node, else NULL
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  88)  * locking is done in load_misc_binary
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  89)  */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  90) static Node *check_file(struct linux_binprm *bprm)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  91) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  92) 	char *p = strrchr(bprm->interp, '.');
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  93) 	struct list_head *l;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  94) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800  95) 	/* Walk all the registered handlers. */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  96) 	list_for_each(l, &entries) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  97) 		Node *e = list_entry(l, Node, list);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  98) 		char *s;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700  99) 		int j;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 100) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 101) 		/* Make sure this one is currently enabled. */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 102) 		if (!test_bit(Enabled, &e->flags))
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 103) 			continue;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 104) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 105) 		/* Do matching based on extension if applicable. */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 106) 		if (!test_bit(Magic, &e->flags)) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 107) 			if (p && !strcmp(e->magic, p + 1))
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 108) 				return e;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 109) 			continue;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 110) 		}
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 111) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 112) 		/* Do matching based on magic & mask. */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 113) 		s = bprm->buf + e->offset;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 114) 		if (e->mask) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 115) 			for (j = 0; j < e->size; j++)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 116) 				if ((*s++ ^ e->magic[j]) & e->mask[j])
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 117) 					break;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 118) 		} else {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 119) 			for (j = 0; j < e->size; j++)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 120) 				if ((*s++ ^ e->magic[j]))
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 121) 					break;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 122) 		}
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 123) 		if (j == e->size)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 124) 			return e;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 125) 	}
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 126) 	return NULL;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 127) }
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 128) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 129) /*
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 130)  * the loader itself
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 131)  */
71613c3b871c5 (Al Viro                       2012-10-20 22:00:48 -0400 132) static int load_misc_binary(struct linux_binprm *bprm)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 133) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 134) 	Node *fmt;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 135) 	struct file *interp_file = NULL;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 136) 	int retval;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 137) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 138) 	retval = -ENOEXEC;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 139) 	if (!enabled)
43a4f26190380 (Oleg Nesterov                 2017-10-03 16:15:55 -0700 140) 		return retval;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 141) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 142) 	/* to keep locking time low, we copy the interpreter string */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 143) 	read_lock(&entries_lock);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 144) 	fmt = check_file(bprm);
50097f74934e3 (Oleg Nesterov                 2017-10-03 16:15:58 -0700 145) 	if (fmt)
43a4f26190380 (Oleg Nesterov                 2017-10-03 16:15:55 -0700 146) 		dget(fmt->dentry);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 147) 	read_unlock(&entries_lock);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 148) 	if (!fmt)
43a4f26190380 (Oleg Nesterov                 2017-10-03 16:15:55 -0700 149) 		return retval;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 150) 
51f39a1f0cea1 (David Drysdale                2014-12-12 16:57:29 -0800 151) 	/* Need to be able to load the file after exec */
43a4f26190380 (Oleg Nesterov                 2017-10-03 16:15:55 -0700 152) 	retval = -ENOENT;
51f39a1f0cea1 (David Drysdale                2014-12-12 16:57:29 -0800 153) 	if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
43a4f26190380 (Oleg Nesterov                 2017-10-03 16:15:55 -0700 154) 		goto ret;
51f39a1f0cea1 (David Drysdale                2014-12-12 16:57:29 -0800 155) 
2347961b11d40 (Laurent Vivier                2020-01-28 14:25:39 +0100 156) 	if (fmt->flags & MISC_FMT_PRESERVE_ARGV0) {
2347961b11d40 (Laurent Vivier                2020-01-28 14:25:39 +0100 157) 		bprm->interp_flags |= BINPRM_FLAGS_PRESERVE_ARGV0;
2347961b11d40 (Laurent Vivier                2020-01-28 14:25:39 +0100 158) 	} else {
b6a2fea39318e (Ollie Wild                    2007-07-19 01:48:16 -0700 159) 		retval = remove_arg_zero(bprm);
b6a2fea39318e (Ollie Wild                    2007-07-19 01:48:16 -0700 160) 		if (retval)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 161) 			goto ret;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 162) 	}
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 163) 
bc2bf338d54b7 (Eric W. Biederman             2020-05-18 18:43:20 -0500 164) 	if (fmt->flags & MISC_FMT_OPEN_BINARY)
b8a61c9e7b4a0 (Eric W. Biederman             2020-05-14 15:17:40 -0500 165) 		bprm->have_execfd = 1;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 166) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 167) 	/* make argv[1] be the path to the binary */
986db2d14a6dc (Christoph Hellwig             2020-06-04 16:51:14 -0700 168) 	retval = copy_string_kernel(bprm->interp, bprm);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 169) 	if (retval < 0)
b8a61c9e7b4a0 (Eric W. Biederman             2020-05-14 15:17:40 -0500 170) 		goto ret;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 171) 	bprm->argc++;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 172) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 173) 	/* add the interp as argv[0] */
986db2d14a6dc (Christoph Hellwig             2020-06-04 16:51:14 -0700 174) 	retval = copy_string_kernel(fmt->interpreter, bprm);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 175) 	if (retval < 0)
b8a61c9e7b4a0 (Eric W. Biederman             2020-05-14 15:17:40 -0500 176) 		goto ret;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 177) 	bprm->argc++;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 178) 
b66c598401753 (Kees Cook                     2012-12-20 15:05:16 -0800 179) 	/* Update interp in case binfmt_script needs it. */
50097f74934e3 (Oleg Nesterov                 2017-10-03 16:15:58 -0700 180) 	retval = bprm_change_interp(fmt->interpreter, bprm);
b66c598401753 (Kees Cook                     2012-12-20 15:05:16 -0800 181) 	if (retval < 0)
b8a61c9e7b4a0 (Eric W. Biederman             2020-05-14 15:17:40 -0500 182) 		goto ret;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 183) 
eb23aa0317eb1 (Oleg Nesterov                 2017-10-03 16:15:51 -0700 184) 	if (fmt->flags & MISC_FMT_OPEN_FILE) {
19f391eb05b8b (Al Viro                       2018-06-08 11:19:32 -0400 185) 		interp_file = file_clone_open(fmt->interp_file);
948b701a607f1 (James Bottomley               2016-02-17 16:51:16 -0800 186) 		if (!IS_ERR(interp_file))
948b701a607f1 (James Bottomley               2016-02-17 16:51:16 -0800 187) 			deny_write_access(interp_file);
948b701a607f1 (James Bottomley               2016-02-17 16:51:16 -0800 188) 	} else {
50097f74934e3 (Oleg Nesterov                 2017-10-03 16:15:58 -0700 189) 		interp_file = open_exec(fmt->interpreter);
948b701a607f1 (James Bottomley               2016-02-17 16:51:16 -0800 190) 	}
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 191) 	retval = PTR_ERR(interp_file);
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 192) 	if (IS_ERR(interp_file))
b8a61c9e7b4a0 (Eric W. Biederman             2020-05-14 15:17:40 -0500 193) 		goto ret;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 194) 
bc2bf338d54b7 (Eric W. Biederman             2020-05-18 18:43:20 -0500 195) 	bprm->interpreter = interp_file;
a16b3357b2b8e (Eric W. Biederman             2020-05-16 06:02:54 -0500 196) 	if (fmt->flags & MISC_FMT_CREDENTIALS)
56305aa9b6fab (Eric W. Biederman             2020-05-29 22:00:54 -0500 197) 		bprm->execfd_creds = 1;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 198) 
bc2bf338d54b7 (Eric W. Biederman             2020-05-18 18:43:20 -0500 199) 	retval = 0;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 200) ret:
43a4f26190380 (Oleg Nesterov                 2017-10-03 16:15:55 -0700 201) 	dput(fmt->dentry);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 202) 	return retval;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 203) }
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 204) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 205) /* Command parsers */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 206) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 207) /*
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 208)  * parses and copies one argument enclosed in del from *sp to *dp,
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 209)  * recognising the \x special.
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 210)  * returns pointer to the copied argument or NULL in case of an
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 211)  * error (and sets err) or null argument length.
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 212)  */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 213) static char *scanarg(char *s, char del)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 214) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 215) 	char c;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 216) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 217) 	while ((c = *s++) != del) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 218) 		if (c == '\\' && *s == 'x') {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 219) 			s++;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 220) 			if (!isxdigit(*s++))
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 221) 				return NULL;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 222) 			if (!isxdigit(*s++))
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 223) 				return NULL;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 224) 		}
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 225) 	}
7d65cf10e3d77 (Al Viro                       2014-12-17 05:29:16 -0500 226) 	s[-1] ='\0';
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 227) 	return s;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 228) }
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 229) 
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 230) static char *check_special_flags(char *sfs, Node *e)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 231) {
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 232) 	char *p = sfs;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 233) 	int cont = 1;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 234) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 235) 	/* special flags */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 236) 	while (cont) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 237) 		switch (*p) {
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 238) 		case 'P':
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 239) 			pr_debug("register: flag: P (preserve argv0)\n");
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 240) 			p++;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 241) 			e->flags |= MISC_FMT_PRESERVE_ARGV0;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 242) 			break;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 243) 		case 'O':
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 244) 			pr_debug("register: flag: O (open binary)\n");
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 245) 			p++;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 246) 			e->flags |= MISC_FMT_OPEN_BINARY;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 247) 			break;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 248) 		case 'C':
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 249) 			pr_debug("register: flag: C (preserve creds)\n");
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 250) 			p++;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 251) 			/* this flags also implies the
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 252) 			   open-binary flag */
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 253) 			e->flags |= (MISC_FMT_CREDENTIALS |
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 254) 					MISC_FMT_OPEN_BINARY);
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 255) 			break;
948b701a607f1 (James Bottomley               2016-02-17 16:51:16 -0800 256) 		case 'F':
948b701a607f1 (James Bottomley               2016-02-17 16:51:16 -0800 257) 			pr_debug("register: flag: F: open interpreter file now\n");
948b701a607f1 (James Bottomley               2016-02-17 16:51:16 -0800 258) 			p++;
948b701a607f1 (James Bottomley               2016-02-17 16:51:16 -0800 259) 			e->flags |= MISC_FMT_OPEN_FILE;
948b701a607f1 (James Bottomley               2016-02-17 16:51:16 -0800 260) 			break;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 261) 		default:
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 262) 			cont = 0;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 263) 		}
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 264) 	}
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 265) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 266) 	return p;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 267) }
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 268) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 269) /*
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 270)  * This registers a new binary format, it recognises the syntax
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 271)  * ':name:type:offset:magic:mask:interpreter:flags'
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 272)  * where the ':' is the IFS, that can be chosen with the first char
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 273)  */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 274) static Node *create_entry(const char __user *buffer, size_t count)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 275) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 276) 	Node *e;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 277) 	int memsize, err;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 278) 	char *buf, *p;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 279) 	char del;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 280) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 281) 	pr_debug("register: received %zu bytes\n", count);
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 282) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 283) 	/* some sanity checks */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 284) 	err = -EINVAL;
bbaecc088245e (Mike Frysinger                2014-10-13 15:52:03 -0700 285) 	if ((count < 11) || (count > MAX_REGISTER_LENGTH))
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 286) 		goto out;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 287) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 288) 	err = -ENOMEM;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 289) 	memsize = sizeof(Node) + count + 8;
f7e1ad1a1e23a (Andrew Morton                 2014-12-10 15:52:13 -0800 290) 	e = kmalloc(memsize, GFP_KERNEL);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 291) 	if (!e)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 292) 		goto out;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 293) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 294) 	p = buf = (char *)e + sizeof(Node);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 295) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 296) 	memset(e, 0, sizeof(Node));
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 297) 	if (copy_from_user(buf, buffer, count))
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 298) 		goto efault;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 299) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 300) 	del = *p++;	/* delimeter */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 301) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 302) 	pr_debug("register: delim: %#x {%c}\n", del, del);
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 303) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 304) 	/* Pad the buffer with the delim to simplify parsing below. */
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 305) 	memset(buf + count, del, 8);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 306) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 307) 	/* Parse the 'name' field. */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 308) 	e->name = p;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 309) 	p = strchr(p, del);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 310) 	if (!p)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 311) 		goto einval;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 312) 	*p++ = '\0';
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 313) 	if (!e->name[0] ||
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 314) 	    !strcmp(e->name, ".") ||
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 315) 	    !strcmp(e->name, "..") ||
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 316) 	    strchr(e->name, '/'))
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 317) 		goto einval;
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 318) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 319) 	pr_debug("register: name: {%s}\n", e->name);
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 320) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 321) 	/* Parse the 'type' field. */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 322) 	switch (*p++) {
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 323) 	case 'E':
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 324) 		pr_debug("register: type: E (extension)\n");
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 325) 		e->flags = 1 << Enabled;
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 326) 		break;
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 327) 	case 'M':
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 328) 		pr_debug("register: type: M (magic)\n");
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 329) 		e->flags = (1 << Enabled) | (1 << Magic);
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 330) 		break;
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 331) 	default:
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 332) 		goto einval;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 333) 	}
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 334) 	if (*p++ != del)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 335) 		goto einval;
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 336) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 337) 	if (test_bit(Magic, &e->flags)) {
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 338) 		/* Handle the 'M' (magic) format. */
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 339) 		char *s;
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 340) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 341) 		/* Parse the 'offset' field. */
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 342) 		s = strchr(p, del);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 343) 		if (!s)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 344) 			goto einval;
5cc41e099504b (Thadeu Lima de Souza Cascardo 2018-06-07 17:11:01 -0700 345) 		*s = '\0';
5cc41e099504b (Thadeu Lima de Souza Cascardo 2018-06-07 17:11:01 -0700 346) 		if (p != s) {
5cc41e099504b (Thadeu Lima de Souza Cascardo 2018-06-07 17:11:01 -0700 347) 			int r = kstrtoint(p, 10, &e->offset);
5cc41e099504b (Thadeu Lima de Souza Cascardo 2018-06-07 17:11:01 -0700 348) 			if (r != 0 || e->offset < 0)
5cc41e099504b (Thadeu Lima de Souza Cascardo 2018-06-07 17:11:01 -0700 349) 				goto einval;
5cc41e099504b (Thadeu Lima de Souza Cascardo 2018-06-07 17:11:01 -0700 350) 		}
5cc41e099504b (Thadeu Lima de Souza Cascardo 2018-06-07 17:11:01 -0700 351) 		p = s;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 352) 		if (*p++)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 353) 			goto einval;
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 354) 		pr_debug("register: offset: %#x\n", e->offset);
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 355) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 356) 		/* Parse the 'magic' field. */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 357) 		e->magic = p;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 358) 		p = scanarg(p, del);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 359) 		if (!p)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 360) 			goto einval;
7d65cf10e3d77 (Al Viro                       2014-12-17 05:29:16 -0500 361) 		if (!e->magic[0])
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 362) 			goto einval;
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 363) 		if (USE_DEBUG)
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 364) 			print_hex_dump_bytes(
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 365) 				KBUILD_MODNAME ": register: magic[raw]: ",
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 366) 				DUMP_PREFIX_NONE, e->magic, p - e->magic);
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 367) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 368) 		/* Parse the 'mask' field. */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 369) 		e->mask = p;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 370) 		p = scanarg(p, del);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 371) 		if (!p)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 372) 			goto einval;
7d65cf10e3d77 (Al Viro                       2014-12-17 05:29:16 -0500 373) 		if (!e->mask[0]) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 374) 			e->mask = NULL;
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 375) 			pr_debug("register:  mask[raw]: none\n");
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 376) 		} else if (USE_DEBUG)
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 377) 			print_hex_dump_bytes(
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 378) 				KBUILD_MODNAME ": register:  mask[raw]: ",
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 379) 				DUMP_PREFIX_NONE, e->mask, p - e->mask);
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 380) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 381) 		/*
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 382) 		 * Decode the magic & mask fields.
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 383) 		 * Note: while we might have accepted embedded NUL bytes from
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 384) 		 * above, the unescape helpers here will stop at the first one
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 385) 		 * it encounters.
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 386) 		 */
8d82e180b51f8 (Andy Shevchenko               2013-04-30 15:27:33 -0700 387) 		e->size = string_unescape_inplace(e->magic, UNESCAPE_HEX);
8d82e180b51f8 (Andy Shevchenko               2013-04-30 15:27:33 -0700 388) 		if (e->mask &&
8d82e180b51f8 (Andy Shevchenko               2013-04-30 15:27:33 -0700 389) 		    string_unescape_inplace(e->mask, UNESCAPE_HEX) != e->size)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 390) 			goto einval;
5cc41e099504b (Thadeu Lima de Souza Cascardo 2018-06-07 17:11:01 -0700 391) 		if (e->size > BINPRM_BUF_SIZE ||
5cc41e099504b (Thadeu Lima de Souza Cascardo 2018-06-07 17:11:01 -0700 392) 		    BINPRM_BUF_SIZE - e->size < e->offset)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 393) 			goto einval;
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 394) 		pr_debug("register: magic/mask length: %i\n", e->size);
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 395) 		if (USE_DEBUG) {
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 396) 			print_hex_dump_bytes(
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 397) 				KBUILD_MODNAME ": register: magic[decoded]: ",
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 398) 				DUMP_PREFIX_NONE, e->magic, e->size);
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 399) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 400) 			if (e->mask) {
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 401) 				int i;
f7e1ad1a1e23a (Andrew Morton                 2014-12-10 15:52:13 -0800 402) 				char *masked = kmalloc(e->size, GFP_KERNEL);
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 403) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 404) 				print_hex_dump_bytes(
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 405) 					KBUILD_MODNAME ": register:  mask[decoded]: ",
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 406) 					DUMP_PREFIX_NONE, e->mask, e->size);
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 407) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 408) 				if (masked) {
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 409) 					for (i = 0; i < e->size; ++i)
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 410) 						masked[i] = e->magic[i] & e->mask[i];
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 411) 					print_hex_dump_bytes(
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 412) 						KBUILD_MODNAME ": register:  magic[masked]: ",
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 413) 						DUMP_PREFIX_NONE, masked, e->size);
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 414) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 415) 					kfree(masked);
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 416) 				}
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 417) 			}
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 418) 		}
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 419) 	} else {
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 420) 		/* Handle the 'E' (extension) format. */
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 421) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 422) 		/* Skip the 'offset' field. */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 423) 		p = strchr(p, del);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 424) 		if (!p)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 425) 			goto einval;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 426) 		*p++ = '\0';
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 427) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 428) 		/* Parse the 'magic' field. */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 429) 		e->magic = p;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 430) 		p = strchr(p, del);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 431) 		if (!p)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 432) 			goto einval;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 433) 		*p++ = '\0';
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 434) 		if (!e->magic[0] || strchr(e->magic, '/'))
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 435) 			goto einval;
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 436) 		pr_debug("register: extension: {%s}\n", e->magic);
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 437) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 438) 		/* Skip the 'mask' field. */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 439) 		p = strchr(p, del);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 440) 		if (!p)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 441) 			goto einval;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 442) 		*p++ = '\0';
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 443) 	}
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 444) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 445) 	/* Parse the 'interpreter' field. */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 446) 	e->interpreter = p;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 447) 	p = strchr(p, del);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 448) 	if (!p)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 449) 		goto einval;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 450) 	*p++ = '\0';
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 451) 	if (!e->interpreter[0])
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 452) 		goto einval;
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 453) 	pr_debug("register: interpreter: {%s}\n", e->interpreter);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 454) 
6b899c4e9a049 (Mike Frysinger                2014-12-10 15:52:08 -0800 455) 	/* Parse the 'flags' field. */
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 456) 	p = check_special_flags(p, e);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 457) 	if (*p == '\n')
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 458) 		p++;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 459) 	if (p != buf + count)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 460) 		goto einval;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 461) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 462) 	return e;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 463) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 464) out:
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 465) 	return ERR_PTR(err);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 466) 
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 467) efault:
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 468) 	kfree(e);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 469) 	return ERR_PTR(-EFAULT);
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 470) einval:
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 471) 	kfree(e);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 472) 	return ERR_PTR(-EINVAL);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 473) }
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 474) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 475) /*
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 476)  * Set status of entry/binfmt_misc:
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 477)  * '1' enables, '0' disables and '-1' clears entry/binfmt_misc
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 478)  */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 479) static int parse_command(const char __user *buffer, size_t count)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 480) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 481) 	char s[4];
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 482) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 483) 	if (count > 3)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 484) 		return -EINVAL;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 485) 	if (copy_from_user(s, buffer, count))
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 486) 		return -EFAULT;
de8288b1f8714 (Arnd Bergmann                 2014-10-13 15:52:08 -0700 487) 	if (!count)
de8288b1f8714 (Arnd Bergmann                 2014-10-13 15:52:08 -0700 488) 		return 0;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 489) 	if (s[count - 1] == '\n')
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 490) 		count--;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 491) 	if (count == 1 && s[0] == '0')
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 492) 		return 1;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 493) 	if (count == 1 && s[0] == '1')
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 494) 		return 2;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 495) 	if (count == 2 && s[0] == '-' && s[1] == '1')
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 496) 		return 3;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 497) 	return -EINVAL;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 498) }
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 499) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 500) /* generic stuff */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 501) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 502) static void entry_status(Node *e, char *page)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 503) {
6ceafb880c218 (Rasmus Villemoes              2015-04-16 12:44:56 -0700 504) 	char *dp = page;
6ceafb880c218 (Rasmus Villemoes              2015-04-16 12:44:56 -0700 505) 	const char *status = "disabled";
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 506) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 507) 	if (test_bit(Enabled, &e->flags))
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 508) 		status = "enabled";
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 509) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 510) 	if (!VERBOSE_STATUS) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 511) 		sprintf(page, "%s\n", status);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 512) 		return;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 513) 	}
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 514) 
6ceafb880c218 (Rasmus Villemoes              2015-04-16 12:44:56 -0700 515) 	dp += sprintf(dp, "%s\ninterpreter %s\n", status, e->interpreter);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 516) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 517) 	/* print the special flags */
6ceafb880c218 (Rasmus Villemoes              2015-04-16 12:44:56 -0700 518) 	dp += sprintf(dp, "flags: ");
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 519) 	if (e->flags & MISC_FMT_PRESERVE_ARGV0)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 520) 		*dp++ = 'P';
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 521) 	if (e->flags & MISC_FMT_OPEN_BINARY)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 522) 		*dp++ = 'O';
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 523) 	if (e->flags & MISC_FMT_CREDENTIALS)
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 524) 		*dp++ = 'C';
948b701a607f1 (James Bottomley               2016-02-17 16:51:16 -0800 525) 	if (e->flags & MISC_FMT_OPEN_FILE)
948b701a607f1 (James Bottomley               2016-02-17 16:51:16 -0800 526) 		*dp++ = 'F';
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 527) 	*dp++ = '\n';
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 528) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 529) 	if (!test_bit(Magic, &e->flags)) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 530) 		sprintf(dp, "extension .%s\n", e->magic);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 531) 	} else {
6ceafb880c218 (Rasmus Villemoes              2015-04-16 12:44:56 -0700 532) 		dp += sprintf(dp, "offset %i\nmagic ", e->offset);
6ceafb880c218 (Rasmus Villemoes              2015-04-16 12:44:56 -0700 533) 		dp = bin2hex(dp, e->magic, e->size);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 534) 		if (e->mask) {
6ceafb880c218 (Rasmus Villemoes              2015-04-16 12:44:56 -0700 535) 			dp += sprintf(dp, "\nmask ");
6ceafb880c218 (Rasmus Villemoes              2015-04-16 12:44:56 -0700 536) 			dp = bin2hex(dp, e->mask, e->size);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 537) 		}
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 538) 		*dp++ = '\n';
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 539) 		*dp = '\0';
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 540) 	}
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 541) }
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 542) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 543) static struct inode *bm_get_inode(struct super_block *sb, int mode)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 544) {
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 545) 	struct inode *inode = new_inode(sb);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 546) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 547) 	if (inode) {
85fe4025c616a (Christoph Hellwig             2010-10-23 11:19:54 -0400 548) 		inode->i_ino = get_next_ino();
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 549) 		inode->i_mode = mode;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 550) 		inode->i_atime = inode->i_mtime = inode->i_ctime =
c2050a454c7f1 (Deepa Dinamani                2016-09-14 07:48:06 -0700 551) 			current_time(inode);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 552) 	}
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 553) 	return inode;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 554) }
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 555) 
b57922d97fd6f (Al Viro                       2010-06-07 14:34:48 -0400 556) static void bm_evict_inode(struct inode *inode)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 557) {
83f918274e4b8 (Oleg Nesterov                 2017-10-03 16:15:48 -0700 558) 	Node *e = inode->i_private;
83f918274e4b8 (Oleg Nesterov                 2017-10-03 16:15:48 -0700 559) 
7e86600606cef (Eryu Guan                     2017-10-13 15:58:18 -0700 560) 	if (e && e->flags & MISC_FMT_OPEN_FILE)
83f918274e4b8 (Oleg Nesterov                 2017-10-03 16:15:48 -0700 561) 		filp_close(e->interp_file, NULL);
83f918274e4b8 (Oleg Nesterov                 2017-10-03 16:15:48 -0700 562) 
dbd5768f87ff6 (Jan Kara                      2012-05-03 14:48:02 +0200 563) 	clear_inode(inode);
83f918274e4b8 (Oleg Nesterov                 2017-10-03 16:15:48 -0700 564) 	kfree(e);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 565) }
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 566) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 567) static void kill_node(Node *e)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 568) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 569) 	struct dentry *dentry;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 570) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 571) 	write_lock(&entries_lock);
baba1b29731c7 (Oleg Nesterov                 2017-10-03 16:15:45 -0700 572) 	list_del_init(&e->list);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 573) 	write_unlock(&entries_lock);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 574) 
baba1b29731c7 (Oleg Nesterov                 2017-10-03 16:15:45 -0700 575) 	dentry = e->dentry;
baba1b29731c7 (Oleg Nesterov                 2017-10-03 16:15:45 -0700 576) 	drop_nlink(d_inode(dentry));
baba1b29731c7 (Oleg Nesterov                 2017-10-03 16:15:45 -0700 577) 	d_drop(dentry);
baba1b29731c7 (Oleg Nesterov                 2017-10-03 16:15:45 -0700 578) 	dput(dentry);
baba1b29731c7 (Oleg Nesterov                 2017-10-03 16:15:45 -0700 579) 	simple_release_fs(&bm_mnt, &entry_count);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 580) }
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 581) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 582) /* /<entry> */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 583) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 584) static ssize_t
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 585) bm_entry_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 586) {
496ad9aa8ef44 (Al Viro                       2013-01-23 17:07:38 -0500 587) 	Node *e = file_inode(file)->i_private;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 588) 	ssize_t res;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 589) 	char *page;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 590) 
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 591) 	page = (char *) __get_free_page(GFP_KERNEL);
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 592) 	if (!page)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 593) 		return -ENOMEM;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 594) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 595) 	entry_status(e, page);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 596) 
6e2c10a12a217 (Akinobu Mita                  2008-07-23 21:29:15 -0700 597) 	res = simple_read_from_buffer(buf, nbytes, ppos, page, strlen(page));
6e2c10a12a217 (Akinobu Mita                  2008-07-23 21:29:15 -0700 598) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 599) 	free_page((unsigned long) page);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 600) 	return res;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 601) }
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 602) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 603) static ssize_t bm_entry_write(struct file *file, const char __user *buffer,
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 604) 				size_t count, loff_t *ppos)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 605) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 606) 	struct dentry *root;
496ad9aa8ef44 (Al Viro                       2013-01-23 17:07:38 -0500 607) 	Node *e = file_inode(file)->i_private;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 608) 	int res = parse_command(buffer, count);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 609) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 610) 	switch (res) {
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 611) 	case 1:
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 612) 		/* Disable this handler. */
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 613) 		clear_bit(Enabled, &e->flags);
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 614) 		break;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 615) 	case 2:
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 616) 		/* Enable this handler. */
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 617) 		set_bit(Enabled, &e->flags);
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 618) 		break;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 619) 	case 3:
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 620) 		/* Delete this handler. */
ea7d4c046ba6e (Al Viro                       2016-05-29 19:14:03 -0400 621) 		root = file_inode(file)->i_sb->s_root;
5955102c9984f (Al Viro                       2016-01-22 15:40:57 -0500 622) 		inode_lock(d_inode(root));
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 623) 
baba1b29731c7 (Oleg Nesterov                 2017-10-03 16:15:45 -0700 624) 		if (!list_empty(&e->list))
baba1b29731c7 (Oleg Nesterov                 2017-10-03 16:15:45 -0700 625) 			kill_node(e);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 626) 
5955102c9984f (Al Viro                       2016-01-22 15:40:57 -0500 627) 		inode_unlock(d_inode(root));
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 628) 		break;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 629) 	default:
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 630) 		return res;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 631) 	}
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 632) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 633) 	return count;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 634) }
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 635) 
4b6f5d20b04dc (Arjan van de Ven              2006-03-28 01:56:42 -0800 636) static const struct file_operations bm_entry_operations = {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 637) 	.read		= bm_entry_read,
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 638) 	.write		= bm_entry_write,
6038f373a3dc1 (Arnd Bergmann                 2010-08-15 18:52:59 +0200 639) 	.llseek		= default_llseek,
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 640) };
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 641) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 642) /* /register */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 643) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 644) static ssize_t bm_register_write(struct file *file, const char __user *buffer,
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 645) 			       size_t count, loff_t *ppos)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 646) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 647) 	Node *e;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 648) 	struct inode *inode;
ea7d4c046ba6e (Al Viro                       2016-05-29 19:14:03 -0400 649) 	struct super_block *sb = file_inode(file)->i_sb;
ea7d4c046ba6e (Al Viro                       2016-05-29 19:14:03 -0400 650) 	struct dentry *root = sb->s_root, *dentry;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 651) 	int err = 0;
e7850f4d844e0 (Lior Ribak                    2021-03-12 21:07:41 -0800 652) 	struct file *f = NULL;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 653) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 654) 	e = create_entry(buffer, count);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 655) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 656) 	if (IS_ERR(e))
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 657) 		return PTR_ERR(e);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 658) 
e7850f4d844e0 (Lior Ribak                    2021-03-12 21:07:41 -0800 659) 	if (e->flags & MISC_FMT_OPEN_FILE) {
e7850f4d844e0 (Lior Ribak                    2021-03-12 21:07:41 -0800 660) 		f = open_exec(e->interpreter);
e7850f4d844e0 (Lior Ribak                    2021-03-12 21:07:41 -0800 661) 		if (IS_ERR(f)) {
e7850f4d844e0 (Lior Ribak                    2021-03-12 21:07:41 -0800 662) 			pr_notice("register: failed to install interpreter file %s\n",
e7850f4d844e0 (Lior Ribak                    2021-03-12 21:07:41 -0800 663) 				 e->interpreter);
e7850f4d844e0 (Lior Ribak                    2021-03-12 21:07:41 -0800 664) 			kfree(e);
e7850f4d844e0 (Lior Ribak                    2021-03-12 21:07:41 -0800 665) 			return PTR_ERR(f);
e7850f4d844e0 (Lior Ribak                    2021-03-12 21:07:41 -0800 666) 		}
e7850f4d844e0 (Lior Ribak                    2021-03-12 21:07:41 -0800 667) 		e->interp_file = f;
e7850f4d844e0 (Lior Ribak                    2021-03-12 21:07:41 -0800 668) 	}
e7850f4d844e0 (Lior Ribak                    2021-03-12 21:07:41 -0800 669) 
5955102c9984f (Al Viro                       2016-01-22 15:40:57 -0500 670) 	inode_lock(d_inode(root));
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 671) 	dentry = lookup_one_len(e->name, root, strlen(e->name));
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 672) 	err = PTR_ERR(dentry);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 673) 	if (IS_ERR(dentry))
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 674) 		goto out;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 675) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 676) 	err = -EEXIST;
75c3cfa855dce (David Howells                 2015-03-17 22:26:12 +0000 677) 	if (d_really_is_positive(dentry))
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 678) 		goto out2;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 679) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 680) 	inode = bm_get_inode(sb, S_IFREG | 0644);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 681) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 682) 	err = -ENOMEM;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 683) 	if (!inode)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 684) 		goto out2;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 685) 
1f5ce9e93aa96 (Trond Myklebust               2006-06-09 09:34:16 -0400 686) 	err = simple_pin_fs(&bm_fs_type, &bm_mnt, &entry_count);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 687) 	if (err) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 688) 		iput(inode);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 689) 		inode = NULL;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 690) 		goto out2;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 691) 	}
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 692) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 693) 	e->dentry = dget(dentry);
8e18e2941c534 (Theodore Ts'o                 2006-09-27 01:50:46 -0700 694) 	inode->i_private = e;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 695) 	inode->i_fop = &bm_entry_operations;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 696) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 697) 	d_instantiate(dentry, inode);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 698) 	write_lock(&entries_lock);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 699) 	list_add(&e->list, &entries);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 700) 	write_unlock(&entries_lock);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 701) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 702) 	err = 0;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 703) out2:
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 704) 	dput(dentry);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 705) out:
5955102c9984f (Al Viro                       2016-01-22 15:40:57 -0500 706) 	inode_unlock(d_inode(root));
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 707) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 708) 	if (err) {
e7850f4d844e0 (Lior Ribak                    2021-03-12 21:07:41 -0800 709) 		if (f)
e7850f4d844e0 (Lior Ribak                    2021-03-12 21:07:41 -0800 710) 			filp_close(f, NULL);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 711) 		kfree(e);
948b701a607f1 (James Bottomley               2016-02-17 16:51:16 -0800 712) 		return err;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 713) 	}
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 714) 	return count;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 715) }
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 716) 
4b6f5d20b04dc (Arjan van de Ven              2006-03-28 01:56:42 -0800 717) static const struct file_operations bm_register_operations = {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 718) 	.write		= bm_register_write,
6038f373a3dc1 (Arnd Bergmann                 2010-08-15 18:52:59 +0200 719) 	.llseek		= noop_llseek,
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 720) };
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 721) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 722) /* /status */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 723) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 724) static ssize_t
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 725) bm_status_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 726) {
87113e806a9ee (Qinghuang Feng                2009-01-06 14:41:38 -0800 727) 	char *s = enabled ? "enabled\n" : "disabled\n";
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 728) 
92f4c701aad79 (Akinobu Mita                  2007-05-09 02:33:32 -0700 729) 	return simple_read_from_buffer(buf, nbytes, ppos, s, strlen(s));
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 730) }
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 731) 
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 732) static ssize_t bm_status_write(struct file *file, const char __user *buffer,
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 733) 		size_t count, loff_t *ppos)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 734) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 735) 	int res = parse_command(buffer, count);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 736) 	struct dentry *root;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 737) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 738) 	switch (res) {
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 739) 	case 1:
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 740) 		/* Disable all handlers. */
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 741) 		enabled = 0;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 742) 		break;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 743) 	case 2:
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 744) 		/* Enable all handlers. */
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 745) 		enabled = 1;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 746) 		break;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 747) 	case 3:
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 748) 		/* Delete all handlers. */
ea7d4c046ba6e (Al Viro                       2016-05-29 19:14:03 -0400 749) 		root = file_inode(file)->i_sb->s_root;
5955102c9984f (Al Viro                       2016-01-22 15:40:57 -0500 750) 		inode_lock(d_inode(root));
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 751) 
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 752) 		while (!list_empty(&entries))
baba1b29731c7 (Oleg Nesterov                 2017-10-03 16:15:45 -0700 753) 			kill_node(list_first_entry(&entries, Node, list));
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 754) 
5955102c9984f (Al Viro                       2016-01-22 15:40:57 -0500 755) 		inode_unlock(d_inode(root));
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 756) 		break;
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 757) 	default:
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 758) 		return res;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 759) 	}
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 760) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 761) 	return count;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 762) }
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 763) 
4b6f5d20b04dc (Arjan van de Ven              2006-03-28 01:56:42 -0800 764) static const struct file_operations bm_status_operations = {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 765) 	.read		= bm_status_read,
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 766) 	.write		= bm_status_write,
6038f373a3dc1 (Arnd Bergmann                 2010-08-15 18:52:59 +0200 767) 	.llseek		= default_llseek,
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 768) };
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 769) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 770) /* Superblock handling */
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 771) 
ee9b6d61a2a43 (Josef 'Jeff' Sipek            2007-02-12 00:55:41 -0800 772) static const struct super_operations s_ops = {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 773) 	.statfs		= simple_statfs,
b57922d97fd6f (Al Viro                       2010-06-07 14:34:48 -0400 774) 	.evict_inode	= bm_evict_inode,
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 775) };
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 776) 
bc99a664e9be2 (David Howells                 2019-03-25 16:38:28 +0000 777) static int bm_fill_super(struct super_block *sb, struct fs_context *fc)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 778) {
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 779) 	int err;
cda37124f4e95 (Eric Biggers                  2017-03-25 21:15:37 -0700 780) 	static const struct tree_descr bm_files[] = {
1a1c9bb433af2 (Jeff Layton                   2007-05-08 00:32:31 -0700 781) 		[2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
1a1c9bb433af2 (Jeff Layton                   2007-05-08 00:32:31 -0700 782) 		[3] = {"register", &bm_register_operations, S_IWUSR},
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 783) 		/* last one */ {""}
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 784) 	};
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 785) 
e6084d4a086b6 (Mike Frysinger                2014-12-10 15:52:10 -0800 786) 	err = simple_fill_super(sb, BINFMTFS_MAGIC, bm_files);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 787) 	if (!err)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 788) 		sb->s_op = &s_ops;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 789) 	return err;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 790) }
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 791) 
bc99a664e9be2 (David Howells                 2019-03-25 16:38:28 +0000 792) static int bm_get_tree(struct fs_context *fc)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 793) {
bc99a664e9be2 (David Howells                 2019-03-25 16:38:28 +0000 794) 	return get_tree_single(fc, bm_fill_super);
bc99a664e9be2 (David Howells                 2019-03-25 16:38:28 +0000 795) }
bc99a664e9be2 (David Howells                 2019-03-25 16:38:28 +0000 796) 
bc99a664e9be2 (David Howells                 2019-03-25 16:38:28 +0000 797) static const struct fs_context_operations bm_context_ops = {
bc99a664e9be2 (David Howells                 2019-03-25 16:38:28 +0000 798) 	.get_tree	= bm_get_tree,
bc99a664e9be2 (David Howells                 2019-03-25 16:38:28 +0000 799) };
bc99a664e9be2 (David Howells                 2019-03-25 16:38:28 +0000 800) 
bc99a664e9be2 (David Howells                 2019-03-25 16:38:28 +0000 801) static int bm_init_fs_context(struct fs_context *fc)
bc99a664e9be2 (David Howells                 2019-03-25 16:38:28 +0000 802) {
bc99a664e9be2 (David Howells                 2019-03-25 16:38:28 +0000 803) 	fc->ops = &bm_context_ops;
bc99a664e9be2 (David Howells                 2019-03-25 16:38:28 +0000 804) 	return 0;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 805) }
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 806) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 807) static struct linux_binfmt misc_format = {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 808) 	.module = THIS_MODULE,
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 809) 	.load_binary = load_misc_binary,
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 810) };
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 811) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 812) static struct file_system_type bm_fs_type = {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 813) 	.owner		= THIS_MODULE,
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 814) 	.name		= "binfmt_misc",
bc99a664e9be2 (David Howells                 2019-03-25 16:38:28 +0000 815) 	.init_fs_context = bm_init_fs_context,
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 816) 	.kill_sb	= kill_litter_super,
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 817) };
7f78e03513940 (Eric W. Biederman             2013-03-02 19:39:14 -0800 818) MODULE_ALIAS_FS("binfmt_misc");
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 819) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 820) static int __init init_misc_binfmt(void)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 821) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 822) 	int err = register_filesystem(&bm_fs_type);
8fc3dc5a3a17a (Al Viro                       2012-03-17 03:05:16 -0400 823) 	if (!err)
8fc3dc5a3a17a (Al Viro                       2012-03-17 03:05:16 -0400 824) 		insert_binfmt(&misc_format);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 825) 	return err;
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 826) }
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 827) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 828) static void __exit exit_misc_binfmt(void)
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 829) {
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 830) 	unregister_binfmt(&misc_format);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 831) 	unregister_filesystem(&bm_fs_type);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 832) }
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 833) 
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 834) core_initcall(init_misc_binfmt);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 835) module_exit(exit_misc_binfmt);
^1da177e4c3f4 (Linus Torvalds                2005-04-16 15:20:36 -0700 836) MODULE_LICENSE("GPL");