Skip to content

Commit

Permalink
Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/li…
Browse files Browse the repository at this point in the history
…nux/kernel/git/rusty/linux

Pull module update from Rusty Russell:
 "Nothing major: support for compressing modules, and auto-tainting
  params.

  PS. My virtio-next tree is empty: DaveM took the patches I had.  There
      might be a virtio-rng starvation fix, but so far it's a bit voodoo
      so I will get to that in the next two days or it will wait"

* tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux:
  moduleparam: Resolve missing-field-initializer warning
  kbuild: handle module compression while running 'make modules_install'.
  modinst: wrap long lines in order to enhance cmd_modules_install
  modsign: lookup lines ending in .ko in .mod files
  modpost: simplify file name generation of *.mod.c files
  modpost: reduce visibility of symbols and constify r/o arrays
  param: check for tainting before calling set op.
  drm/i915: taint the kernel if unsafe module parameters are set
  module: add module_param_unsafe and module_param_named_unsafe
  module: make it possible to have unsafe, tainting module params
  module: rename KERNEL_PARAM_FL_NOARG to avoid confusion
  • Loading branch information
torvalds committed Oct 8, 2014
2 parents a40a720 + 184c3fc commit bdf428f
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 36 deletions.
15 changes: 15 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,21 @@ mod_strip_cmd = true
endif # INSTALL_MOD_STRIP
export mod_strip_cmd

# CONFIG_MODULE_COMPRESS, if defined, will cause module to be compressed
# after they are installed in agreement with CONFIG_MODULE_COMPRESS_GZIP
# or CONFIG_MODULE_COMPRESS_XZ.

mod_compress_cmd = true
ifdef CONFIG_MODULE_COMPRESS
ifdef CONFIG_MODULE_COMPRESS_GZIP
mod_compress_cmd = gzip -n
endif # CONFIG_MODULE_COMPRESS_GZIP
ifdef CONFIG_MODULE_COMPRESS_XZ
mod_compress_cmd = xz
endif # CONFIG_MODULE_COMPRESS_XZ
endif # CONFIG_MODULE_COMPRESS
export mod_compress_cmd

# Select initial ramdisk compression format, default is gzip(1).
# This shall be used by the dracut(8) tool while creating an initramfs image.
#
Expand Down
8 changes: 4 additions & 4 deletions drivers/gpu/drm/i915/i915_params.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,20 @@ module_param_named(powersave, i915.powersave, int, 0600);
MODULE_PARM_DESC(powersave,
"Enable powersavings, fbc, downclocking, etc. (default: true)");

module_param_named(semaphores, i915.semaphores, int, 0400);
module_param_named_unsafe(semaphores, i915.semaphores, int, 0400);
MODULE_PARM_DESC(semaphores,
"Use semaphores for inter-ring sync "
"(default: -1 (use per-chip defaults))");

module_param_named(enable_rc6, i915.enable_rc6, int, 0400);
module_param_named_unsafe(enable_rc6, i915.enable_rc6, int, 0400);
MODULE_PARM_DESC(enable_rc6,
"Enable power-saving render C-state 6. "
"Different stages can be selected via bitmask values "
"(0 = disable; 1 = enable rc6; 2 = enable deep rc6; 4 = enable deepest rc6). "
"For example, 3 would enable rc6 and deep rc6, and 7 would enable everything. "
"default: -1 (use per-chip default)");

module_param_named(enable_fbc, i915.enable_fbc, int, 0600);
module_param_named_unsafe(enable_fbc, i915.enable_fbc, int, 0600);
MODULE_PARM_DESC(enable_fbc,
"Enable frame buffer compression for power savings "
"(default: -1 (use per-chip default))");
Expand Down Expand Up @@ -113,7 +113,7 @@ MODULE_PARM_DESC(enable_hangcheck,
"WARNING: Disabling this can cause system wide hangs. "
"(default: true)");

module_param_named(enable_ppgtt, i915.enable_ppgtt, int, 0400);
module_param_named_unsafe(enable_ppgtt, i915.enable_ppgtt, int, 0400);
MODULE_PARM_DESC(enable_ppgtt,
"Override PPGTT usage. "
"(-1=auto [default], 0=disabled, 1=aliasing, 2=full)");
Expand Down
2 changes: 1 addition & 1 deletion drivers/tty/serial/8250/8250_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3587,7 +3587,7 @@ static void __used s8250_options(void)
#ifdef CONFIG_SERIAL_8250_RSA
__module_param_call(MODULE_PARAM_PREFIX, probe_rsa,
&param_array_ops, .arr = &__param_arr_probe_rsa,
0444, -1);
0444, -1, 0);
#endif
}
#else
Expand Down
50 changes: 39 additions & 11 deletions include/linux/moduleparam.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct kernel_param;
* NOARG - the parameter allows for no argument (foo instead of foo=1)
*/
enum {
KERNEL_PARAM_FL_NOARG = (1 << 0)
KERNEL_PARAM_OPS_FL_NOARG = (1 << 0)
};

struct kernel_param_ops {
Expand All @@ -56,11 +56,21 @@ struct kernel_param_ops {
void (*free)(void *arg);
};

/*
* Flags available for kernel_param
*
* UNSAFE - the parameter is dangerous and setting it will taint the kernel
*/
enum {
KERNEL_PARAM_FL_UNSAFE = (1 << 0)
};

struct kernel_param {
const char *name;
const struct kernel_param_ops *ops;
u16 perm;
s16 level;
s8 level;
u8 flags;
union {
void *arg;
const struct kparam_string *str;
Expand Down Expand Up @@ -112,6 +122,12 @@ struct kparam_array
#define module_param(name, type, perm) \
module_param_named(name, name, type, perm)

/**
* module_param_unsafe - same as module_param but taints kernel
*/
#define module_param_unsafe(name, type, perm) \
module_param_named_unsafe(name, name, type, perm)

/**
* module_param_named - typesafe helper for a renamed module/cmdline parameter
* @name: a valid C identifier which is the parameter name.
Expand All @@ -128,6 +144,14 @@ struct kparam_array
module_param_cb(name, &param_ops_##type, &value, perm); \
__MODULE_PARM_TYPE(name, #type)

/**
* module_param_named_unsafe - same as module_param_named but taints kernel
*/
#define module_param_named_unsafe(name, value, type, perm) \
param_check_##type(name, &(value)); \
module_param_cb_unsafe(name, &param_ops_##type, &value, perm); \
__MODULE_PARM_TYPE(name, #type)

/**
* module_param_cb - general callback for a module/cmdline parameter
* @name: a valid C identifier which is the parameter name.
Expand All @@ -137,7 +161,11 @@ struct kparam_array
* The ops can have NULL set or get functions.
*/
#define module_param_cb(name, ops, arg, perm) \
__module_param_call(MODULE_PARAM_PREFIX, name, ops, arg, perm, -1)
__module_param_call(MODULE_PARAM_PREFIX, name, ops, arg, perm, -1, 0)

#define module_param_cb_unsafe(name, ops, arg, perm) \
__module_param_call(MODULE_PARAM_PREFIX, name, ops, arg, perm, -1, \
KERNEL_PARAM_FL_UNSAFE)

/**
* <level>_param_cb - general callback for a module/cmdline parameter
Expand All @@ -149,7 +177,7 @@ struct kparam_array
* The ops can have NULL set or get functions.
*/
#define __level_param_cb(name, ops, arg, perm, level) \
__module_param_call(MODULE_PARAM_PREFIX, name, ops, arg, perm, level)
__module_param_call(MODULE_PARAM_PREFIX, name, ops, arg, perm, level, 0)

#define core_param_cb(name, ops, arg, perm) \
__level_param_cb(name, ops, arg, perm, 1)
Expand Down Expand Up @@ -184,22 +212,22 @@ struct kparam_array

/* This is the fundamental function for registering boot/module
parameters. */
#define __module_param_call(prefix, name, ops, arg, perm, level) \
#define __module_param_call(prefix, name, ops, arg, perm, level, flags) \
/* Default value instead of permissions? */ \
static const char __param_str_##name[] = prefix #name; \
static struct kernel_param __moduleparam_const __param_##name \
__used \
__attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
= { __param_str_##name, ops, VERIFY_OCTAL_PERMISSIONS(perm), \
level, { arg } }
level, flags, { arg } }

/* Obsolete - use module_param_cb() */
#define module_param_call(name, set, get, arg, perm) \
static struct kernel_param_ops __param_ops_##name = \
{ 0, (void *)set, (void *)get }; \
{ .flags = 0, (void *)set, (void *)get }; \
__module_param_call(MODULE_PARAM_PREFIX, \
name, &__param_ops_##name, arg, \
(perm) + sizeof(__check_old_set_param(set))*0, -1)
(perm) + sizeof(__check_old_set_param(set))*0, -1, 0)

/* We don't get oldget: it's often a new-style param_get_uint, etc. */
static inline int
Expand Down Expand Up @@ -279,7 +307,7 @@ static inline void __kernel_param_unlock(void)
*/
#define core_param(name, var, type, perm) \
param_check_##type(name, &(var)); \
__module_param_call("", name, &param_ops_##type, &var, perm, -1)
__module_param_call("", name, &param_ops_##type, &var, perm, -1, 0)
#endif /* !MODULE */

/**
Expand All @@ -297,7 +325,7 @@ static inline void __kernel_param_unlock(void)
= { len, string }; \
__module_param_call(MODULE_PARAM_PREFIX, name, \
&param_ops_string, \
.str = &__param_string_##name, perm, -1); \
.str = &__param_string_##name, perm, -1, 0);\
__MODULE_PARM_TYPE(name, "string")

/**
Expand Down Expand Up @@ -444,7 +472,7 @@ extern int param_set_bint(const char *val, const struct kernel_param *kp);
__module_param_call(MODULE_PARAM_PREFIX, name, \
&param_array_ops, \
.arr = &__param_arr_##name, \
perm, -1); \
perm, -1, 0); \
__MODULE_PARM_TYPE(name, "array of " #type)

extern struct kernel_param_ops param_array_ops;
Expand Down
43 changes: 43 additions & 0 deletions init/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1919,6 +1919,49 @@ config MODULE_SIG_HASH
default "sha384" if MODULE_SIG_SHA384
default "sha512" if MODULE_SIG_SHA512

config MODULE_COMPRESS
bool "Compress modules on installation"
depends on MODULES
help
This option compresses the kernel modules when 'make
modules_install' is run.

The modules will be compressed either using gzip or xz depend on the
choice made in "Compression algorithm".

module-init-tools has support for gzip format while kmod handle gzip
and xz compressed modules.

When a kernel module is installed from outside of the main kernel
source and uses the Kbuild system for installing modules then that
kernel module will also be compressed when it is installed.

This option provides little benefit when the modules are to be used inside
an initrd or initramfs, it generally is more efficient to compress the whole
initrd or initramfs instead.

This is fully compatible with signed modules while the signed module is
compressed. module-init-tools or kmod handles decompression and provide to
other layer the uncompressed but signed payload.

choice
prompt "Compression algorithm"
depends on MODULE_COMPRESS
default MODULE_COMPRESS_GZIP
help
This determines which sort of compression will be used during
'make modules_install'.

GZIP (default) and XZ are supported.

config MODULE_COMPRESS_GZIP
bool "GZIP"

config MODULE_COMPRESS_XZ
bool "XZ"

endchoice

endif # MODULES

config INIT_ALL_POSSIBLE
Expand Down
2 changes: 1 addition & 1 deletion kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ static int param_set_bool_enable_only(const char *val,
}

static const struct kernel_param_ops param_ops_bool_enable_only = {
.flags = KERNEL_PARAM_FL_NOARG,
.flags = KERNEL_PARAM_OPS_FL_NOARG,
.set = param_set_bool_enable_only,
.get = param_get_bool,
};
Expand Down
17 changes: 14 additions & 3 deletions kernel/params.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ bool parameq(const char *a, const char *b)
return parameqn(a, b, strlen(a)+1);
}

static void param_check_unsafe(const struct kernel_param *kp)
{
if (kp->flags & KERNEL_PARAM_FL_UNSAFE) {
pr_warn("Setting dangerous option %s - tainting kernel\n",
kp->name);
add_taint(TAINT_USER, LOCKDEP_STILL_OK);
}
}

static int parse_one(char *param,
char *val,
const char *doing,
Expand All @@ -104,11 +113,12 @@ static int parse_one(char *param,
return 0;
/* No one handled NULL, so do it here. */
if (!val &&
!(params[i].ops->flags & KERNEL_PARAM_FL_NOARG))
!(params[i].ops->flags & KERNEL_PARAM_OPS_FL_NOARG))
return -EINVAL;
pr_debug("handling %s with %p\n", param,
params[i].ops->set);
mutex_lock(&param_lock);
param_check_unsafe(&params[i]);
err = params[i].ops->set(val, &params[i]);
mutex_unlock(&param_lock);
return err;
Expand Down Expand Up @@ -318,7 +328,7 @@ int param_get_bool(char *buffer, const struct kernel_param *kp)
EXPORT_SYMBOL(param_get_bool);

struct kernel_param_ops param_ops_bool = {
.flags = KERNEL_PARAM_FL_NOARG,
.flags = KERNEL_PARAM_OPS_FL_NOARG,
.set = param_set_bool,
.get = param_get_bool,
};
Expand Down Expand Up @@ -369,7 +379,7 @@ int param_set_bint(const char *val, const struct kernel_param *kp)
EXPORT_SYMBOL(param_set_bint);

struct kernel_param_ops param_ops_bint = {
.flags = KERNEL_PARAM_FL_NOARG,
.flags = KERNEL_PARAM_OPS_FL_NOARG,
.set = param_set_bint,
.get = param_get_int,
};
Expand Down Expand Up @@ -552,6 +562,7 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
return -EPERM;

mutex_lock(&param_lock);
param_check_unsafe(attribute->param);
err = attribute->param->ops->set(buf, attribute->param);
mutex_unlock(&param_lock);
if (!err)
Expand Down
7 changes: 6 additions & 1 deletion scripts/Makefile.modinst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ __modinst: $(modules)

# Don't stop modules_install if we can't sign external modules.
quiet_cmd_modules_install = INSTALL $@
cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@) ; $(mod_sign_cmd) $(2)/$(notdir $@) $(patsubst %,|| true,$(KBUILD_EXTMOD))
cmd_modules_install = \
mkdir -p $(2) ; \
cp $@ $(2) ; \
$(mod_strip_cmd) $(2)/$(notdir $@) ; \
$(mod_sign_cmd) $(2)/$(notdir $@) $(patsubst %,|| true,$(KBUILD_EXTMOD)) ; \
$(mod_compress_cmd) $(2)/$(notdir $@)

# Modules built outside the kernel source tree go into extra by default
INSTALL_MOD_DIR ?= extra
Expand Down
2 changes: 1 addition & 1 deletion scripts/Makefile.modsign
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ __modsign:

include scripts/Kbuild.include

__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
__modules := $(sort $(shell grep -h '\.ko$$' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o)))

PHONY += $(modules)
Expand Down
Loading

0 comments on commit bdf428f

Please sign in to comment.