Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3398d252 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux

Pull module updates from Rusty Russell:
 "Minor fixes mainly, including a potential use-after-free on remove
  found by CONFIG_DEBUG_KOBJECT_RELEASE which may be theoretical"

* tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux:
  module: Fix mod->mkobj.kobj potentially freed too early
  kernel/params.c: use scnprintf() instead of sprintf()
  kernel/module.c: use scnprintf() instead of sprintf()
  module/lsm: Have apparmor module parameters work with no args
  module: Add NOARG flag for ops with param_set_bool_enable_only() set function
  module: Add flag to allow mod params to have no arguments
  modules: add support for soft module dependencies
  scripts/mod/modpost.c: permit '.cranges' secton for sh64 architecture.
  module: fix sprintf format specifier in param_get_byte()
parents 27703bb4 942e4431
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ struct module_kobject {
	struct module *mod;
	struct kobject *drivers_dir;
	struct module_param_attrs *mp;
	struct completion *kobj_completion;
};

struct module_attribute {
@@ -97,6 +98,11 @@ extern const struct gtype##_id __mod_##gtype##_table \
/* For userspace: you can also call me... */
#define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias)

/* Soft module dependencies. See man modprobe.d for details.
 * Example: MODULE_SOFTDEP("pre: module-foo module-bar post: module-baz")
 */
#define MODULE_SOFTDEP(_softdep) MODULE_INFO(softdep, _softdep)

/*
 * The following license idents are currently accepted as indicating free
 * software modules
+12 −1
Original line number Diff line number Diff line
@@ -36,7 +36,18 @@ static const char __UNIQUE_ID(name)[] \

struct kernel_param;

/*
 * Flags available for kernel_param_ops
 *
 * NOARG - the parameter allows for no argument (foo instead of foo=1)
 */
enum {
	KERNEL_PARAM_FL_NOARG = (1 << 0)
};

struct kernel_param_ops {
	/* How the ops should behave */
	unsigned int flags;
	/* Returns 0, or -errno.  arg is in kp->arg. */
	int (*set)(const char *val, const struct kernel_param *kp);
	/* Returns length written or -errno.  Buffer is 4k (ie. be short!) */
@@ -187,7 +198,7 @@ struct kparam_array
/* Obsolete - use module_param_cb() */
#define module_param_call(name, set, get, arg, perm)			\
	static struct kernel_param_ops __param_ops_##name =		\
		 { (void *)set, (void *)get };				\
		{ 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)
+13 −4
Original line number Diff line number Diff line
@@ -136,6 +136,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,
	.set = param_set_bool_enable_only,
	.get = param_get_bool,
};
@@ -603,7 +604,7 @@ static void setup_modinfo_##field(struct module *mod, const char *s) \
static ssize_t show_modinfo_##field(struct module_attribute *mattr,   \
			struct module_kobject *mk, char *buffer)      \
{                                                                     \
	return sprintf(buffer, "%s\n", mk->mod->field);               \
	return scnprintf(buffer, PAGE_SIZE, "%s\n", mk->mod->field);  \
}                                                                     \
static int modinfo_##field##_exists(struct module *mod)               \
{                                                                     \
@@ -1611,6 +1612,14 @@ static void module_remove_modinfo_attrs(struct module *mod)
	kfree(mod->modinfo_attrs);
}

static void mod_kobject_put(struct module *mod)
{
	DECLARE_COMPLETION_ONSTACK(c);
	mod->mkobj.kobj_completion = &c;
	kobject_put(&mod->mkobj.kobj);
	wait_for_completion(&c);
}

static int mod_sysfs_init(struct module *mod)
{
	int err;
@@ -1638,7 +1647,7 @@ static int mod_sysfs_init(struct module *mod)
	err = kobject_init_and_add(&mod->mkobj.kobj, &module_ktype, NULL,
				   "%s", mod->name);
	if (err)
		kobject_put(&mod->mkobj.kobj);
		mod_kobject_put(mod);

	/* delay uevent until full sysfs population */
out:
@@ -1682,7 +1691,7 @@ out_unreg_param:
out_unreg_holders:
	kobject_put(mod->holders_dir);
out_unreg:
	kobject_put(&mod->mkobj.kobj);
	mod_kobject_put(mod);
out:
	return err;
}
@@ -1691,7 +1700,7 @@ static void mod_sysfs_fini(struct module *mod)
{
	remove_notes_attrs(mod);
	remove_sect_attrs(mod);
	kobject_put(&mod->mkobj.kobj);
	mod_kobject_put(mod);
}

#else /* !CONFIG_SYSFS */
+16 −6
Original line number Diff line number Diff line
@@ -103,8 +103,8 @@ static int parse_one(char *param,
			    || params[i].level > max_level)
				return 0;
			/* No one handled NULL, so do it here. */
			if (!val && params[i].ops->set != param_set_bool
			    && params[i].ops->set != param_set_bint)
			if (!val &&
			    !(params[i].ops->flags & KERNEL_PARAM_FL_NOARG))
				return -EINVAL;
			pr_debug("handling %s with %p\n", param,
				params[i].ops->set);
@@ -241,7 +241,8 @@ int parse_args(const char *doing,
	}								\
	int param_get_##name(char *buffer, const struct kernel_param *kp) \
	{								\
		return sprintf(buffer, format, *((type *)kp->arg));	\
		return scnprintf(buffer, PAGE_SIZE, format,		\
				*((type *)kp->arg));			\
	}								\
	struct kernel_param_ops param_ops_##name = {			\
		.set = param_set_##name,				\
@@ -252,7 +253,7 @@ int parse_args(const char *doing,
	EXPORT_SYMBOL(param_ops_##name)


STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, strict_strtoul);
STANDARD_PARAM_DEF(byte, unsigned char, "%hhu", unsigned long, strict_strtoul);
STANDARD_PARAM_DEF(short, short, "%hi", long, strict_strtol);
STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", unsigned long, strict_strtoul);
STANDARD_PARAM_DEF(int, int, "%i", long, strict_strtol);
@@ -285,7 +286,7 @@ EXPORT_SYMBOL(param_set_charp);

int param_get_charp(char *buffer, const struct kernel_param *kp)
{
	return sprintf(buffer, "%s", *((char **)kp->arg));
	return scnprintf(buffer, PAGE_SIZE, "%s", *((char **)kp->arg));
}
EXPORT_SYMBOL(param_get_charp);

@@ -320,6 +321,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,
	.set = param_set_bool,
	.get = param_get_bool,
};
@@ -370,6 +372,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,
	.set = param_set_bint,
	.get = param_get_int,
};
@@ -827,7 +830,7 @@ ssize_t __modver_version_show(struct module_attribute *mattr,
	struct module_version_attribute *vattr =
		container_of(mattr, struct module_version_attribute, mattr);

	return sprintf(buf, "%s\n", vattr->version);
	return scnprintf(buf, PAGE_SIZE, "%s\n", vattr->version);
}

extern const struct module_version_attribute *__start___modver[];
@@ -912,7 +915,14 @@ static const struct kset_uevent_ops module_uevent_ops = {
struct kset *module_kset;
int module_sysfs_initialized;

static void module_kobj_release(struct kobject *kobj)
{
	struct module_kobject *mk = to_module_kobject(kobj);
	complete(mk->kobj_completion);
}

struct kobj_type module_ktype = {
	.release   =	module_kobj_release,
	.sysfs_ops =	&module_sysfs_ops,
};

+1 −0
Original line number Diff line number Diff line
@@ -821,6 +821,7 @@ static const char *section_white_list[] =
{
	".comment*",
	".debug*",
	".cranges",		/* sh64 */
	".zdebug*",		/* Compressed debug sections. */
	".GCC-command-line",	/* mn10300 */
	".GCC.command.line",	/* record-gcc-switches, non mn10300 */
Loading