mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-09 06:43:09 +00:00
Minor fixes mainly, including a potential use-after-free on remove found by
CONFIG_DEBUG_KOBJECT_RELEASE which may be theoretical. Cheers, Rusty. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJSJsL7AAoJENkgDmzRrbjx/N0P+wU81L55uYdJnDVPsW/fzhyJ BEZtmhFWtqxHeuFMQpwm5N3/ORwMht4czF4Hf957ePtI2PelHu+kapnFFQ+/KHZs T5sjH0mAYf9+CPa8wj4OKVzvd8lH4udbV+E7INVfciDySRX5HKXynJ6pZHvfeu7y /2q2PH6kGzuGoTEkDwOOwJ5yyZqs+RW9ZkSMStgCOUE8GmoDXEsH1KwIYE/9buCh XTngMo7AhimQaQ9QKypJLjlcnI9X/9ljXqFRKqSFOeMA1Ba+h+7eUqd4FJI6jDJu tecMOxX9PezPK6Wdg8V7AFBSzOhDPqoKQBOcaqeLd1wVICi8oQirVzwQNlsoiVNu JC+8rDqaeuG3dazROhaAnez7nhHfTjnMsYLVMRUmYtqXetd0qWYSmlmcJRKSJwi4 okl/Lv5BroQdB9bB8+sc7l34nE3HXZGV3tJcNXf91NNEbDt97xFZ2YYbdtsQcOqj igUHcjsZq1gLsdIhnkHjTGLkLPxMTdCi8mtUc9+uzXHvSPJqEUMcn+fEA7RdliUw /WvpUX2tj2Al44LfBy6L0D6AVyS2/zIQ9PzH6FHsgVDqrNHomkF20w3btnM3yyPA hakV6vPr+kOpfSJYlTSU7yhEJh+LGkfPXeaX4X3tqubKhsZjq8rS7vrfbcqmgwvT DbzDKRx5R3URiiFSbb2v =15lp -----END PGP SIGNATURE----- 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()
This commit is contained in:
commit
3398d252a4
@ -42,6 +42,7 @@ struct module_kobject {
|
|||||||
struct module *mod;
|
struct module *mod;
|
||||||
struct kobject *drivers_dir;
|
struct kobject *drivers_dir;
|
||||||
struct module_param_attrs *mp;
|
struct module_param_attrs *mp;
|
||||||
|
struct completion *kobj_completion;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct module_attribute {
|
struct module_attribute {
|
||||||
@ -97,6 +98,11 @@ extern const struct gtype##_id __mod_##gtype##_table \
|
|||||||
/* For userspace: you can also call me... */
|
/* For userspace: you can also call me... */
|
||||||
#define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias)
|
#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
|
* The following license idents are currently accepted as indicating free
|
||||||
* software modules
|
* software modules
|
||||||
|
@ -36,7 +36,18 @@ static const char __UNIQUE_ID(name)[] \
|
|||||||
|
|
||||||
struct kernel_param;
|
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 {
|
struct kernel_param_ops {
|
||||||
|
/* How the ops should behave */
|
||||||
|
unsigned int flags;
|
||||||
/* Returns 0, or -errno. arg is in kp->arg. */
|
/* Returns 0, or -errno. arg is in kp->arg. */
|
||||||
int (*set)(const char *val, const struct kernel_param *kp);
|
int (*set)(const char *val, const struct kernel_param *kp);
|
||||||
/* Returns length written or -errno. Buffer is 4k (ie. be short!) */
|
/* Returns length written or -errno. Buffer is 4k (ie. be short!) */
|
||||||
@ -187,7 +198,7 @@ struct kparam_array
|
|||||||
/* Obsolete - use module_param_cb() */
|
/* Obsolete - use module_param_cb() */
|
||||||
#define module_param_call(name, set, get, arg, perm) \
|
#define module_param_call(name, set, get, arg, perm) \
|
||||||
static struct kernel_param_ops __param_ops_##name = \
|
static struct kernel_param_ops __param_ops_##name = \
|
||||||
{ (void *)set, (void *)get }; \
|
{ 0, (void *)set, (void *)get }; \
|
||||||
__module_param_call(MODULE_PARAM_PREFIX, \
|
__module_param_call(MODULE_PARAM_PREFIX, \
|
||||||
name, &__param_ops_##name, arg, \
|
name, &__param_ops_##name, arg, \
|
||||||
(perm) + sizeof(__check_old_set_param(set))*0, -1)
|
(perm) + sizeof(__check_old_set_param(set))*0, -1)
|
||||||
|
@ -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 = {
|
static const struct kernel_param_ops param_ops_bool_enable_only = {
|
||||||
|
.flags = KERNEL_PARAM_FL_NOARG,
|
||||||
.set = param_set_bool_enable_only,
|
.set = param_set_bool_enable_only,
|
||||||
.get = param_get_bool,
|
.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, \
|
static ssize_t show_modinfo_##field(struct module_attribute *mattr, \
|
||||||
struct module_kobject *mk, char *buffer) \
|
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) \
|
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);
|
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)
|
static int mod_sysfs_init(struct module *mod)
|
||||||
{
|
{
|
||||||
int err;
|
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,
|
err = kobject_init_and_add(&mod->mkobj.kobj, &module_ktype, NULL,
|
||||||
"%s", mod->name);
|
"%s", mod->name);
|
||||||
if (err)
|
if (err)
|
||||||
kobject_put(&mod->mkobj.kobj);
|
mod_kobject_put(mod);
|
||||||
|
|
||||||
/* delay uevent until full sysfs population */
|
/* delay uevent until full sysfs population */
|
||||||
out:
|
out:
|
||||||
@ -1682,7 +1691,7 @@ static int mod_sysfs_setup(struct module *mod,
|
|||||||
out_unreg_holders:
|
out_unreg_holders:
|
||||||
kobject_put(mod->holders_dir);
|
kobject_put(mod->holders_dir);
|
||||||
out_unreg:
|
out_unreg:
|
||||||
kobject_put(&mod->mkobj.kobj);
|
mod_kobject_put(mod);
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -1691,7 +1700,7 @@ static void mod_sysfs_fini(struct module *mod)
|
|||||||
{
|
{
|
||||||
remove_notes_attrs(mod);
|
remove_notes_attrs(mod);
|
||||||
remove_sect_attrs(mod);
|
remove_sect_attrs(mod);
|
||||||
kobject_put(&mod->mkobj.kobj);
|
mod_kobject_put(mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* !CONFIG_SYSFS */
|
#else /* !CONFIG_SYSFS */
|
||||||
|
@ -103,8 +103,8 @@ static int parse_one(char *param,
|
|||||||
|| params[i].level > max_level)
|
|| params[i].level > max_level)
|
||||||
return 0;
|
return 0;
|
||||||
/* No one handled NULL, so do it here. */
|
/* No one handled NULL, so do it here. */
|
||||||
if (!val && params[i].ops->set != param_set_bool
|
if (!val &&
|
||||||
&& params[i].ops->set != param_set_bint)
|
!(params[i].ops->flags & KERNEL_PARAM_FL_NOARG))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
pr_debug("handling %s with %p\n", param,
|
pr_debug("handling %s with %p\n", param,
|
||||||
params[i].ops->set);
|
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) \
|
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 = { \
|
struct kernel_param_ops param_ops_##name = { \
|
||||||
.set = param_set_##name, \
|
.set = param_set_##name, \
|
||||||
@ -252,7 +253,7 @@ int parse_args(const char *doing,
|
|||||||
EXPORT_SYMBOL(param_ops_##name)
|
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(short, short, "%hi", long, strict_strtol);
|
||||||
STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", unsigned long, strict_strtoul);
|
STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", unsigned long, strict_strtoul);
|
||||||
STANDARD_PARAM_DEF(int, int, "%i", long, strict_strtol);
|
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)
|
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);
|
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);
|
EXPORT_SYMBOL(param_get_bool);
|
||||||
|
|
||||||
struct kernel_param_ops param_ops_bool = {
|
struct kernel_param_ops param_ops_bool = {
|
||||||
|
.flags = KERNEL_PARAM_FL_NOARG,
|
||||||
.set = param_set_bool,
|
.set = param_set_bool,
|
||||||
.get = param_get_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);
|
EXPORT_SYMBOL(param_set_bint);
|
||||||
|
|
||||||
struct kernel_param_ops param_ops_bint = {
|
struct kernel_param_ops param_ops_bint = {
|
||||||
|
.flags = KERNEL_PARAM_FL_NOARG,
|
||||||
.set = param_set_bint,
|
.set = param_set_bint,
|
||||||
.get = param_get_int,
|
.get = param_get_int,
|
||||||
};
|
};
|
||||||
@ -827,7 +830,7 @@ ssize_t __modver_version_show(struct module_attribute *mattr,
|
|||||||
struct module_version_attribute *vattr =
|
struct module_version_attribute *vattr =
|
||||||
container_of(mattr, struct module_version_attribute, mattr);
|
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[];
|
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;
|
struct kset *module_kset;
|
||||||
int module_sysfs_initialized;
|
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 = {
|
struct kobj_type module_ktype = {
|
||||||
|
.release = module_kobj_release,
|
||||||
.sysfs_ops = &module_sysfs_ops,
|
.sysfs_ops = &module_sysfs_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -821,6 +821,7 @@ static const char *section_white_list[] =
|
|||||||
{
|
{
|
||||||
".comment*",
|
".comment*",
|
||||||
".debug*",
|
".debug*",
|
||||||
|
".cranges", /* sh64 */
|
||||||
".zdebug*", /* Compressed debug sections. */
|
".zdebug*", /* Compressed debug sections. */
|
||||||
".GCC-command-line", /* mn10300 */
|
".GCC-command-line", /* mn10300 */
|
||||||
".GCC.command.line", /* record-gcc-switches, non mn10300 */
|
".GCC.command.line", /* record-gcc-switches, non mn10300 */
|
||||||
|
@ -666,6 +666,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);
|
static int param_get_aabool(char *buffer, const struct kernel_param *kp);
|
||||||
#define param_check_aabool param_check_bool
|
#define param_check_aabool param_check_bool
|
||||||
static struct kernel_param_ops param_ops_aabool = {
|
static struct kernel_param_ops param_ops_aabool = {
|
||||||
|
.flags = KERNEL_PARAM_FL_NOARG,
|
||||||
.set = param_set_aabool,
|
.set = param_set_aabool,
|
||||||
.get = param_get_aabool
|
.get = param_get_aabool
|
||||||
};
|
};
|
||||||
@ -682,6 +683,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);
|
static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp);
|
||||||
#define param_check_aalockpolicy param_check_bool
|
#define param_check_aalockpolicy param_check_bool
|
||||||
static struct kernel_param_ops param_ops_aalockpolicy = {
|
static struct kernel_param_ops param_ops_aalockpolicy = {
|
||||||
|
.flags = KERNEL_PARAM_FL_NOARG,
|
||||||
.set = param_set_aalockpolicy,
|
.set = param_set_aalockpolicy,
|
||||||
.get = param_get_aalockpolicy
|
.get = param_get_aalockpolicy
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user