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; |