Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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