From f4cdf7ca9a1fdcca413157df19753f388a5a224e Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 19 Aug 2026 10:09:22 -0700 Subject: Merge tag 'media/v7.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media Pull media updates from Mauro Carvalho Chehab: - v4l2-core: added ISP statistics support and per-block validation - v4l2-core: Allow unknown HDR10 white point and luminance - New camera sensors: Sony IMX678 and IMX471m, Himax HM1092 IR sensor - New codec: Milos: VPU v2.0 codec support - isp driver: gained support for Dreamchip RPPX1 ISP framework - vsp1 driver: gained support for RZ/T2H and RZ/N2H - Novalake driver: gained CVS support for new NVL hardware - dvb-core: fix feed leak on failed DMX_ADD_PID - several driver fixes, cleanups and minor improvements * tag 'media/v7.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (308 commits) media: ipu-bridge: check all DMI entries when overriding sensor rotation media: v4l2-async: avoid deleting unlinked ASC entry on link error media: rzg2l-cru: Align bytesperline to hardware DMA stride requirement media: intel/ipu6: fix async notifier cleanup leak on parse error media: staging/ipu7: fix async notifier UAF on probe error path media: amd: isp4: fix self-deadlock in isp4sd_pwron_and_init() error path media: amd: isp4: release partial allocations in isp4if_alloc_fw_gpumem() media: rcar-isp: Fix VSPX reference leaks media: rcar-isp: Release ISPCORE resources media: i2c: imx415: Release runtime PM reference on VBLANK error media: i2c: imx415: Return test pattern write errors media: renesas: vsp1: Declare index variables in for loop statement media: renesas: vsp1: Make reset control optional to support platforms without a reset line media: dt-bindings: media: renesas,vsp1: Document RZ/T2H and RZ/N2H SoCs media: dt-bindings: media: renesas,fcp: Document RZ/T2H and RZ/N2H SoCs media: nxp: imx8-isi: Add additional 32-bit RGB format support media: nxp: imx8-isi: Add 16-bit raw Bayer format support media: nxp: imx8-isi: Implement per-stream reference counting for multiplexed streams media: nxp: imx8-isi: Use BIT_ULL() for 64-bit stream masks media: nxp: imx8-isi: Correct color map between V4L2 and ISI ... --- fs/binfmt_script.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 fs/binfmt_script.c (limited to 'fs/binfmt_script.c') diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c new file mode 100644 index 000000000..637daf6e4 --- /dev/null +++ b/fs/binfmt_script.c @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * linux/fs/binfmt_script.c + * + * Copyright (C) 1996 Martin von Löwis + * original #!-checking implemented by tytso. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static inline bool spacetab(char c) { return c == ' ' || c == '\t'; } +static inline const char *next_non_spacetab(const char *first, const char *last) +{ + for (; first <= last; first++) + if (!spacetab(*first)) + return first; + return NULL; +} +static inline const char *next_terminator(const char *first, const char *last) +{ + for (; first <= last; first++) + if (spacetab(*first) || !*first) + return first; + return NULL; +} + +static int load_script(struct linux_binprm *bprm) +{ + const char *i_name, *i_sep, *i_arg, *i_end, *buf_end; + struct file *file; + int retval; + + /* Not ours to exec if we don't start with "#!". */ + if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!')) + return -ENOEXEC; + + /* + * This section handles parsing the #! line into separate + * interpreter path and argument strings. We must be careful + * because bprm->buf is not yet guaranteed to be NUL-terminated + * (though the buffer will have trailing NUL padding when the + * file size was smaller than the buffer size). + * + * We do not want to exec a truncated interpreter path, so either + * we find a newline (which indicates nothing is truncated), or + * we find a space/tab/NUL after the interpreter path (which + * itself may be preceded by spaces/tabs). Truncating the + * arguments is fine: the interpreter can re-read the script to + * parse them on its own. + */ + buf_end = bprm->buf + sizeof(bprm->buf) - 1; + i_end = strnchr(bprm->buf, sizeof(bprm->buf), '\n'); + if (!i_end) { + i_end = next_non_spacetab(bprm->buf + 2, buf_end); + if (!i_end) + return -ENOEXEC; /* Entire buf is spaces/tabs */ + /* + * If there is no later space/tab/NUL we must assume the + * interpreter path is truncated. + */ + if (!next_terminator(i_end, buf_end)) + return -ENOEXEC; + i_end = buf_end; + } + /* Trim any trailing spaces/tabs from i_end */ + while (spacetab(i_end[-1])) + i_end--; + + /* Skip over leading spaces/tabs */ + i_name = next_non_spacetab(bprm->buf+2, i_end); + if (!i_name || (i_name == i_end)) + return -ENOEXEC; /* No interpreter name found */ + + /* Is there an optional argument? */ + i_arg = NULL; + i_sep = next_terminator(i_name, i_end); + if (i_sep && (*i_sep != '\0')) + i_arg = next_non_spacetab(i_sep, i_end); + + /* + * If the script filename will be inaccessible after exec, typically + * because it is a "/dev/fd//.." path against an O_CLOEXEC fd, give + * up now (on the assumption that the interpreter will want to load + * this file). + */ + if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE) + return -ENOENT; + + /* + * OK, we've parsed out the interpreter name and + * (optional) argument. + * Splice in (1) the interpreter's name for argv[0] + * (2) (optional) argument to interpreter + * (3) filename of shell script (replace argv[0]) + * + * This is done in reverse order, because of how the + * user environment and arguments are stored. + */ + retval = remove_arg_zero(bprm); + if (retval) + return retval; + retval = copy_string_kernel(bprm->interp, bprm); + if (retval < 0) + return retval; + bprm->argc++; + *((char *)i_end) = '\0'; + if (i_arg) { + *((char *)i_sep) = '\0'; + retval = copy_string_kernel(i_arg, bprm); + if (retval < 0) + return retval; + bprm->argc++; + } + retval = copy_string_kernel(i_name, bprm); + if (retval) + return retval; + bprm->argc++; + retval = bprm_change_interp(i_name, bprm); + if (retval < 0) + return retval; + + /* + * OK, now restart the process with the interpreter's dentry. + */ + file = open_exec(i_name); + if (IS_ERR(file)) + return PTR_ERR(file); + + bprm->interpreter = file; + return 0; +} + +static struct linux_binfmt script_format = { + .module = THIS_MODULE, + .load_binary = load_script, +}; + +static int __init init_script_binfmt(void) +{ + register_binfmt(&script_format); + return 0; +} + +static void __exit exit_script_binfmt(void) +{ + unregister_binfmt(&script_format); +} + +core_initcall(init_script_binfmt); +module_exit(exit_script_binfmt); +MODULE_DESCRIPTION("Kernel support for scripts starting with #!"); +MODULE_LICENSE("GPL"); -- cgit v1.3.1