aboutsummaryrefslogtreecommitdiffstats
diff options
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-12-11 18:15:35 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-12-11 18:15:35 +0100
commit22276c57445de5b29e143affdabe72576ab8dce3 (patch)
tree14754e08a6fafa472065b31afe5123c47281bb58
parent946cb48082b0bbff0bb96b3f816d0327bf409d79 (diff)
downloadpatches-22276c57445de5b29e143affdabe72576ab8dce3.tar.gz
usermode helper patches added
-rw-r--r--0001-kmod-make-usermodehelper-path-a-const-string.patch61
-rw-r--r--0002-drbd-rename-usermode_helper-to-drbd_usermode_helper.patch112
-rw-r--r--0003-Make-static-usermode-helper-binaries-constant.patch181
-rw-r--r--0004-Introduce-CONFIG_READONLY_USERMODEHELPER.patch396
-rw-r--r--c09.patch4
-rw-r--r--series4
6 files changed, 756 insertions, 2 deletions
diff --git a/0001-kmod-make-usermodehelper-path-a-const-string.patch b/0001-kmod-make-usermodehelper-path-a-const-string.patch
new file mode 100644
index 00000000000000..d7a9f87974dcf0
--- /dev/null
+++ b/0001-kmod-make-usermodehelper-path-a-const-string.patch
@@ -0,0 +1,61 @@
+From 359179eb6145c5982a958367197ca4b785b6b15f Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Sun, 11 Dec 2016 09:44:42 +0100
+Subject: [PATCH 1/4] kmod: make usermodehelper path a const string
+
+This is in preparation for making it so that usermode helper programs
+can't be changed, if desired, by userspace. We will tackle the mess of
+cleaning up the write-ability of argv and env later, that's going to
+take more work, for much less gain...
+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/kmod.h | 7 ++++---
+ kernel/kmod.c | 4 ++--
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+
+--- a/include/linux/kmod.h
++++ b/include/linux/kmod.h
+@@ -56,7 +56,7 @@ struct file;
+ struct subprocess_info {
+ struct work_struct work;
+ struct completion *complete;
+- char *path;
++ const char *path;
+ char **argv;
+ char **envp;
+ int wait;
+@@ -67,10 +67,11 @@ struct subprocess_info {
+ };
+
+ extern int
+-call_usermodehelper(char *path, char **argv, char **envp, int wait);
++call_usermodehelper(const char *path, char **argv, char **envp, int wait);
+
+ extern struct subprocess_info *
+-call_usermodehelper_setup(char *path, char **argv, char **envp, gfp_t gfp_mask,
++call_usermodehelper_setup(const char *path, char **argv, char **envp,
++ gfp_t gfp_mask,
+ int (*init)(struct subprocess_info *info, struct cred *new),
+ void (*cleanup)(struct subprocess_info *), void *data);
+
+--- a/kernel/kmod.c
++++ b/kernel/kmod.c
+@@ -516,7 +516,7 @@ static void helper_unlock(void)
+ * Function must be runnable in either a process context or the
+ * context in which call_usermodehelper_exec is called.
+ */
+-struct subprocess_info *call_usermodehelper_setup(char *path, char **argv,
++struct subprocess_info *call_usermodehelper_setup(const char *path, char **argv,
+ char **envp, gfp_t gfp_mask,
+ int (*init)(struct subprocess_info *info, struct cred *new),
+ void (*cleanup)(struct subprocess_info *info),
+@@ -613,7 +613,7 @@ EXPORT_SYMBOL(call_usermodehelper_exec);
+ * This function is the equivalent to use call_usermodehelper_setup() and
+ * call_usermodehelper_exec().
+ */
+-int call_usermodehelper(char *path, char **argv, char **envp, int wait)
++int call_usermodehelper(const char *path, char **argv, char **envp, int wait)
+ {
+ struct subprocess_info *info;
+ gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
diff --git a/0002-drbd-rename-usermode_helper-to-drbd_usermode_helper.patch b/0002-drbd-rename-usermode_helper-to-drbd_usermode_helper.patch
new file mode 100644
index 00000000000000..bf5e0a9db50a1d
--- /dev/null
+++ b/0002-drbd-rename-usermode_helper-to-drbd_usermode_helper.patch
@@ -0,0 +1,112 @@
+From 391148315fe8357ae67131c4fef5bb539852cfea Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Sun, 11 Dec 2016 10:39:09 +0100
+Subject: [PATCH 2/4] drbd: rename "usermode_helper" to "drbd_usermode_helper"
+
+Nothing like having a very generic global variable in a tiny driver
+subsystem to make a mess of the global namespace...
+
+Anyway, clean it up in anticipation of making drbd_usermode_helper
+read-only in a future patch.
+
+Note, there are many other "generic" named global variables in the drbd
+subsystem, someone should fix those up one day before they hit a linking
+error.
+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/block/drbd/drbd_int.h | 2 +-
+ drivers/block/drbd/drbd_main.c | 4 ++--
+ drivers/block/drbd/drbd_nl.c | 20 ++++++++++----------
+ 3 files changed, 13 insertions(+), 13 deletions(-)
+
+--- a/drivers/block/drbd/drbd_int.h
++++ b/drivers/block/drbd/drbd_int.h
+@@ -75,7 +75,7 @@ extern int fault_rate;
+ extern int fault_devs;
+ #endif
+
+-extern char usermode_helper[];
++extern char drbd_usermode_helper[];
+
+
+ /* This is used to stop/restart our threads.
+--- a/drivers/block/drbd/drbd_main.c
++++ b/drivers/block/drbd/drbd_main.c
+@@ -108,9 +108,9 @@ int proc_details; /* Detail level
+
+ /* Module parameter for setting the user mode helper program
+ * to run. Default is /sbin/drbdadm */
+-char usermode_helper[80] = "/sbin/drbdadm";
++char drbd_usermode_helper[80] = "/sbin/drbdadm";
+
+-module_param_string(usermode_helper, usermode_helper, sizeof(usermode_helper), 0644);
++module_param_string(usermode_helper, drbd_usermode_helper, sizeof(drbd_usermode_helper), 0644);
+
+ /* in 2.6.x, our device mapping and config info contains our virtual gendisks
+ * as member "struct gendisk *vdisk;"
+--- a/drivers/block/drbd/drbd_nl.c
++++ b/drivers/block/drbd/drbd_nl.c
+@@ -344,7 +344,7 @@ int drbd_khelper(struct drbd_device *dev
+ (char[60]) { }, /* address */
+ NULL };
+ char mb[14];
+- char *argv[] = {usermode_helper, cmd, mb, NULL };
++ char *argv[] = {drbd_usermode_helper, cmd, mb, NULL };
+ struct drbd_connection *connection = first_peer_device(device)->connection;
+ struct sib_info sib;
+ int ret;
+@@ -359,19 +359,19 @@ int drbd_khelper(struct drbd_device *dev
+ * write out any unsynced meta data changes now */
+ drbd_md_sync(device);
+
+- drbd_info(device, "helper command: %s %s %s\n", usermode_helper, cmd, mb);
++ drbd_info(device, "helper command: %s %s %s\n", drbd_usermode_helper, cmd, mb);
+ sib.sib_reason = SIB_HELPER_PRE;
+ sib.helper_name = cmd;
+ drbd_bcast_event(device, &sib);
+ notify_helper(NOTIFY_CALL, device, connection, cmd, 0);
+- ret = call_usermodehelper(usermode_helper, argv, envp, UMH_WAIT_PROC);
++ ret = call_usermodehelper(drbd_usermode_helper, argv, envp, UMH_WAIT_PROC);
+ if (ret)
+ drbd_warn(device, "helper command: %s %s %s exit code %u (0x%x)\n",
+- usermode_helper, cmd, mb,
++ drbd_usermode_helper, cmd, mb,
+ (ret >> 8) & 0xff, ret);
+ else
+ drbd_info(device, "helper command: %s %s %s exit code %u (0x%x)\n",
+- usermode_helper, cmd, mb,
++ drbd_usermode_helper, cmd, mb,
+ (ret >> 8) & 0xff, ret);
+ sib.sib_reason = SIB_HELPER_POST;
+ sib.helper_exit_code = ret;
+@@ -396,24 +396,24 @@ enum drbd_peer_state conn_khelper(struct
+ (char[60]) { }, /* address */
+ NULL };
+ char *resource_name = connection->resource->name;
+- char *argv[] = {usermode_helper, cmd, resource_name, NULL };
++ char *argv[] = {drbd_usermode_helper, cmd, resource_name, NULL };
+ int ret;
+
+ setup_khelper_env(connection, envp);
+ conn_md_sync(connection);
+
+- drbd_info(connection, "helper command: %s %s %s\n", usermode_helper, cmd, resource_name);
++ drbd_info(connection, "helper command: %s %s %s\n", drbd_usermode_helper, cmd, resource_name);
+ /* TODO: conn_bcast_event() ?? */
+ notify_helper(NOTIFY_CALL, NULL, connection, cmd, 0);
+
+- ret = call_usermodehelper(usermode_helper, argv, envp, UMH_WAIT_PROC);
++ ret = call_usermodehelper(drbd_usermode_helper, argv, envp, UMH_WAIT_PROC);
+ if (ret)
+ drbd_warn(connection, "helper command: %s %s %s exit code %u (0x%x)\n",
+- usermode_helper, cmd, resource_name,
++ drbd_usermode_helper, cmd, resource_name,
+ (ret >> 8) & 0xff, ret);
+ else
+ drbd_info(connection, "helper command: %s %s %s exit code %u (0x%x)\n",
+- usermode_helper, cmd, resource_name,
++ drbd_usermode_helper, cmd, resource_name,
+ (ret >> 8) & 0xff, ret);
+ /* TODO: conn_bcast_event() ?? */
+ notify_helper(NOTIFY_RESPONSE, NULL, connection, cmd, ret);
diff --git a/0003-Make-static-usermode-helper-binaries-constant.patch b/0003-Make-static-usermode-helper-binaries-constant.patch
new file mode 100644
index 00000000000000..53ad93571e77e5
--- /dev/null
+++ b/0003-Make-static-usermode-helper-binaries-constant.patch
@@ -0,0 +1,181 @@
+From b8cc8ef7094cbaf916b87573efa3c31727bd6b2d Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Sun, 11 Dec 2016 18:00:43 +0100
+Subject: [PATCH 3/4] Make static usermode helper binaries constant
+
+There are a number of usermode helper binaries that are "hard coded" in
+the kernel today, so mark them as "const" to make it harder for someone
+to change where the variables point to.
+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/macintosh/windfarm_core.c | 2 +-
+ drivers/net/hamradio/baycom_epp.c | 2 +-
+ drivers/pnp/pnpbios/core.c | 5 +++--
+ drivers/staging/greybus/svc_watchdog.c | 4 ++--
+ drivers/staging/rtl8192e/rtl8192e/rtl_dm.c | 6 +++---
+ fs/nfsd/nfs4layouts.c | 6 ++++--
+ security/keys/request_key.c | 7 ++++---
+ 7 files changed, 18 insertions(+), 14 deletions(-)
+
+--- a/drivers/macintosh/windfarm_core.c
++++ b/drivers/macintosh/windfarm_core.c
+@@ -74,7 +74,7 @@ static inline void wf_notify(int event,
+
+ static int wf_critical_overtemp(void)
+ {
+- static char * critical_overtemp_path = "/sbin/critical_overtemp";
++ static const char * critical_overtemp_path = "/sbin/critical_overtemp";
+ char *argv[] = { critical_overtemp_path, NULL };
+ static char *envp[] = { "HOME=/",
+ "TERM=linux",
+--- a/drivers/net/hamradio/baycom_epp.c
++++ b/drivers/net/hamradio/baycom_epp.c
+@@ -299,7 +299,7 @@ static inline void baycom_int_freq(struc
+ * eppconfig_path should be setable via /proc/sys.
+ */
+
+-static char eppconfig_path[256] = "/usr/sbin/eppfpga";
++static const char eppconfig_path[256] = "/usr/sbin/eppfpga";
+
+ static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL };
+
+--- a/drivers/pnp/pnpbios/core.c
++++ b/drivers/pnp/pnpbios/core.c
+@@ -98,6 +98,7 @@ static struct completion unload_sem;
+ */
+ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info)
+ {
++ static const char *sbin_pnpbios = "/sbin/pnpbios";
+ char *argv[3], **envp, *buf, *scratch;
+ int i = 0, value;
+
+@@ -112,7 +113,7 @@ static int pnp_dock_event(int dock, stru
+ * integrated into the driver core and use the usual infrastructure
+ * like sysfs and uevents
+ */
+- argv[0] = "/sbin/pnpbios";
++ argv[0] = sbin_pnpbios;
+ argv[1] = "dock";
+ argv[2] = NULL;
+
+@@ -139,7 +140,7 @@ static int pnp_dock_event(int dock, stru
+ info->location_id, info->serial, info->capabilities);
+ envp[i] = NULL;
+
+- value = call_usermodehelper(argv [0], argv, envp, UMH_WAIT_EXEC);
++ value = call_usermodehelper(sbin_pnpbios, argv, envp, UMH_WAIT_EXEC);
+ kfree(buf);
+ kfree(envp);
+ return 0;
+--- a/drivers/staging/greybus/svc_watchdog.c
++++ b/drivers/staging/greybus/svc_watchdog.c
+@@ -44,14 +44,14 @@ static int svc_watchdog_pm_notifier(stru
+
+ static void greybus_reset(struct work_struct *work)
+ {
+- static char start_path[256] = "/system/bin/start";
++ static const char start_path[256] = "/system/bin/start";
+ static char *envp[] = {
+ "HOME=/",
+ "PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin",
+ NULL,
+ };
+ static char *argv[] = {
+- start_path,
++ (char *)start_path,
+ "unipro_reset",
+ NULL,
+ };
+--- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
++++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
+@@ -268,7 +268,7 @@ void rtl92e_dm_watchdog(struct net_devic
+ static void _rtl92e_dm_check_ac_dc_power(struct net_device *dev)
+ {
+ struct r8192_priv *priv = rtllib_priv(dev);
+- static char *ac_dc_script = "/etc/acpi/wireless-rtl-ac-dc-power.sh";
++ static const char *ac_dc_script = "/etc/acpi/wireless-rtl-ac-dc-power.sh";
+ char *argv[] = {ac_dc_script, DRV_NAME, NULL};
+ static char *envp[] = {"HOME=/",
+ "TERM=linux",
+@@ -1823,7 +1823,7 @@ static void _rtl92e_dm_check_rf_ctrl_gpi
+ enum rt_rf_power_state eRfPowerStateToSet;
+ bool bActuallySet = false;
+ char *argv[3];
+- static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh";
++ static const char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh";
+ static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin",
+ NULL};
+
+@@ -1862,7 +1862,7 @@ static void _rtl92e_dm_check_rf_ctrl_gpi
+ else
+ argv[1] = "RFON";
+
+- argv[0] = RadioPowerPath;
++ argv[0] = (char *)RadioPowerPath;
+ argv[2] = NULL;
+ call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC);
+ }
+--- a/fs/nfsd/nfs4layouts.c
++++ b/fs/nfsd/nfs4layouts.c
+@@ -613,6 +613,7 @@ nfsd4_cb_layout_fail(struct nfs4_layout_
+ {
+ struct nfs4_client *clp = ls->ls_stid.sc_client;
+ char addr_str[INET6_ADDRSTRLEN];
++ static const char *nfsd_recall_failed = "/sbin/nfsd-recall-failed";
+ static char *envp[] = {
+ "HOME=/",
+ "TERM=linux",
+@@ -628,12 +629,13 @@ nfsd4_cb_layout_fail(struct nfs4_layout_
+ "nfsd: client %s failed to respond to layout recall. "
+ " Fencing..\n", addr_str);
+
+- argv[0] = "/sbin/nfsd-recall-failed";
++ argv[0] = (char *)nfsd_recall_failed;
+ argv[1] = addr_str;
+ argv[2] = ls->ls_file->f_path.mnt->mnt_sb->s_id;
+ argv[3] = NULL;
+
+- error = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
++ error = call_usermodehelper(nfsd_recall_failed, argv, envp,
++ UMH_WAIT_PROC);
+ if (error) {
+ printk(KERN_ERR "nfsd: fence failed for client %s: %d!\n",
+ addr_str, error);
+--- a/security/keys/request_key.c
++++ b/security/keys/request_key.c
+@@ -72,7 +72,7 @@ static void umh_keys_cleanup(struct subp
+ /*
+ * Call a usermode helper with a specific session keyring.
+ */
+-static int call_usermodehelper_keys(char *path, char **argv, char **envp,
++static int call_usermodehelper_keys(const char *path, char **argv, char **envp,
+ struct key *session_keyring, int wait)
+ {
+ struct subprocess_info *info;
+@@ -95,6 +95,7 @@ static int call_sbin_request_key(struct
+ const char *op,
+ void *aux)
+ {
++ static const char *request_key = "/sbin/request-key";
+ const struct cred *cred = current_cred();
+ key_serial_t prkey, sskey;
+ struct key *key = cons->key, *authkey = cons->authkey, *keyring,
+@@ -161,7 +162,7 @@ static int call_sbin_request_key(struct
+
+ /* set up the argument list */
+ i = 0;
+- argv[i++] = "/sbin/request-key";
++ argv[i++] = (char *)request_key;
+ argv[i++] = (char *) op;
+ argv[i++] = key_str;
+ argv[i++] = uid_str;
+@@ -172,7 +173,7 @@ static int call_sbin_request_key(struct
+ argv[i] = NULL;
+
+ /* do it */
+- ret = call_usermodehelper_keys(argv[0], argv, envp, keyring,
++ ret = call_usermodehelper_keys(request_key, argv, envp, keyring,
+ UMH_WAIT_PROC);
+ kdebug("usermode -> 0x%x", ret);
+ if (ret >= 0) {
diff --git a/0004-Introduce-CONFIG_READONLY_USERMODEHELPER.patch b/0004-Introduce-CONFIG_READONLY_USERMODEHELPER.patch
new file mode 100644
index 00000000000000..883487076ab0fd
--- /dev/null
+++ b/0004-Introduce-CONFIG_READONLY_USERMODEHELPER.patch
@@ -0,0 +1,396 @@
+From 7c7aad8525b5ba93a45853992e199045392fa755 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Sun, 11 Dec 2016 18:06:14 +0100
+Subject: [PATCH 4/4] Introduce CONFIG_READONLY_USERMODEHELPER
+
+If you can write to kernel memory, an "easy" way to get the kernel to
+run any application is to change the pointer of one of the usermode
+helper program names. To try to mitigate this, create a new config
+option, CONFIG_READONLY_USERMODEHELPER.
+
+This option only allows "predefined" binaries to be called. A number of
+drivers and subsystems allow for the name of the binary to be changed,
+and this config option disables that capability, so be aware of that.
+
+Note: Still a proof-of-concept at this point in time, doesn't cover all
+of the call_usermodehelper() calls just yet, including the "fun" of
+coredumps, it's still a work in progress.
+
+Not-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kernel/cpu/mcheck/mce.c | 12 +++++++---
+ drivers/block/drbd/drbd_int.h | 6 ++++-
+ drivers/block/drbd/drbd_main.c | 5 ++++
+ drivers/staging/lustre/include/linux/libcfs/libcfs.h | 2 +
+ drivers/staging/lustre/lnet/libcfs/linux/linux-debug.c | 11 ++++++++-
+ drivers/staging/lustre/lnet/libcfs/module.c | 2 +
+ drivers/video/fbdev/uvesafb.c | 19 ++++++++++++-----
+ fs/nfs/cache_lib.c | 12 ++++++++--
+ include/linux/reboot.h | 2 +
+ kernel/ksysfs.c | 6 ++++-
+ kernel/reboot.c | 3 ++
+ kernel/sysctl.c | 4 +++
+ lib/kobject_uevent.c | 3 ++
+ security/Kconfig | 17 +++++++++++++++
+ 14 files changed, 89 insertions(+), 15 deletions(-)
+
+--- a/arch/x86/kernel/cpu/mcheck/mce.c
++++ b/arch/x86/kernel/cpu/mcheck/mce.c
+@@ -2283,15 +2283,16 @@ static ssize_t set_bank(struct device *s
+ }
+
+ static ssize_t
+-show_trigger(struct device *s, struct device_attribute *attr, char *buf)
++trigger_show(struct device *s, struct device_attribute *attr, char *buf)
+ {
+ strcpy(buf, mce_helper);
+ strcat(buf, "\n");
+ return strlen(mce_helper) + 1;
+ }
+
+-static ssize_t set_trigger(struct device *s, struct device_attribute *attr,
+- const char *buf, size_t siz)
++#ifndef CONFIG_READONLY_USERMODEHELPER
++static ssize_t trigger_store(struct device *s, struct device_attribute *attr,
++ const char *buf, size_t siz)
+ {
+ char *p;
+
+@@ -2304,6 +2305,10 @@ static ssize_t set_trigger(struct device
+
+ return strlen(mce_helper) + !!p;
+ }
++static DEVICE_ATTR_RW(trigger);
++#else
++static DEVICE_ATTR_RO(trigger);
++#endif
+
+ static ssize_t set_ignore_ce(struct device *s,
+ struct device_attribute *attr,
+@@ -2361,7 +2366,6 @@ static ssize_t store_int_with_restart(st
+ return ret;
+ }
+
+-static DEVICE_ATTR(trigger, 0644, show_trigger, set_trigger);
+ static DEVICE_INT_ATTR(tolerant, 0644, mca_cfg.tolerant);
+ static DEVICE_INT_ATTR(monarch_timeout, 0644, mca_cfg.monarch_timeout);
+ static DEVICE_BOOL_ATTR(dont_log_ce, 0644, mca_cfg.dont_log_ce);
+--- a/drivers/block/drbd/drbd_int.h
++++ b/drivers/block/drbd/drbd_int.h
+@@ -75,7 +75,11 @@ extern int fault_rate;
+ extern int fault_devs;
+ #endif
+
+-extern char drbd_usermode_helper[];
++extern
++#ifdef CONFIG_READONLY_USERMODEHELPER
++ const
++#endif
++ char drbd_usermode_helper[];
+
+
+ /* This is used to stop/restart our threads.
+--- a/drivers/block/drbd/drbd_main.c
++++ b/drivers/block/drbd/drbd_main.c
+@@ -108,9 +108,14 @@ int proc_details; /* Detail level
+
+ /* Module parameter for setting the user mode helper program
+ * to run. Default is /sbin/drbdadm */
++#ifdef CONFIG_READONLY_USERMODEHELPER
++const
++#endif
+ char drbd_usermode_helper[80] = "/sbin/drbdadm";
+
++#ifndef CONFIG_READONLY_USERMODEHELPER
+ module_param_string(usermode_helper, drbd_usermode_helper, sizeof(drbd_usermode_helper), 0644);
++#endif
+
+ /* in 2.6.x, our device mapping and config info contains our virtual gendisks
+ * as member "struct gendisk *vdisk;"
+--- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h
++++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h
+@@ -125,8 +125,10 @@ extern struct miscdevice libcfs_dev;
+ /**
+ * The path of debug log dump upcall script.
+ */
++#ifndef CONFIG_READONLY_USERMODEHELPER
+ extern char lnet_upcall[1024];
+ extern char lnet_debug_log_upcall[1024];
++#endif
+
+ extern struct cfs_wi_sched *cfs_sched_rehash;
+
+--- a/drivers/staging/lustre/lnet/libcfs/linux/linux-debug.c
++++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-debug.c
+@@ -57,7 +57,14 @@
+
+ #include <linux/kallsyms.h>
+
++#ifdef CONFIG_READONLY_USERMODEHELPER
++static const
+ char lnet_upcall[1024] = "/usr/lib/lustre/lnet_upcall";
++#endif
++
++#ifdef CONFIG_READONLY_USERMODEHELPER
++static const
++#endif
+ char lnet_debug_log_upcall[1024] = "/usr/lib/lustre/lnet_debug_log_upcall";
+
+ /**
+@@ -74,7 +81,7 @@ void libcfs_run_debug_log_upcall(char *f
+ "PATH=/sbin:/bin:/usr/sbin:/usr/bin",
+ NULL};
+
+- argv[0] = lnet_debug_log_upcall;
++ argv[0] = (char *)lnet_debug_log_upcall;
+
+ LASSERTF(file, "called on a null filename\n");
+ argv[1] = file; /* only need to pass the path of the file */
+@@ -100,7 +107,7 @@ void libcfs_run_upcall(char **argv)
+ "PATH=/sbin:/bin:/usr/sbin:/usr/bin",
+ NULL};
+
+- argv[0] = lnet_upcall;
++ argv[0] = (char *)lnet_upcall;
+ argc = 1;
+ while (argv[argc])
+ argc++;
+--- a/drivers/staging/lustre/lnet/libcfs/module.c
++++ b/drivers/staging/lustre/lnet/libcfs/module.c
+@@ -366,6 +366,7 @@ static struct ctl_table lnet_table[] = {
+ .proc_handler = &proc_cpt_table,
+ },
+
++#ifndef CONFIG_READONLY_USERMODEHELPER
+ {
+ .procname = "upcall",
+ .data = lnet_upcall,
+@@ -380,6 +381,7 @@ static struct ctl_table lnet_table[] = {
+ .mode = 0644,
+ .proc_handler = &proc_dostring,
+ },
++#endif
+ {
+ .procname = "catastrophe",
+ .data = &libcfs_catastrophe,
+--- a/drivers/video/fbdev/uvesafb.c
++++ b/drivers/video/fbdev/uvesafb.c
+@@ -30,7 +30,11 @@ static struct cb_id uvesafb_cn_id = {
+ .idx = CN_IDX_V86D,
+ .val = CN_VAL_V86D_UVESAFB
+ };
++#ifdef CONFIG_READONLY_USERMODEHELPER
++static const char v86d_path[PATH_MAX] = "/sbin/v86d";
++#else
+ static char v86d_path[PATH_MAX] = "/sbin/v86d";
++#endif
+ static char v86d_started; /* has v86d been started by uvesafb? */
+
+ static const struct fb_fix_screeninfo uvesafb_fix = {
+@@ -114,7 +118,7 @@ static int uvesafb_helper_start(void)
+ };
+
+ char *argv[] = {
+- v86d_path,
++ (char *)v86d_path,
+ NULL,
+ };
+
+@@ -1883,19 +1887,22 @@ static int uvesafb_setup(char *options)
+ }
+ #endif /* !MODULE */
+
+-static ssize_t show_v86d(struct device_driver *dev, char *buf)
++static ssize_t v86d_show(struct device_driver *dev, char *buf)
+ {
+ return snprintf(buf, PAGE_SIZE, "%s\n", v86d_path);
+ }
+
+-static ssize_t store_v86d(struct device_driver *dev, const char *buf,
++#ifndef CONFIG_READONLY_USERMODEHELPER
++static ssize_t v86d_store(struct device_driver *dev, const char *buf,
+ size_t count)
+ {
+ strncpy(v86d_path, buf, PATH_MAX);
+ return count;
+ }
+-
+-static DRIVER_ATTR(v86d, S_IRUGO | S_IWUSR, show_v86d, store_v86d);
++static DRIVER_ATTR_RW(v86d);
++#else
++static DRIVER_ATTR_RO(v86d);
++#endif
+
+ static int uvesafb_init(void)
+ {
+@@ -2017,8 +2024,10 @@ MODULE_PARM_DESC(mode_option,
+ module_param(vbemode, ushort, 0);
+ MODULE_PARM_DESC(vbemode,
+ "VBE mode number to set, overrides the 'mode' option");
++#ifndef CONFIG_READONLY_USERMODEHELPER
+ module_param_string(v86d, v86d_path, PATH_MAX, 0660);
+ MODULE_PARM_DESC(v86d, "Path to the v86d userspace helper.");
++#endif
+
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Michal Januszewski <spock@gentoo.org>");
+--- a/fs/nfs/cache_lib.c
++++ b/fs/nfs/cache_lib.c
+@@ -20,13 +20,20 @@
+ #define NFS_CACHE_UPCALL_PATHLEN 256
+ #define NFS_CACHE_UPCALL_TIMEOUT 15
+
++#ifdef CONFIG_READONLY_USERMODEHELPER
++static const char nfs_cache_getent_prog[NFS_CACHE_UPCALL_PATHLEN] =
++#else
+ static char nfs_cache_getent_prog[NFS_CACHE_UPCALL_PATHLEN] =
++#endif
+ "/sbin/nfs_cache_getent";
+ static unsigned long nfs_cache_getent_timeout = NFS_CACHE_UPCALL_TIMEOUT;
+
++#ifndef CONFIG_READONLY_USERMODEHELPER
+ module_param_string(cache_getent, nfs_cache_getent_prog,
+ sizeof(nfs_cache_getent_prog), 0600);
+ MODULE_PARM_DESC(cache_getent, "Path to the client cache upcall program");
++#endif
++
+ module_param_named(cache_getent_timeout, nfs_cache_getent_timeout, ulong, 0600);
+ MODULE_PARM_DESC(cache_getent_timeout, "Timeout (in seconds) after which "
+ "the cache upcall is assumed to have failed");
+@@ -39,7 +46,7 @@ int nfs_cache_upcall(struct cache_detail
+ NULL
+ };
+ char *argv[] = {
+- nfs_cache_getent_prog,
++ (char *)nfs_cache_getent_prog,
+ cd->name,
+ entry_name,
+ NULL
+@@ -48,7 +55,8 @@ int nfs_cache_upcall(struct cache_detail
+
+ if (nfs_cache_getent_prog[0] == '\0')
+ goto out;
+- ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
++ ret = call_usermodehelper(nfs_cache_getent_prog, argv, envp,
++ UMH_WAIT_EXEC);
+ /*
+ * Disable the upcall mechanism if we're getting an ENOENT or
+ * EACCES error. The admin can re-enable it on the fly by using
+--- a/include/linux/reboot.h
++++ b/include/linux/reboot.h
+@@ -68,7 +68,9 @@ extern int C_A_D; /* for sysctl */
+ void ctrl_alt_del(void);
+
+ #define POWEROFF_CMD_PATH_LEN 256
++#ifndef CONFIG_READONLY_USERMODEHELPER
+ extern char poweroff_cmd[POWEROFF_CMD_PATH_LEN];
++#endif
+
+ extern void orderly_poweroff(bool force);
+ extern void orderly_reboot(void);
+--- a/kernel/ksysfs.c
++++ b/kernel/ksysfs.c
+@@ -44,6 +44,7 @@ static ssize_t uevent_helper_show(struct
+ {
+ return sprintf(buf, "%s\n", uevent_helper);
+ }
++#ifndef CONFIG_READONLY_USERMODEHELPER
+ static ssize_t uevent_helper_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+@@ -57,7 +58,10 @@ static ssize_t uevent_helper_store(struc
+ return count;
+ }
+ KERNEL_ATTR_RW(uevent_helper);
+-#endif
++#else
++KERNEL_ATTR_RO(uevent_helper);
++#endif /* CONFIG_READONLY_USERMODEHELPER */
++#endif /* CONFIG_UEVENT_HELPER */
+
+ #ifdef CONFIG_PROFILING
+ static ssize_t profiling_show(struct kobject *kobj,
+--- a/kernel/reboot.c
++++ b/kernel/reboot.c
+@@ -386,6 +386,9 @@ void ctrl_alt_del(void)
+ kill_cad_pid(SIGINT, 1);
+ }
+
++#ifdef CONFIG_READONLY_USERMODEHELPER
++static const
++#endif
+ char poweroff_cmd[POWEROFF_CMD_PATH_LEN] = "/sbin/poweroff";
+ static const char reboot_cmd[] = "/sbin/reboot";
+
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -669,6 +669,7 @@ static struct ctl_table kern_table[] = {
+ },
+ #endif
+ #ifdef CONFIG_UEVENT_HELPER
++#ifndef CONFIG_READONLY_USERMODEHELPER
+ {
+ .procname = "hotplug",
+ .data = &uevent_helper,
+@@ -677,6 +678,7 @@ static struct ctl_table kern_table[] = {
+ .proc_handler = proc_dostring,
+ },
+ #endif
++#endif
+ #ifdef CONFIG_CHR_DEV_SG
+ {
+ .procname = "sg-big-buff",
+@@ -1093,6 +1095,7 @@ static struct ctl_table kern_table[] = {
+ .proc_handler = proc_dointvec,
+ },
+ #endif
++#ifndef CONFIG_READONLY_USERMODEHELPER
+ {
+ .procname = "poweroff_cmd",
+ .data = &poweroff_cmd,
+@@ -1100,6 +1103,7 @@ static struct ctl_table kern_table[] = {
+ .mode = 0644,
+ .proc_handler = proc_dostring,
+ },
++#endif
+ #ifdef CONFIG_KEYS
+ {
+ .procname = "keys",
+--- a/lib/kobject_uevent.c
++++ b/lib/kobject_uevent.c
+@@ -29,6 +29,9 @@
+
+ u64 uevent_seqnum;
+ #ifdef CONFIG_UEVENT_HELPER
++#ifdef CONFIG_READONLY_USERMODEHELPER
++const
++#endif
+ char uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH;
+ #endif
+ #ifdef CONFIG_NET
+--- a/security/Kconfig
++++ b/security/Kconfig
+@@ -158,6 +158,23 @@ config HARDENED_USERCOPY_PAGESPAN
+ been removed. This config is intended to be used only while
+ trying to find such users.
+
++config READONLY_USERMODEHELPER
++ bool "Make User Mode Helper program names read-only"
++ default N
++ help
++ Some user mode helper program names can be changed at runtime
++ by userspace programs. Prevent this from happening by "hard
++ coding" all user mode helper program names at kernel build
++ time, moving the names into read-only memory, making it harder
++ for any arbritrary program to be run as root if something were
++ to go wrong.
++
++ Note, some subsystems and drivers allow their user mode helper
++ binary to be changed with a module parameter, sysctl, sysfs
++ file, or some combination of these. Enabling this option
++ prevents the binary name to be changed, which might not be
++ good for some systems.
++
+ source security/selinux/Kconfig
+ source security/smack/Kconfig
+ source security/tomoyo/Kconfig
diff --git a/c09.patch b/c09.patch
index d6cca560e1da40..bf2461b55dd8f1 100644
--- a/c09.patch
+++ b/c09.patch
@@ -36,7 +36,7 @@
return -EINVAL;
}
-+static CLASS_ATTRIBUTE_WO(add);
++static CLASS_ATTR_WO(add);
-static ssize_t class_pktcdvd_store_remove(struct class *c,
- struct class_attribute *attr,
@@ -51,7 +51,7 @@
}
return -EINVAL;
}
-+static CLASS_ATTRIBUTE_WO(remove);
++static CLASS_ATTR_WO(remove);
-static struct class_attribute class_pktcdvd_attrs[] = {
- __ATTR(add, 0200, NULL, class_pktcdvd_store_add),
diff --git a/series b/series
index a0714106ccb313..661e3b0fa70591 100644
--- a/series
+++ b/series
@@ -1,3 +1,7 @@
+0001-kmod-make-usermodehelper-path-a-const-string.patch
+0002-drbd-rename-usermode_helper-to-drbd_usermode_helper.patch
+0003-Make-static-usermode-helper-binaries-constant.patch
+0004-Introduce-CONFIG_READONLY_USERMODEHELPER.patch
usb-core-add-missing-license-information.patch
## broken patch!