Nothing major: support for compressing modules, and auto-tainting params.

Cheers,
 Rusty.
 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.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJUGFrvAAoJENkgDmzRrbjxOJYQALaZbTumrtX3Mo/FAtzn8d5N
 8gxcqk1Mhz4lR1vPWy/YN/H2f23qb/saqLxPar8Wgou3h7N8EqSdwDqJSuvEqhG0
 iEXUsNLC7BOsDkLYhdjTfZoW/lsVU/EH4bkZMSxAZI9V64phXhDYfPb5SQgJTECr
 Ue6IK4ijW6zdWLstGfg/ixrIeGDUSnyiThF9O2mYVaB1D0QkLDIAZxbjZJgfFfut
 PwO33/sEV4pceTpkmxFKl/OiS+obi/VbDixjSCcO+jaBd1pVxH9fhhKREStOhN4z
 88z5ADR71RH6so9TQTwIIcgb2Hon5d+3RVMB6CxuvKs9NmHSXDiQyZvG9J/jiSdm
 KrPKSiVwGGwJSwxXTm8CDaz6Oj0ibDXBIzv/vYI22sR7u8PmRQFvL3O1VrW+KDnE
 yoG75S9DHzSQ1183xFFFTt4FBRm/4XKyVs+F6YqYkchLigrUfQMCGb1cmZyE5y7K
 bgNyonu0m/ItoQmekoDgYqvSjwdguaJ35XCW55GrKJ84JDHBaw3SpPdEfjAS8FsH
 aT5o2oernvwRG6gsX9858RvB/uo1UKwHv1waDfV4cqNjMm5Ko+Yr6OIdQvBQiq07
 cFkVmkrMtEyX19QyIGW3QSbFL1lr3X5cC5glzEeKY941yZbTluSsNuMlMPT1+IMx
 NOUbh0aG8B8ZaMZPFNLi
 =QzCn
 -----END PGP SIGNATURE-----

Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/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
This commit is contained in:
Linus Torvalds 2014-10-07 20:17:38 -04:00
commit bdf428feb2
11 changed files with 139 additions and 36 deletions

View File

@ -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.
#

View File

@ -66,12 +66,12 @@ 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 "
@ -79,7 +79,7 @@ MODULE_PARM_DESC(enable_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))");
@ -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)");

View File

@ -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

View File

@ -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 {
@ -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;
@ -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.
@ -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.
@ -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
@ -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)
@ -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
@ -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 */
/**
@ -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")
/**
@ -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;

View File

@ -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

View File

@ -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,
};

View File

@ -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,
@ -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;
@ -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,
};
@ -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,
};
@ -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)

View File

@ -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

View File

@ -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)

View File

@ -24,9 +24,9 @@
#include "../../include/linux/export.h"
/* Are we using CONFIG_MODVERSIONS? */
int modversions = 0;
static int modversions = 0;
/* Warn about undefined symbols? (do so if we have vmlinux) */
int have_vmlinux = 0;
static int have_vmlinux = 0;
/* Is CONFIG_MODULE_SRCVERSION_ALL set? */
static int all_versions = 0;
/* If we are modposting external module set to 1 */
@ -229,7 +229,7 @@ static struct symbol *find_symbol(const char *name)
return NULL;
}
static struct {
static const struct {
const char *str;
enum export export;
} export_list[] = {
@ -805,7 +805,7 @@ static int match(const char *sym, const char * const pat[])
}
/* sections that we do not want to do full section mismatch check on */
static const char *section_white_list[] =
static const char *const section_white_list[] =
{
".comment*",
".debug*",
@ -882,17 +882,18 @@ static void check_section(const char *modname, struct elf_info *elf,
#define MEM_EXIT_SECTIONS ".memexit.*"
/* init data sections */
static const char *init_data_sections[] = { ALL_INIT_DATA_SECTIONS, NULL };
static const char *const init_data_sections[] =
{ ALL_INIT_DATA_SECTIONS, NULL };
/* all init sections */
static const char *init_sections[] = { ALL_INIT_SECTIONS, NULL };
static const char *const init_sections[] = { ALL_INIT_SECTIONS, NULL };
/* All init and exit sections (code + data) */
static const char *init_exit_sections[] =
static const char *const init_exit_sections[] =
{ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL };
/* data section */
static const char *data_sections[] = { DATA_SECTIONS, NULL };
static const char *const data_sections[] = { DATA_SECTIONS, NULL };
/* symbols in .data that may refer to init/exit sections */
@ -906,8 +907,8 @@ static const char *data_sections[] = { DATA_SECTIONS, NULL };
"*_probe_one", \
"*_console"
static const char *head_sections[] = { ".head.text*", NULL };
static const char *linker_symbols[] =
static const char *const head_sections[] = { ".head.text*", NULL };
static const char *const linker_symbols[] =
{ "__init_begin", "_sinittext", "_einittext", NULL };
enum mismatch {
@ -929,7 +930,7 @@ struct sectioncheck {
const char *symbol_white_list[20];
};
const struct sectioncheck sectioncheck[] = {
static const struct sectioncheck sectioncheck[] = {
/* Do not reference init/exit code/data from
* normal code and data
*/
@ -2211,7 +2212,7 @@ int main(int argc, char **argv)
err = 0;
for (mod = modules; mod; mod = mod->next) {
char fname[strlen(mod->name) + 10];
char fname[PATH_MAX];
if (mod->skip)
continue;

View File

@ -668,7 +668,7 @@ static int param_set_aabool(const char *val, const struct kernel_param *kp);
static int param_get_aabool(char *buffer, const struct kernel_param *kp);
#define param_check_aabool param_check_bool
static struct kernel_param_ops param_ops_aabool = {
.flags = KERNEL_PARAM_FL_NOARG,
.flags = KERNEL_PARAM_OPS_FL_NOARG,
.set = param_set_aabool,
.get = param_get_aabool
};
@ -685,7 +685,7 @@ static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp
static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp);
#define param_check_aalockpolicy param_check_bool
static struct kernel_param_ops param_ops_aalockpolicy = {
.flags = KERNEL_PARAM_FL_NOARG,
.flags = KERNEL_PARAM_OPS_FL_NOARG,
.set = param_set_aalockpolicy,
.get = param_get_aalockpolicy
};