^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);