Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+50 -11
+6
include/linux/module.h
··· 42 42 struct module *mod; 43 43 struct kobject *drivers_dir; 44 44 struct module_param_attrs *mp; 45 + struct completion *kobj_completion; 45 46 }; 46 47 47 48 struct module_attribute { ··· 97 96 98 97 /* For userspace: you can also call me... */ 99 98 #define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias) 99 + 100 + /* Soft module dependencies. See man modprobe.d for details. 101 + * Example: MODULE_SOFTDEP("pre: module-foo module-bar post: module-baz") 102 + */ 103 + #define MODULE_SOFTDEP(_softdep) MODULE_INFO(softdep, _softdep) 100 104 101 105 /* 102 106 * The following license idents are currently accepted as indicating free
+12 -1
include/linux/moduleparam.h
··· 36 36 37 37 struct kernel_param; 38 38 39 + /* 40 + * Flags available for kernel_param_ops 41 + * 42 + * NOARG - the parameter allows for no argument (foo instead of foo=1) 43 + */ 44 + enum { 45 + KERNEL_PARAM_FL_NOARG = (1 << 0) 46 + }; 47 + 39 48 struct kernel_param_ops { 49 + /* How the ops should behave */ 50 + unsigned int flags; 40 51 /* Returns 0, or -errno. arg is in kp->arg. */ 41 52 int (*set)(const char *val, const struct kernel_param *kp); 42 53 /* Returns length written or -errno. Buffer is 4k (ie. be short!) */ ··· 198 187 /* Obsolete - use module_param_cb() */ 199 188 #define module_param_call(name, set, get, arg, perm) \ 200 189 static struct kernel_param_ops __param_ops_##name = \ 201 - { (void *)set, (void *)get }; \ 190 + { 0, (void *)set, (void *)get }; \ 202 191 __module_param_call(MODULE_PARAM_PREFIX, \ 203 192 name, &__param_ops_##name, arg, \ 204 193 (perm) + sizeof(__check_old_set_param(set))*0, -1)
+13 -4
kernel/module.c
··· 136 136 } 137 137 138 138 static const struct kernel_param_ops param_ops_bool_enable_only = { 139 + .flags = KERNEL_PARAM_FL_NOARG, 139 140 .set = param_set_bool_enable_only, 140 141 .get = param_get_bool, 141 142 }; ··· 604 603 static ssize_t show_modinfo_##field(struct module_attribute *mattr, \ 605 604 struct module_kobject *mk, char *buffer) \ 606 605 { \ 607 - return sprintf(buffer, "%s\n", mk->mod->field); \ 606 + return scnprintf(buffer, PAGE_SIZE, "%s\n", mk->mod->field); \ 608 607 } \ 609 608 static int modinfo_##field##_exists(struct module *mod) \ 610 609 { \ ··· 1612 1611 kfree(mod->modinfo_attrs); 1613 1612 } 1614 1613 1614 + static void mod_kobject_put(struct module *mod) 1615 + { 1616 + DECLARE_COMPLETION_ONSTACK(c); 1617 + mod->mkobj.kobj_completion = &c; 1618 + kobject_put(&mod->mkobj.kobj); 1619 + wait_for_completion(&c); 1620 + } 1621 + 1615 1622 static int mod_sysfs_init(struct module *mod) 1616 1623 { 1617 1624 int err; ··· 1647 1638 err = kobject_init_and_add(&mod->mkobj.kobj, &module_ktype, NULL, 1648 1639 "%s", mod->name); 1649 1640 if (err) 1650 - kobject_put(&mod->mkobj.kobj); 1641 + mod_kobject_put(mod); 1651 1642 1652 1643 /* delay uevent until full sysfs population */ 1653 1644 out: ··· 1691 1682 out_unreg_holders: 1692 1683 kobject_put(mod->holders_dir); 1693 1684 out_unreg: 1694 - kobject_put(&mod->mkobj.kobj); 1685 + mod_kobject_put(mod); 1695 1686 out: 1696 1687 return err; 1697 1688 } ··· 1700 1691 { 1701 1692 remove_notes_attrs(mod); 1702 1693 remove_sect_attrs(mod); 1703 - kobject_put(&mod->mkobj.kobj); 1694 + mod_kobject_put(mod); 1704 1695 } 1705 1696 1706 1697 #else /* !CONFIG_SYSFS */
+16 -6
kernel/params.c
··· 103 103 || params[i].level > max_level) 104 104 return 0; 105 105 /* No one handled NULL, so do it here. */ 106 - if (!val && params[i].ops->set != param_set_bool 107 - && params[i].ops->set != param_set_bint) 106 + if (!val && 107 + !(params[i].ops->flags & KERNEL_PARAM_FL_NOARG)) 108 108 return -EINVAL; 109 109 pr_debug("handling %s with %p\n", param, 110 110 params[i].ops->set); ··· 241 241 } \ 242 242 int param_get_##name(char *buffer, const struct kernel_param *kp) \ 243 243 { \ 244 - return sprintf(buffer, format, *((type *)kp->arg)); \ 244 + return scnprintf(buffer, PAGE_SIZE, format, \ 245 + *((type *)kp->arg)); \ 245 246 } \ 246 247 struct kernel_param_ops param_ops_##name = { \ 247 248 .set = param_set_##name, \ ··· 253 252 EXPORT_SYMBOL(param_ops_##name) 254 253 255 254 256 - STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, strict_strtoul); 255 + STANDARD_PARAM_DEF(byte, unsigned char, "%hhu", unsigned long, strict_strtoul); 257 256 STANDARD_PARAM_DEF(short, short, "%hi", long, strict_strtol); 258 257 STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", unsigned long, strict_strtoul); 259 258 STANDARD_PARAM_DEF(int, int, "%i", long, strict_strtol); ··· 286 285 287 286 int param_get_charp(char *buffer, const struct kernel_param *kp) 288 287 { 289 - return sprintf(buffer, "%s", *((char **)kp->arg)); 288 + return scnprintf(buffer, PAGE_SIZE, "%s", *((char **)kp->arg)); 290 289 } 291 290 EXPORT_SYMBOL(param_get_charp); 292 291 ··· 321 320 EXPORT_SYMBOL(param_get_bool); 322 321 323 322 struct kernel_param_ops param_ops_bool = { 323 + .flags = KERNEL_PARAM_FL_NOARG, 324 324 .set = param_set_bool, 325 325 .get = param_get_bool, 326 326 }; ··· 372 370 EXPORT_SYMBOL(param_set_bint); 373 371 374 372 struct kernel_param_ops param_ops_bint = { 373 + .flags = KERNEL_PARAM_FL_NOARG, 375 374 .set = param_set_bint, 376 375 .get = param_get_int, 377 376 }; ··· 830 827 struct module_version_attribute *vattr = 831 828 container_of(mattr, struct module_version_attribute, mattr); 832 829 833 - return sprintf(buf, "%s\n", vattr->version); 830 + return scnprintf(buf, PAGE_SIZE, "%s\n", vattr->version); 834 831 } 835 832 836 833 extern const struct module_version_attribute *__start___modver[]; ··· 915 912 struct kset *module_kset; 916 913 int module_sysfs_initialized; 917 914 915 + static void module_kobj_release(struct kobject *kobj) 916 + { 917 + struct module_kobject *mk = to_module_kobject(kobj); 918 + complete(mk->kobj_completion); 919 + } 920 + 918 921 struct kobj_type module_ktype = { 922 + .release = module_kobj_release, 919 923 .sysfs_ops = &module_sysfs_ops, 920 924 }; 921 925
+1
scripts/mod/modpost.c
··· 821 821 { 822 822 ".comment*", 823 823 ".debug*", 824 + ".cranges", /* sh64 */ 824 825 ".zdebug*", /* Compressed debug sections. */ 825 826 ".GCC-command-line", /* mn10300 */ 826 827 ".GCC.command.line", /* record-gcc-switches, non mn10300 */
+2
security/apparmor/lsm.c
··· 666 666 static int param_get_aabool(char *buffer, const struct kernel_param *kp); 667 667 #define param_check_aabool param_check_bool 668 668 static struct kernel_param_ops param_ops_aabool = { 669 + .flags = KERNEL_PARAM_FL_NOARG, 669 670 .set = param_set_aabool, 670 671 .get = param_get_aabool 671 672 }; ··· 683 682 static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp); 684 683 #define param_check_aalockpolicy param_check_bool 685 684 static struct kernel_param_ops param_ops_aalockpolicy = { 685 + .flags = KERNEL_PARAM_FL_NOARG, 686 686 .set = param_set_aalockpolicy, 687 687 .get = param_get_aalockpolicy 688 688 };