user: Use generic ns_common::count
[linux-2.6-microblaze.git] / kernel / module.c
index 646f1e2..1c5cff3 100644 (file)
@@ -4,6 +4,9 @@
    Copyright (C) 2001 Rusty Russell, 2002, 2010 Rusty Russell IBM.
 
 */
+
+#define INCLUDE_VERMAGIC
+
 #include <linux/export.h>
 #include <linux/extable.h>
 #include <linux/moduleloader.h>
@@ -419,7 +422,7 @@ static bool each_symbol_in_section(const struct symsearch *arr,
 }
 
 /* Returns true as soon as fn returns true, otherwise false. */
-bool each_symbol_section(bool (*fn)(const struct symsearch *arr,
+static bool each_symbol_section(bool (*fn)(const struct symsearch *arr,
                                    struct module *owner,
                                    void *data),
                         void *data)
@@ -481,7 +484,6 @@ bool each_symbol_section(bool (*fn)(const struct symsearch *arr,
        }
        return false;
 }
-EXPORT_SYMBOL_GPL(each_symbol_section);
 
 struct find_symbol_arg {
        /* Input */
@@ -493,6 +495,7 @@ struct find_symbol_arg {
        struct module *owner;
        const s32 *crc;
        const struct kernel_symbol *sym;
+       enum mod_license license;
 };
 
 static bool check_exported_symbol(const struct symsearch *syms,
@@ -502,9 +505,9 @@ static bool check_exported_symbol(const struct symsearch *syms,
        struct find_symbol_arg *fsa = data;
 
        if (!fsa->gplok) {
-               if (syms->licence == GPL_ONLY)
+               if (syms->license == GPL_ONLY)
                        return false;
-               if (syms->licence == WILL_BE_GPL_ONLY && fsa->warn) {
+               if (syms->license == WILL_BE_GPL_ONLY && fsa->warn) {
                        pr_warn("Symbol %s is being used by a non-GPL module, "
                                "which will not be allowed in the future\n",
                                fsa->name);
@@ -526,6 +529,7 @@ static bool check_exported_symbol(const struct symsearch *syms,
        fsa->owner = owner;
        fsa->crc = symversion(syms->crcs, symnum);
        fsa->sym = &syms->start[symnum];
+       fsa->license = syms->license;
        return true;
 }
 
@@ -582,9 +586,10 @@ static bool find_exported_symbol_in_section(const struct symsearch *syms,
 
 /* Find an exported symbol and return it, along with, (optional) crc and
  * (optional) module which owns it.  Needs preempt disabled or module_mutex. */
-const struct kernel_symbol *find_symbol(const char *name,
+static const struct kernel_symbol *find_symbol(const char *name,
                                        struct module **owner,
                                        const s32 **crc,
+                                       enum mod_license *license,
                                        bool gplok,
                                        bool warn)
 {
@@ -599,13 +604,14 @@ const struct kernel_symbol *find_symbol(const char *name,
                        *owner = fsa.owner;
                if (crc)
                        *crc = fsa.crc;
+               if (license)
+                       *license = fsa.license;
                return fsa.sym;
        }
 
        pr_debug("Failed to find symbol %s\n", name);
        return NULL;
 }
-EXPORT_SYMBOL_GPL(find_symbol);
 
 /*
  * Search for module by name: must hold module_mutex (or preempt disabled
@@ -866,7 +872,7 @@ static int add_module_usage(struct module *a, struct module *b)
 }
 
 /* Module a uses b: caller needs module_mutex() */
-int ref_module(struct module *a, struct module *b)
+static int ref_module(struct module *a, struct module *b)
 {
        int err;
 
@@ -885,7 +891,6 @@ int ref_module(struct module *a, struct module *b)
        }
        return 0;
 }
-EXPORT_SYMBOL_GPL(ref_module);
 
 /* Clear the unload stuff of the module. */
 static void module_unload_free(struct module *mod)
@@ -1074,7 +1079,7 @@ void __symbol_put(const char *symbol)
        struct module *owner;
 
        preempt_disable();
-       if (!find_symbol(symbol, &owner, NULL, true, false))
+       if (!find_symbol(symbol, &owner, NULL, NULL, true, false))
                BUG();
        module_put(owner);
        preempt_enable();
@@ -1166,11 +1171,10 @@ static inline void module_unload_free(struct module *mod)
 {
 }
 
-int ref_module(struct module *a, struct module *b)
+static int ref_module(struct module *a, struct module *b)
 {
        return strong_try_module_get(b);
 }
-EXPORT_SYMBOL_GPL(ref_module);
 
 static inline int module_unload_init(struct module *mod)
 {
@@ -1353,7 +1357,7 @@ static inline int check_modstruct_version(const struct load_info *info,
         * locking is necessary -- use preempt_disable() to placate lockdep.
         */
        preempt_disable();
-       if (!find_symbol("module_layout", NULL, &crc, true, false)) {
+       if (!find_symbol("module_layout", NULL, &crc, NULL, true, false)) {
                preempt_enable();
                BUG();
        }
@@ -1427,6 +1431,24 @@ static int verify_namespace_is_imported(const struct load_info *info,
        return 0;
 }
 
+static bool inherit_taint(struct module *mod, struct module *owner)
+{
+       if (!owner || !test_bit(TAINT_PROPRIETARY_MODULE, &owner->taints))
+               return true;
+
+       if (mod->using_gplonly_symbols) {
+               pr_err("%s: module using GPL-only symbols uses symbols from proprietary module %s.\n",
+                       mod->name, owner->name);
+               return false;
+       }
+
+       if (!test_bit(TAINT_PROPRIETARY_MODULE, &mod->taints)) {
+               pr_warn("%s: module uses symbols from proprietary module %s, inheriting taint.\n",
+                       mod->name, owner->name);
+               set_bit(TAINT_PROPRIETARY_MODULE, &mod->taints);
+       }
+       return true;
+}
 
 /* Resolve a symbol for this module.  I.e. if we find one, record usage. */
 static const struct kernel_symbol *resolve_symbol(struct module *mod,
@@ -1437,6 +1459,7 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
        struct module *owner;
        const struct kernel_symbol *sym;
        const s32 *crc;
+       enum mod_license license;
        int err;
 
        /*
@@ -1446,11 +1469,19 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
         */
        sched_annotate_sleep();
        mutex_lock(&module_mutex);
-       sym = find_symbol(name, &owner, &crc,
+       sym = find_symbol(name, &owner, &crc, &license,
                          !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true);
        if (!sym)
                goto unlock;
 
+       if (license == GPL_ONLY)
+               mod->using_gplonly_symbols = true;
+
+       if (!inherit_taint(mod, owner)) {
+               sym = NULL;
+               goto getname;
+       }
+
        if (!check_version(info, name, mod, crc)) {
                sym = ERR_PTR(-EINVAL);
                goto getname;
@@ -1507,8 +1538,7 @@ static inline bool sect_empty(const Elf_Shdr *sect)
 }
 
 struct module_sect_attr {
-       struct module_attribute mattr;
-       char *name;
+       struct bin_attribute battr;
        unsigned long address;
 };
 
@@ -1518,13 +1548,34 @@ struct module_sect_attrs {
        struct module_sect_attr attrs[];
 };
 
-static ssize_t module_sect_show(struct module_attribute *mattr,
-                               struct module_kobject *mk, char *buf)
+#define MODULE_SECT_READ_SIZE (3 /* "0x", "\n" */ + (BITS_PER_LONG / 4))
+static ssize_t module_sect_read(struct file *file, struct kobject *kobj,
+                               struct bin_attribute *battr,
+                               char *buf, loff_t pos, size_t count)
 {
        struct module_sect_attr *sattr =
-               container_of(mattr, struct module_sect_attr, mattr);
-       return sprintf(buf, "0x%px\n", kptr_restrict < 2 ?
-                      (void *)sattr->address : NULL);
+               container_of(battr, struct module_sect_attr, battr);
+       char bounce[MODULE_SECT_READ_SIZE + 1];
+       size_t wrote;
+
+       if (pos != 0)
+               return -EINVAL;
+
+       /*
+        * Since we're a binary read handler, we must account for the
+        * trailing NUL byte that sprintf will write: if "buf" is
+        * too small to hold the NUL, or the NUL is exactly the last
+        * byte, the read will look like it got truncated by one byte.
+        * Since there is no way to ask sprintf nicely to not write
+        * the NUL, we have to use a bounce buffer.
+        */
+       wrote = scnprintf(bounce, sizeof(bounce), "0x%px\n",
+                        kallsyms_show_value(file->f_cred)
+                               ? (void *)sattr->address : NULL);
+       count = min(count, wrote);
+       memcpy(buf, bounce, count);
+
+       return count;
 }
 
 static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
@@ -1532,7 +1583,7 @@ static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
        unsigned int section;
 
        for (section = 0; section < sect_attrs->nsections; section++)
-               kfree(sect_attrs->attrs[section].name);
+               kfree(sect_attrs->attrs[section].battr.attr.name);
        kfree(sect_attrs);
 }
 
@@ -1541,42 +1592,41 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info)
        unsigned int nloaded = 0, i, size[2];
        struct module_sect_attrs *sect_attrs;
        struct module_sect_attr *sattr;
-       struct attribute **gattr;
+       struct bin_attribute **gattr;
 
        /* Count loaded sections and allocate structures */
        for (i = 0; i < info->hdr->e_shnum; i++)
                if (!sect_empty(&info->sechdrs[i]))
                        nloaded++;
        size[0] = ALIGN(struct_size(sect_attrs, attrs, nloaded),
-                       sizeof(sect_attrs->grp.attrs[0]));
-       size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.attrs[0]);
+                       sizeof(sect_attrs->grp.bin_attrs[0]));
+       size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.bin_attrs[0]);
        sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
        if (sect_attrs == NULL)
                return;
 
        /* Setup section attributes. */
        sect_attrs->grp.name = "sections";
-       sect_attrs->grp.attrs = (void *)sect_attrs + size[0];
+       sect_attrs->grp.bin_attrs = (void *)sect_attrs + size[0];
 
        sect_attrs->nsections = 0;
        sattr = &sect_attrs->attrs[0];
-       gattr = &sect_attrs->grp.attrs[0];
+       gattr = &sect_attrs->grp.bin_attrs[0];
        for (i = 0; i < info->hdr->e_shnum; i++) {
                Elf_Shdr *sec = &info->sechdrs[i];
                if (sect_empty(sec))
                        continue;
+               sysfs_bin_attr_init(&sattr->battr);
                sattr->address = sec->sh_addr;
-               sattr->name = kstrdup(info->secstrings + sec->sh_name,
-                                       GFP_KERNEL);
-               if (sattr->name == NULL)
+               sattr->battr.attr.name =
+                       kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL);
+               if (sattr->battr.attr.name == NULL)
                        goto out;
                sect_attrs->nsections++;
-               sysfs_attr_init(&sattr->mattr.attr);
-               sattr->mattr.show = module_sect_show;
-               sattr->mattr.store = NULL;
-               sattr->mattr.attr.name = sattr->name;
-               sattr->mattr.attr.mode = S_IRUSR;
-               *(gattr++) = &(sattr++)->mattr.attr;
+               sattr->battr.read = module_sect_read;
+               sattr->battr.size = MODULE_SECT_READ_SIZE;
+               sattr->battr.attr.mode = 0400;
+               *(gattr++) = &(sattr++)->battr;
        }
        *gattr = NULL;
 
@@ -1666,7 +1716,7 @@ static void add_notes_attrs(struct module *mod, const struct load_info *info)
                        continue;
                if (info->sechdrs[i].sh_type == SHT_NOTE) {
                        sysfs_bin_attr_init(nattr);
-                       nattr->attr.name = mod->sect_attrs->attrs[loaded].name;
+                       nattr->attr.name = mod->sect_attrs->attrs[loaded].battr.attr.name;
                        nattr->attr.mode = S_IRUGO;
                        nattr->size = info->sechdrs[i].sh_size;
                        nattr->private = (void *) info->sechdrs[i].sh_addr;
@@ -1943,7 +1993,6 @@ static void mod_sysfs_teardown(struct module *mod)
        mod_sysfs_fini(mod);
 }
 
-#ifdef CONFIG_ARCH_HAS_STRICT_MODULE_RWX
 /*
  * LKM RO/NX protection: protect module's text/ro-data
  * from modification and any data from execution.
@@ -1957,6 +2006,14 @@ static void mod_sysfs_teardown(struct module *mod)
  *
  * These values are always page-aligned (as is base)
  */
+
+/*
+ * Since some arches are moving towards PAGE_KERNEL module allocations instead
+ * of PAGE_KERNEL_EXEC, keep frob_text() and module_enable_x() outside of the
+ * CONFIG_STRICT_MODULE_RWX block below because they are needed regardless of
+ * whether we are strict.
+ */
+#ifdef CONFIG_ARCH_HAS_STRICT_MODULE_RWX
 static void frob_text(const struct module_layout *layout,
                      int (*set_memory)(unsigned long start, int num_pages))
 {
@@ -1966,6 +2023,15 @@ static void frob_text(const struct module_layout *layout,
                   layout->text_size >> PAGE_SHIFT);
 }
 
+static void module_enable_x(const struct module *mod)
+{
+       frob_text(&mod->core_layout, set_memory_x);
+       frob_text(&mod->init_layout, set_memory_x);
+}
+#else /* !CONFIG_ARCH_HAS_STRICT_MODULE_RWX */
+static void module_enable_x(const struct module *mod) { }
+#endif /* CONFIG_ARCH_HAS_STRICT_MODULE_RWX */
+
 #ifdef CONFIG_STRICT_MODULE_RWX
 static void frob_rodata(const struct module_layout *layout,
                        int (*set_memory)(unsigned long start, int num_pages))
@@ -1997,20 +2063,7 @@ static void frob_writable_data(const struct module_layout *layout,
                   (layout->size - layout->ro_after_init_size) >> PAGE_SHIFT);
 }
 
-/* livepatching wants to disable read-only so it can frob module. */
-void module_disable_ro(const struct module *mod)
-{
-       if (!rodata_enabled)
-               return;
-
-       frob_text(&mod->core_layout, set_memory_rw);
-       frob_rodata(&mod->core_layout, set_memory_rw);
-       frob_ro_after_init(&mod->core_layout, set_memory_rw);
-       frob_text(&mod->init_layout, set_memory_rw);
-       frob_rodata(&mod->init_layout, set_memory_rw);
-}
-
-void module_enable_ro(const struct module *mod, bool after_init)
+static void module_enable_ro(const struct module *mod, bool after_init)
 {
        if (!rodata_enabled)
                return;
@@ -2036,19 +2089,29 @@ static void module_enable_nx(const struct module *mod)
        frob_writable_data(&mod->init_layout, set_memory_nx);
 }
 
+static int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
+                                      char *secstrings, struct module *mod)
+{
+       const unsigned long shf_wx = SHF_WRITE|SHF_EXECINSTR;
+       int i;
+
+       for (i = 0; i < hdr->e_shnum; i++) {
+               if ((sechdrs[i].sh_flags & shf_wx) == shf_wx)
+                       return -ENOEXEC;
+       }
+
+       return 0;
+}
+
 #else /* !CONFIG_STRICT_MODULE_RWX */
 static void module_enable_nx(const struct module *mod) { }
-#endif /*  CONFIG_STRICT_MODULE_RWX */
-static void module_enable_x(const struct module *mod)
+static void module_enable_ro(const struct module *mod, bool after_init) {}
+static int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
+                                      char *secstrings, struct module *mod)
 {
-       frob_text(&mod->core_layout, set_memory_x);
-       frob_text(&mod->init_layout, set_memory_x);
+       return 0;
 }
-#else /* !CONFIG_ARCH_HAS_STRICT_MODULE_RWX */
-static void module_enable_nx(const struct module *mod) { }
-static void module_enable_x(const struct module *mod) { }
-#endif /* CONFIG_ARCH_HAS_STRICT_MODULE_RWX */
-
+#endif /*  CONFIG_STRICT_MODULE_RWX */
 
 #ifdef CONFIG_LIVEPATCH
 /*
@@ -2201,7 +2264,7 @@ void *__symbol_get(const char *symbol)
        const struct kernel_symbol *sym;
 
        preempt_disable();
-       sym = find_symbol(symbol, &owner, NULL, true, true);
+       sym = find_symbol(symbol, &owner, NULL, NULL, true, true);
        if (sym && strong_try_module_get(owner))
                sym = NULL;
        preempt_enable();
@@ -2237,7 +2300,7 @@ static int verify_exported_symbols(struct module *mod)
        for (i = 0; i < ARRAY_SIZE(arr); i++) {
                for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) {
                        if (find_symbol(kernel_symbol_name(s), &owner, NULL,
-                                       true, false)) {
+                                       NULL, true, false)) {
                                pr_err("%s: exports duplicate symbol %s"
                                       " (owned by %s)\n",
                                       mod->name, kernel_symbol_name(s),
@@ -2334,11 +2397,13 @@ static int apply_relocations(struct module *mod, const struct load_info *info)
                if (!(info->sechdrs[infosec].sh_flags & SHF_ALLOC))
                        continue;
 
-               /* Livepatch relocation sections are applied by livepatch */
                if (info->sechdrs[i].sh_flags & SHF_RELA_LIVEPATCH)
-                       continue;
-
-               if (info->sechdrs[i].sh_type == SHT_REL)
+                       err = klp_apply_section_relocs(mod, info->sechdrs,
+                                                      info->secstrings,
+                                                      info->strtab,
+                                                      info->index.sym, i,
+                                                      NULL);
+               else if (info->sechdrs[i].sh_type == SHT_REL)
                        err = apply_relocate(info->sechdrs, info->strtab,
                                             info->index.sym, i, mod);
                else if (info->sechdrs[i].sh_type == SHT_RELA)
@@ -2400,7 +2465,7 @@ static void layout_sections(struct module *mod, struct load_info *info)
                        if ((s->sh_flags & masks[m][0]) != masks[m][0]
                            || (s->sh_flags & masks[m][1])
                            || s->sh_entsize != ~0UL
-                           || strstarts(sname, ".init"))
+                           || module_init_section(sname))
                                continue;
                        s->sh_entsize = get_offset(mod, &mod->core_layout.size, s, i);
                        pr_debug("\t%s\n", sname);
@@ -2433,7 +2498,7 @@ static void layout_sections(struct module *mod, struct load_info *info)
                        if ((s->sh_flags & masks[m][0]) != masks[m][0]
                            || (s->sh_flags & masks[m][1])
                            || s->sh_entsize != ~0UL
-                           || !strstarts(sname, ".init"))
+                           || !module_init_section(sname))
                                continue;
                        s->sh_entsize = (get_offset(mod, &mod->init_layout.size, s, i)
                                         | INIT_OFFSET_MASK);
@@ -2765,7 +2830,14 @@ static void dynamic_debug_remove(struct module *mod, struct _ddebug *debug)
 
 void * __weak module_alloc(unsigned long size)
 {
-       return vmalloc_exec(size);
+       return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,
+                       GFP_KERNEL, PAGE_KERNEL_EXEC, VM_FLUSH_RESET_PERMS,
+                       NUMA_NO_NODE, __builtin_return_address(0));
+}
+
+bool __weak module_init_section(const char *name)
+{
+       return strstarts(name, ".init");
 }
 
 bool __weak module_exit_section(const char *name)
@@ -2946,8 +3018,7 @@ static int copy_module_from_user(const void __user *umod, unsigned long len,
                return err;
 
        /* Suck in entire file: we'll want most of it. */
-       info->hdr = __vmalloc(info->len,
-                       GFP_KERNEL | __GFP_NOWARN, PAGE_KERNEL);
+       info->hdr = __vmalloc(info->len, GFP_KERNEL | __GFP_NOWARN);
        if (!info->hdr)
                return -ENOMEM;
 
@@ -3150,6 +3221,9 @@ static int find_module_sections(struct module *mod, struct load_info *info)
        }
 #endif
 
+       mod->noinstr_text_start = section_objs(info, ".noinstr.text", 1,
+                                               &mod->noinstr_text_size);
+
 #ifdef CONFIG_TRACEPOINTS
        mod->tracepoints_ptrs = section_objs(info, "__tracepoints_ptrs",
                                             sizeof(*mod->tracepoints_ptrs),
@@ -3193,6 +3267,13 @@ static int find_module_sections(struct module *mod, struct load_info *info)
        mod->ei_funcs = section_objs(info, "_error_injection_whitelist",
                                            sizeof(*mod->ei_funcs),
                                            &mod->num_ei_funcs);
+#endif
+#ifdef CONFIG_KPROBES
+       mod->kprobes_text_start = section_objs(info, ".kprobes.text", 1,
+                                               &mod->kprobes_text_size);
+       mod->kprobe_blacklist = section_objs(info, "_kprobe_blacklist",
+                                               sizeof(unsigned long),
+                                               &mod->num_kprobe_blacklist);
 #endif
        mod->extable = section_objs(info, "__ex_table",
                                    sizeof(*mod->extable), &mod->num_exentries);
@@ -3200,7 +3281,7 @@ static int find_module_sections(struct module *mod, struct load_info *info)
        if (section_addr(info, "__obsparm"))
                pr_warn("%s: Ignoring obsolete parameters\n", mod->name);
 
-       info->debug = section_objs(info, "__verbose",
+       info->debug = section_objs(info, "__dyndbg",
                                   sizeof(*info->debug), &info->num_debug);
 
        return 0;
@@ -3312,12 +3393,6 @@ static int check_module_license_and_versions(struct module *mod)
 
 static void flush_module_icache(const struct module *mod)
 {
-       mm_segment_t old_fs;
-
-       /* flush the icache in correct context */
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-
        /*
         * Flush the instruction cache, since we've played with text.
         * Do it before processing of module parameters, so the module
@@ -3329,8 +3404,6 @@ static void flush_module_icache(const struct module *mod)
                                   + mod->init_layout.size);
        flush_icache_range((unsigned long)mod->core_layout.base,
                           (unsigned long)mod->core_layout.base + mod->core_layout.size);
-
-       set_fs(old_fs);
 }
 
 int __weak module_frob_arch_sections(Elf_Ehdr *hdr,
@@ -3378,6 +3451,11 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
        if (err < 0)
                return ERR_PTR(err);
 
+       err = module_enforce_rwx_sections(info->hdr, info->sechdrs,
+                                         info->secstrings, info->mod);
+       if (err < 0)
+               return ERR_PTR(err);
+
        /* We will do a special allocation for per-cpu sections later. */
        info->sechdrs[info->index.pcpu].sh_flags &= ~(unsigned long)SHF_ALLOC;
 
@@ -4348,7 +4426,7 @@ static int modules_open(struct inode *inode, struct file *file)
 
        if (!err) {
                struct seq_file *m = file->private_data;
-               m->private = kallsyms_show_value() ? NULL : (void *)8ul;
+               m->private = kallsyms_show_value(file->f_cred) ? NULL : (void *)8ul;
        }
 
        return err;
@@ -4439,7 +4517,6 @@ struct module *__module_address(unsigned long addr)
        }
        return mod;
 }
-EXPORT_SYMBOL_GPL(__module_address);
 
 /*
  * is_module_text_address - is this address inside module code?
@@ -4478,7 +4555,6 @@ struct module *__module_text_address(unsigned long addr)
        }
        return mod;
 }
-EXPORT_SYMBOL_GPL(__module_text_address);
 
 /* Don't grab lock, we're oopsing. */
 void print_modules(void)