diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/kernel/module.c b/kernel/module.c index 206915830d29..dc582749fa13 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -136,6 +136,7 @@ static int param_set_bool_enable_only(const char *val, | |||
136 | } | 136 | } |
137 | 137 | ||
138 | static const struct kernel_param_ops param_ops_bool_enable_only = { | 138 | static const struct kernel_param_ops param_ops_bool_enable_only = { |
139 | .flags = KERNEL_PARAM_FL_NOARG, | ||
139 | .set = param_set_bool_enable_only, | 140 | .set = param_set_bool_enable_only, |
140 | .get = param_get_bool, | 141 | .get = param_get_bool, |
141 | }; | 142 | }; |
@@ -603,7 +604,7 @@ static void setup_modinfo_##field(struct module *mod, const char *s) \ | |||
603 | static ssize_t show_modinfo_##field(struct module_attribute *mattr, \ | 604 | static ssize_t show_modinfo_##field(struct module_attribute *mattr, \ |
604 | struct module_kobject *mk, char *buffer) \ | 605 | struct module_kobject *mk, char *buffer) \ |
605 | { \ | 606 | { \ |
606 | return sprintf(buffer, "%s\n", mk->mod->field); \ | 607 | return scnprintf(buffer, PAGE_SIZE, "%s\n", mk->mod->field); \ |
607 | } \ | 608 | } \ |
608 | static int modinfo_##field##_exists(struct module *mod) \ | 609 | static int modinfo_##field##_exists(struct module *mod) \ |
609 | { \ | 610 | { \ |
@@ -1611,6 +1612,14 @@ static void module_remove_modinfo_attrs(struct module *mod) | |||
1611 | kfree(mod->modinfo_attrs); | 1612 | kfree(mod->modinfo_attrs); |
1612 | } | 1613 | } |
1613 | 1614 | ||
1615 | static void mod_kobject_put(struct module *mod) | ||
1616 | { | ||
1617 | DECLARE_COMPLETION_ONSTACK(c); | ||
1618 | mod->mkobj.kobj_completion = &c; | ||
1619 | kobject_put(&mod->mkobj.kobj); | ||
1620 | wait_for_completion(&c); | ||
1621 | } | ||
1622 | |||
1614 | static int mod_sysfs_init(struct module *mod) | 1623 | static int mod_sysfs_init(struct module *mod) |
1615 | { | 1624 | { |
1616 | int err; | 1625 | int err; |
@@ -1638,7 +1647,7 @@ static int mod_sysfs_init(struct module *mod) | |||
1638 | err = kobject_init_and_add(&mod->mkobj.kobj, &module_ktype, NULL, | 1647 | err = kobject_init_and_add(&mod->mkobj.kobj, &module_ktype, NULL, |
1639 | "%s", mod->name); | 1648 | "%s", mod->name); |
1640 | if (err) | 1649 | if (err) |
1641 | kobject_put(&mod->mkobj.kobj); | 1650 | mod_kobject_put(mod); |
1642 | 1651 | ||
1643 | /* delay uevent until full sysfs population */ | 1652 | /* delay uevent until full sysfs population */ |
1644 | out: | 1653 | out: |
@@ -1682,7 +1691,7 @@ out_unreg_param: | |||
1682 | out_unreg_holders: | 1691 | out_unreg_holders: |
1683 | kobject_put(mod->holders_dir); | 1692 | kobject_put(mod->holders_dir); |
1684 | out_unreg: | 1693 | out_unreg: |
1685 | kobject_put(&mod->mkobj.kobj); | 1694 | mod_kobject_put(mod); |
1686 | out: | 1695 | out: |
1687 | return err; | 1696 | return err; |
1688 | } | 1697 | } |
@@ -1691,7 +1700,7 @@ static void mod_sysfs_fini(struct module *mod) | |||
1691 | { | 1700 | { |
1692 | remove_notes_attrs(mod); | 1701 | remove_notes_attrs(mod); |
1693 | remove_sect_attrs(mod); | 1702 | remove_sect_attrs(mod); |
1694 | kobject_put(&mod->mkobj.kobj); | 1703 | mod_kobject_put(mod); |
1695 | } | 1704 | } |
1696 | 1705 | ||
1697 | #else /* !CONFIG_SYSFS */ | 1706 | #else /* !CONFIG_SYSFS */ |
@@ -2540,21 +2549,20 @@ static int copy_module_from_user(const void __user *umod, unsigned long len, | |||
2540 | /* Sets info->hdr and info->len. */ | 2549 | /* Sets info->hdr and info->len. */ |
2541 | static int copy_module_from_fd(int fd, struct load_info *info) | 2550 | static int copy_module_from_fd(int fd, struct load_info *info) |
2542 | { | 2551 | { |
2543 | struct file *file; | 2552 | struct fd f = fdget(fd); |
2544 | int err; | 2553 | int err; |
2545 | struct kstat stat; | 2554 | struct kstat stat; |
2546 | loff_t pos; | 2555 | loff_t pos; |
2547 | ssize_t bytes = 0; | 2556 | ssize_t bytes = 0; |
2548 | 2557 | ||
2549 | file = fget(fd); | 2558 | if (!f.file) |
2550 | if (!file) | ||
2551 | return -ENOEXEC; | 2559 | return -ENOEXEC; |
2552 | 2560 | ||
2553 | err = security_kernel_module_from_file(file); | 2561 | err = security_kernel_module_from_file(f.file); |
2554 | if (err) | 2562 | if (err) |
2555 | goto out; | 2563 | goto out; |
2556 | 2564 | ||
2557 | err = vfs_getattr(&file->f_path, &stat); | 2565 | err = vfs_getattr(&f.file->f_path, &stat); |
2558 | if (err) | 2566 | if (err) |
2559 | goto out; | 2567 | goto out; |
2560 | 2568 | ||
@@ -2577,7 +2585,7 @@ static int copy_module_from_fd(int fd, struct load_info *info) | |||
2577 | 2585 | ||
2578 | pos = 0; | 2586 | pos = 0; |
2579 | while (pos < stat.size) { | 2587 | while (pos < stat.size) { |
2580 | bytes = kernel_read(file, pos, (char *)(info->hdr) + pos, | 2588 | bytes = kernel_read(f.file, pos, (char *)(info->hdr) + pos, |
2581 | stat.size - pos); | 2589 | stat.size - pos); |
2582 | if (bytes < 0) { | 2590 | if (bytes < 0) { |
2583 | vfree(info->hdr); | 2591 | vfree(info->hdr); |
@@ -2591,7 +2599,7 @@ static int copy_module_from_fd(int fd, struct load_info *info) | |||
2591 | info->len = pos; | 2599 | info->len = pos; |
2592 | 2600 | ||
2593 | out: | 2601 | out: |
2594 | fput(file); | 2602 | fdput(f); |
2595 | return err; | 2603 | return err; |
2596 | } | 2604 | } |
2597 | 2605 | ||