diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-11 00:31:58 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-11 00:31:58 -0400 |
| commit | c8d6637d0497d62093dbba0694c7b3a80b79bfe1 (patch) | |
| tree | 4ef432511fa6fa959429e1fc961fb186f1745e54 | |
| parent | 801a71a858631109a64bf30b1c480b0a18386605 (diff) | |
| parent | 76215b04fd297c008b91ece732ed36e67e0181fa (diff) | |
Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux
Pull module updates from Rusty Russell:
"This finally applies the stricter sysfs perms checking we pulled out
before last merge window. A few stragglers are fixed (thanks
linux-next!)"
* tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux:
arch/powerpc/platforms/powernv/opal-dump.c: fix world-writable sysfs files
arch/powerpc/platforms/powernv/opal-elog.c: fix world-writable sysfs files
drivers/video/fbdev/s3c2410fb.c: don't make debug world-writable.
ARM: avoid ARM binutils leaking ELF local symbols
scripts: modpost: Remove numeric suffix pattern matching
scripts: modpost: fix compilation warning
sysfs: disallow world-writable files.
module: return bool from within_module*()
module: add within_module() function
modules: Fix build error in moduleloader.h
| -rw-r--r-- | arch/powerpc/platforms/powernv/opal-dump.c | 4 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powernv/opal-elog.c | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/s3c2410fb.c | 2 | ||||
| -rw-r--r-- | include/linux/kernel.h | 2 | ||||
| -rw-r--r-- | include/linux/module.h | 11 | ||||
| -rw-r--r-- | include/linux/moduleloader.h | 6 | ||||
| -rw-r--r-- | kernel/module.c | 14 | ||||
| -rw-r--r-- | scripts/mod/modpost.c | 58 |
8 files changed, 40 insertions, 61 deletions
diff --git a/arch/powerpc/platforms/powernv/opal-dump.c b/arch/powerpc/platforms/powernv/opal-dump.c index 788a1977b9a5..85bb8fff7947 100644 --- a/arch/powerpc/platforms/powernv/opal-dump.c +++ b/arch/powerpc/platforms/powernv/opal-dump.c | |||
| @@ -102,9 +102,9 @@ static ssize_t dump_ack_store(struct dump_obj *dump_obj, | |||
| 102 | * due to the dynamic size of the dump | 102 | * due to the dynamic size of the dump |
| 103 | */ | 103 | */ |
| 104 | static struct dump_attribute id_attribute = | 104 | static struct dump_attribute id_attribute = |
| 105 | __ATTR(id, 0666, dump_id_show, NULL); | 105 | __ATTR(id, S_IRUGO, dump_id_show, NULL); |
| 106 | static struct dump_attribute type_attribute = | 106 | static struct dump_attribute type_attribute = |
| 107 | __ATTR(type, 0666, dump_type_show, NULL); | 107 | __ATTR(type, S_IRUGO, dump_type_show, NULL); |
| 108 | static struct dump_attribute ack_attribute = | 108 | static struct dump_attribute ack_attribute = |
| 109 | __ATTR(acknowledge, 0660, dump_ack_show, dump_ack_store); | 109 | __ATTR(acknowledge, 0660, dump_ack_show, dump_ack_store); |
| 110 | 110 | ||
diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c index 0ad533b617f7..bbdb3ffaab98 100644 --- a/arch/powerpc/platforms/powernv/opal-elog.c +++ b/arch/powerpc/platforms/powernv/opal-elog.c | |||
| @@ -82,9 +82,9 @@ static ssize_t elog_ack_store(struct elog_obj *elog_obj, | |||
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | static struct elog_attribute id_attribute = | 84 | static struct elog_attribute id_attribute = |
| 85 | __ATTR(id, 0666, elog_id_show, NULL); | 85 | __ATTR(id, S_IRUGO, elog_id_show, NULL); |
| 86 | static struct elog_attribute type_attribute = | 86 | static struct elog_attribute type_attribute = |
| 87 | __ATTR(type, 0666, elog_type_show, NULL); | 87 | __ATTR(type, S_IRUGO, elog_type_show, NULL); |
| 88 | static struct elog_attribute ack_attribute = | 88 | static struct elog_attribute ack_attribute = |
| 89 | __ATTR(acknowledge, 0660, elog_ack_show, elog_ack_store); | 89 | __ATTR(acknowledge, 0660, elog_ack_show, elog_ack_store); |
| 90 | 90 | ||
diff --git a/drivers/video/fbdev/s3c2410fb.c b/drivers/video/fbdev/s3c2410fb.c index d68595dcc5fd..43c63a4f3178 100644 --- a/drivers/video/fbdev/s3c2410fb.c +++ b/drivers/video/fbdev/s3c2410fb.c | |||
| @@ -616,7 +616,7 @@ static int s3c2410fb_debug_store(struct device *dev, | |||
| 616 | return len; | 616 | return len; |
| 617 | } | 617 | } |
| 618 | 618 | ||
| 619 | static DEVICE_ATTR(debug, 0666, s3c2410fb_debug_show, s3c2410fb_debug_store); | 619 | static DEVICE_ATTR(debug, 0664, s3c2410fb_debug_show, s3c2410fb_debug_store); |
| 620 | 620 | ||
| 621 | static struct fb_ops s3c2410fb_ops = { | 621 | static struct fb_ops s3c2410fb_ops = { |
| 622 | .owner = THIS_MODULE, | 622 | .owner = THIS_MODULE, |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 31ae66f34235..95624bed87ef 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
| @@ -845,5 +845,7 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { } | |||
| 845 | /* User perms >= group perms >= other perms */ \ | 845 | /* User perms >= group perms >= other perms */ \ |
| 846 | BUILD_BUG_ON_ZERO(((perms) >> 6) < (((perms) >> 3) & 7)) + \ | 846 | BUILD_BUG_ON_ZERO(((perms) >> 6) < (((perms) >> 3) & 7)) + \ |
| 847 | BUILD_BUG_ON_ZERO((((perms) >> 3) & 7) < ((perms) & 7)) + \ | 847 | BUILD_BUG_ON_ZERO((((perms) >> 3) & 7) < ((perms) & 7)) + \ |
| 848 | /* Other writable? Generally considered a bad idea. */ \ | ||
| 849 | BUILD_BUG_ON_ZERO((perms) & 2) + \ | ||
| 848 | (perms)) | 850 | (perms)) |
| 849 | #endif | 851 | #endif |
diff --git a/include/linux/module.h b/include/linux/module.h index f520a767c86c..71f282a4e307 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
| @@ -396,18 +396,25 @@ bool is_module_address(unsigned long addr); | |||
| 396 | bool is_module_percpu_address(unsigned long addr); | 396 | bool is_module_percpu_address(unsigned long addr); |
| 397 | bool is_module_text_address(unsigned long addr); | 397 | bool is_module_text_address(unsigned long addr); |
| 398 | 398 | ||
| 399 | static inline int within_module_core(unsigned long addr, const struct module *mod) | 399 | static inline bool within_module_core(unsigned long addr, |
| 400 | const struct module *mod) | ||
| 400 | { | 401 | { |
| 401 | return (unsigned long)mod->module_core <= addr && | 402 | return (unsigned long)mod->module_core <= addr && |
| 402 | addr < (unsigned long)mod->module_core + mod->core_size; | 403 | addr < (unsigned long)mod->module_core + mod->core_size; |
| 403 | } | 404 | } |
| 404 | 405 | ||
| 405 | static inline int within_module_init(unsigned long addr, const struct module *mod) | 406 | static inline bool within_module_init(unsigned long addr, |
| 407 | const struct module *mod) | ||
| 406 | { | 408 | { |
| 407 | return (unsigned long)mod->module_init <= addr && | 409 | return (unsigned long)mod->module_init <= addr && |
| 408 | addr < (unsigned long)mod->module_init + mod->init_size; | 410 | addr < (unsigned long)mod->module_init + mod->init_size; |
| 409 | } | 411 | } |
| 410 | 412 | ||
| 413 | static inline bool within_module(unsigned long addr, const struct module *mod) | ||
| 414 | { | ||
| 415 | return within_module_init(addr, mod) || within_module_core(addr, mod); | ||
| 416 | } | ||
| 417 | |||
| 411 | /* Search for module by name: must hold module_mutex. */ | 418 | /* Search for module by name: must hold module_mutex. */ |
| 412 | struct module *find_module(const char *name); | 419 | struct module *find_module(const char *name); |
| 413 | 420 | ||
diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h index 560ca53a75fa..7eeb9bbfb816 100644 --- a/include/linux/moduleloader.h +++ b/include/linux/moduleloader.h | |||
| @@ -45,7 +45,8 @@ static inline int apply_relocate(Elf_Shdr *sechdrs, | |||
| 45 | unsigned int relsec, | 45 | unsigned int relsec, |
| 46 | struct module *me) | 46 | struct module *me) |
| 47 | { | 47 | { |
| 48 | printk(KERN_ERR "module %s: REL relocation unsupported\n", me->name); | 48 | printk(KERN_ERR "module %s: REL relocation unsupported\n", |
| 49 | module_name(me)); | ||
| 49 | return -ENOEXEC; | 50 | return -ENOEXEC; |
| 50 | } | 51 | } |
| 51 | #endif | 52 | #endif |
| @@ -67,7 +68,8 @@ static inline int apply_relocate_add(Elf_Shdr *sechdrs, | |||
| 67 | unsigned int relsec, | 68 | unsigned int relsec, |
| 68 | struct module *me) | 69 | struct module *me) |
| 69 | { | 70 | { |
| 70 | printk(KERN_ERR "module %s: REL relocation unsupported\n", me->name); | 71 | printk(KERN_ERR "module %s: REL relocation unsupported\n", |
| 72 | module_name(me)); | ||
| 71 | return -ENOEXEC; | 73 | return -ENOEXEC; |
| 72 | } | 74 | } |
| 73 | #endif | 75 | #endif |
diff --git a/kernel/module.c b/kernel/module.c index ae79ce615cb9..6f69463f0066 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -3381,6 +3381,8 @@ static inline int within(unsigned long addr, void *start, unsigned long size) | |||
| 3381 | */ | 3381 | */ |
| 3382 | static inline int is_arm_mapping_symbol(const char *str) | 3382 | static inline int is_arm_mapping_symbol(const char *str) |
| 3383 | { | 3383 | { |
| 3384 | if (str[0] == '.' && str[1] == 'L') | ||
| 3385 | return true; | ||
| 3384 | return str[0] == '$' && strchr("atd", str[1]) | 3386 | return str[0] == '$' && strchr("atd", str[1]) |
| 3385 | && (str[2] == '\0' || str[2] == '.'); | 3387 | && (str[2] == '\0' || str[2] == '.'); |
| 3386 | } | 3388 | } |
| @@ -3444,8 +3446,7 @@ const char *module_address_lookup(unsigned long addr, | |||
| 3444 | list_for_each_entry_rcu(mod, &modules, list) { | 3446 | list_for_each_entry_rcu(mod, &modules, list) { |
| 3445 | if (mod->state == MODULE_STATE_UNFORMED) | 3447 | if (mod->state == MODULE_STATE_UNFORMED) |
| 3446 | continue; | 3448 | continue; |
| 3447 | if (within_module_init(addr, mod) || | 3449 | if (within_module(addr, mod)) { |
| 3448 | within_module_core(addr, mod)) { | ||
| 3449 | if (modname) | 3450 | if (modname) |
| 3450 | *modname = mod->name; | 3451 | *modname = mod->name; |
| 3451 | ret = get_ksymbol(mod, addr, size, offset); | 3452 | ret = get_ksymbol(mod, addr, size, offset); |
| @@ -3469,8 +3470,7 @@ int lookup_module_symbol_name(unsigned long addr, char *symname) | |||
| 3469 | list_for_each_entry_rcu(mod, &modules, list) { | 3470 | list_for_each_entry_rcu(mod, &modules, list) { |
| 3470 | if (mod->state == MODULE_STATE_UNFORMED) | 3471 | if (mod->state == MODULE_STATE_UNFORMED) |
| 3471 | continue; | 3472 | continue; |
| 3472 | if (within_module_init(addr, mod) || | 3473 | if (within_module(addr, mod)) { |
| 3473 | within_module_core(addr, mod)) { | ||
| 3474 | const char *sym; | 3474 | const char *sym; |
| 3475 | 3475 | ||
| 3476 | sym = get_ksymbol(mod, addr, NULL, NULL); | 3476 | sym = get_ksymbol(mod, addr, NULL, NULL); |
| @@ -3495,8 +3495,7 @@ int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, | |||
| 3495 | list_for_each_entry_rcu(mod, &modules, list) { | 3495 | list_for_each_entry_rcu(mod, &modules, list) { |
| 3496 | if (mod->state == MODULE_STATE_UNFORMED) | 3496 | if (mod->state == MODULE_STATE_UNFORMED) |
| 3497 | continue; | 3497 | continue; |
| 3498 | if (within_module_init(addr, mod) || | 3498 | if (within_module(addr, mod)) { |
| 3499 | within_module_core(addr, mod)) { | ||
| 3500 | const char *sym; | 3499 | const char *sym; |
| 3501 | 3500 | ||
| 3502 | sym = get_ksymbol(mod, addr, size, offset); | 3501 | sym = get_ksymbol(mod, addr, size, offset); |
| @@ -3760,8 +3759,7 @@ struct module *__module_address(unsigned long addr) | |||
| 3760 | list_for_each_entry_rcu(mod, &modules, list) { | 3759 | list_for_each_entry_rcu(mod, &modules, list) { |
| 3761 | if (mod->state == MODULE_STATE_UNFORMED) | 3760 | if (mod->state == MODULE_STATE_UNFORMED) |
| 3762 | continue; | 3761 | continue; |
| 3763 | if (within_module_core(addr, mod) | 3762 | if (within_module(addr, mod)) |
| 3764 | || within_module_init(addr, mod)) | ||
| 3765 | return mod; | 3763 | return mod; |
| 3766 | } | 3764 | } |
| 3767 | return NULL; | 3765 | return NULL; |
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 9d9c5b905b35..091d90573b63 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
| @@ -772,32 +772,10 @@ static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr) | |||
| 772 | sechdr->sh_name; | 772 | sechdr->sh_name; |
| 773 | } | 773 | } |
| 774 | 774 | ||
| 775 | /* if sym is empty or point to a string | ||
| 776 | * like ".[0-9]+" then return 1. | ||
| 777 | * This is the optional prefix added by ld to some sections | ||
| 778 | */ | ||
| 779 | static int number_prefix(const char *sym) | ||
| 780 | { | ||
| 781 | if (*sym++ == '\0') | ||
| 782 | return 1; | ||
| 783 | if (*sym != '.') | ||
| 784 | return 0; | ||
| 785 | do { | ||
| 786 | char c = *sym++; | ||
| 787 | if (c < '0' || c > '9') | ||
| 788 | return 0; | ||
| 789 | } while (*sym); | ||
| 790 | return 1; | ||
| 791 | } | ||
| 792 | |||
| 793 | /* The pattern is an array of simple patterns. | 775 | /* The pattern is an array of simple patterns. |
| 794 | * "foo" will match an exact string equal to "foo" | 776 | * "foo" will match an exact string equal to "foo" |
| 795 | * "*foo" will match a string that ends with "foo" | 777 | * "*foo" will match a string that ends with "foo" |
| 796 | * "foo*" will match a string that begins with "foo" | 778 | * "foo*" will match a string that begins with "foo" |
| 797 | * "foo$" will match a string equal to "foo" or "foo.1" | ||
| 798 | * where the '1' can be any number including several digits. | ||
| 799 | * The $ syntax is for sections where ld append a dot number | ||
| 800 | * to make section name unique. | ||
| 801 | */ | 779 | */ |
| 802 | static int match(const char *sym, const char * const pat[]) | 780 | static int match(const char *sym, const char * const pat[]) |
| 803 | { | 781 | { |
| @@ -816,13 +794,6 @@ static int match(const char *sym, const char * const pat[]) | |||
| 816 | if (strncmp(sym, p, strlen(p) - 1) == 0) | 794 | if (strncmp(sym, p, strlen(p) - 1) == 0) |
| 817 | return 1; | 795 | return 1; |
| 818 | } | 796 | } |
| 819 | /* "foo$" */ | ||
| 820 | else if (*endp == '$') { | ||
| 821 | if (strncmp(sym, p, strlen(p) - 1) == 0) { | ||
| 822 | if (number_prefix(sym + strlen(p) - 1)) | ||
| 823 | return 1; | ||
| 824 | } | ||
| 825 | } | ||
| 826 | /* no wildcards */ | 797 | /* no wildcards */ |
| 827 | else { | 798 | else { |
| 828 | if (strcmp(p, sym) == 0) | 799 | if (strcmp(p, sym) == 0) |
| @@ -880,20 +851,20 @@ static void check_section(const char *modname, struct elf_info *elf, | |||
| 880 | 851 | ||
| 881 | 852 | ||
| 882 | #define ALL_INIT_DATA_SECTIONS \ | 853 | #define ALL_INIT_DATA_SECTIONS \ |
| 883 | ".init.setup$", ".init.rodata$", ".meminit.rodata$", \ | 854 | ".init.setup", ".init.rodata", ".meminit.rodata", \ |
| 884 | ".init.data$", ".meminit.data$" | 855 | ".init.data", ".meminit.data" |
| 885 | #define ALL_EXIT_DATA_SECTIONS \ | 856 | #define ALL_EXIT_DATA_SECTIONS \ |
| 886 | ".exit.data$", ".memexit.data$" | 857 | ".exit.data", ".memexit.data" |
| 887 | 858 | ||
| 888 | #define ALL_INIT_TEXT_SECTIONS \ | 859 | #define ALL_INIT_TEXT_SECTIONS \ |
| 889 | ".init.text$", ".meminit.text$" | 860 | ".init.text", ".meminit.text" |
| 890 | #define ALL_EXIT_TEXT_SECTIONS \ | 861 | #define ALL_EXIT_TEXT_SECTIONS \ |
| 891 | ".exit.text$", ".memexit.text$" | 862 | ".exit.text", ".memexit.text" |
| 892 | 863 | ||
| 893 | #define ALL_PCI_INIT_SECTIONS \ | 864 | #define ALL_PCI_INIT_SECTIONS \ |
| 894 | ".pci_fixup_early$", ".pci_fixup_header$", ".pci_fixup_final$", \ | 865 | ".pci_fixup_early", ".pci_fixup_header", ".pci_fixup_final", \ |
| 895 | ".pci_fixup_enable$", ".pci_fixup_resume$", \ | 866 | ".pci_fixup_enable", ".pci_fixup_resume", \ |
| 896 | ".pci_fixup_resume_early$", ".pci_fixup_suspend$" | 867 | ".pci_fixup_resume_early", ".pci_fixup_suspend" |
| 897 | 868 | ||
| 898 | #define ALL_XXXINIT_SECTIONS MEM_INIT_SECTIONS | 869 | #define ALL_XXXINIT_SECTIONS MEM_INIT_SECTIONS |
| 899 | #define ALL_XXXEXIT_SECTIONS MEM_EXIT_SECTIONS | 870 | #define ALL_XXXEXIT_SECTIONS MEM_EXIT_SECTIONS |
| @@ -901,8 +872,8 @@ static void check_section(const char *modname, struct elf_info *elf, | |||
| 901 | #define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS | 872 | #define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS |
| 902 | #define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS | 873 | #define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS |
| 903 | 874 | ||
| 904 | #define DATA_SECTIONS ".data$", ".data.rel$" | 875 | #define DATA_SECTIONS ".data", ".data.rel" |
| 905 | #define TEXT_SECTIONS ".text$", ".text.unlikely$" | 876 | #define TEXT_SECTIONS ".text", ".text.unlikely" |
| 906 | 877 | ||
| 907 | #define INIT_SECTIONS ".init.*" | 878 | #define INIT_SECTIONS ".init.*" |
| 908 | #define MEM_INIT_SECTIONS ".meminit.*" | 879 | #define MEM_INIT_SECTIONS ".meminit.*" |
| @@ -1703,12 +1674,11 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
| 1703 | 1674 | ||
| 1704 | static char *remove_dot(char *s) | 1675 | static char *remove_dot(char *s) |
| 1705 | { | 1676 | { |
| 1706 | char *end; | 1677 | size_t n = strcspn(s, "."); |
| 1707 | int n = strcspn(s, "."); | ||
| 1708 | 1678 | ||
| 1709 | if (n > 0 && s[n] != 0) { | 1679 | if (n && s[n]) { |
| 1710 | strtoul(s + n + 1, &end, 10); | 1680 | size_t m = strspn(s + n + 1, "0123456789"); |
| 1711 | if (end > s + n + 1 && (*end == '.' || *end == 0)) | 1681 | if (m && (s[n + m] == '.' || s[n + m] == 0)) |
| 1712 | s[n] = 0; | 1682 | s[n] = 0; |
| 1713 | } | 1683 | } |
| 1714 | return s; | 1684 | return s; |
