All of lore.kernel.org
 help / color / mirror / Atom feed
From: Martijn Coenen <maco@android.com>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Martijn Coenen <maco@android.com>,
	Masahiro Yamada <yamada.masahiro@socionext.com>,
	Michal Marek <michal.lkml@markovi.net>,
	Geert Uytterhoeven <geert@linux-m68k.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
	"the arch/x86 maintainers" <x86@kernel.org>,
	Alan Stern <stern@rowland.harvard.edu>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Oliver Neukum <oneukum@suse.com>, Arnd Bergmann <arnd@arndb.de>,
	Jessica Yu <jeyu@kernel.org>, Stephen Boyd <sboyd@codeaurora.org>,
	Philippe Ombredanne <pombredanne@nexb.com>,
	Kate Stewart <kstewart@linuxfoundation.org>,
	Sam Ravnborg <sam@ravnborg.org>,
	linux-kbuild@vger.kernel.org,
	linux-m68k <linux-m68k@lists.linux-m68k.org>,
	USB list <linux-usb@vger.kernel.org>,
	USB Storage list <usb-storage@lists.one-eyed-alien.net>,
	linux-scsi@vger.kernel.org,
	Linux-Arch <linux-arch@vger.kernel.org>,
	Martijn Coenen <maco@google.com>,
	Sandeep Patil <sspatil@google.com>,
	Iliyan Malchev <malchev@google.com>,
	Joel Fernandes <joelaf@google.com>
Subject: Re: [PATCH 2/6] module: add support for symbol namespaces.
Date: Tue, 24 Jul 2018 09:56:47 +0200	[thread overview]
Message-ID: <CAB0TPYEOVHcFGFLTjVvk7R0VSgSnXZRi1PjSYXONJSjqd4NewQ@mail.gmail.com> (raw)
In-Reply-To: <20180716122125.175792-3-maco@android.com>

I did find an issue with my approach:

On Mon, Jul 16, 2018 at 2:21 PM, Martijn Coenen <maco@android.com> wrote:
> The ELF symbols are renamed to include the namespace with an asm label;
> for example, symbol 'usb_stor_suspend' in namespace USB_STORAGE becomes
> 'usb_stor_suspend.USB_STORAGE'.  This allows modpost to do namespace
> checking, without having to go through all the effort of parsing ELF and
> reloction records just to get to the struct kernel_symbols.

depmod doesn't like this: if namespaced symbols are built-in to the
kernel, they will appear as 'symbol.NS' in the symbol table, whereas
modules using those symbols just depend on 'symbol'. This will cause
depmod to warn about unknown symbols. I didn't find this previously
because all the exports/imports I tested were done from modules
themselves.

One way to deal with it is to change depmod, but it looks like it
hasn't been changed in ages, and it would also introduce a dependency
on userspaces to update it to avoid these warnings. So, we'd have to
encode the symbol namespace information in another way for modpost to
use. I could just write a separate post-processing tool (much like
genksyms), or perhaps encode the information in a discardable section.
Any other suggestions welcome.

Thanks,
Martijn

>
> On x86_64 I saw no difference in binary size (compression), but at
> runtime this will require a word of memory per export to hold the
> namespace. An alternative could be to store namespaced symbols in their
> own section and use a separate 'struct namespaced_kernel_symbol' for
> that section, at the cost of making the module loader more complex.
>
> Signed-off-by: Martijn Coenen <maco@android.com>
> ---
>  include/asm-generic/export.h |  2 +-
>  include/linux/export.h       | 83 +++++++++++++++++++++++++++---------
>  include/linux/module.h       | 13 ++++++
>  kernel/module.c              | 79 ++++++++++++++++++++++++++++++++++
>  4 files changed, 156 insertions(+), 21 deletions(-)
>
> diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h
> index 68efb950a918..4c3d1afb702f 100644
> --- a/include/asm-generic/export.h
> +++ b/include/asm-generic/export.h
> @@ -29,7 +29,7 @@
>         .section ___ksymtab\sec+\name,"a"
>         .balign KSYM_ALIGN
>  __ksymtab_\name:
> -       __put \val, __kstrtab_\name
> +       __put \val, __kstrtab_\name, 0
>         .previous
>         .section __ksymtab_strings,"a"
>  __kstrtab_\name:
> diff --git a/include/linux/export.h b/include/linux/export.h
> index ad6b8e697b27..9f6e70eeb85f 100644
> --- a/include/linux/export.h
> +++ b/include/linux/export.h
> @@ -22,6 +22,11 @@ struct kernel_symbol
>  {
>         unsigned long value;
>         const char *name;
> +       const char *namespace;
> +};
> +
> +struct namespace_import {
> +       const char *namespace;
>  };
>
>  #ifdef MODULE
> @@ -54,18 +59,28 @@ extern struct module __this_module;
>  #define __CRC_SYMBOL(sym, sec)
>  #endif
>
> +#define NS_SEPARATOR "."
> +
> +#define MODULE_IMPORT_NS(ns)                                           \
> +       static const struct namespace_import __knsimport_##ns           \
> +       asm("__knsimport_" #ns)                                         \
> +       __attribute__((section("__knsimport"), used))                   \
> +       = { #ns }
> +
>  /* For every exported symbol, place a struct in the __ksymtab section */
> -#define ___EXPORT_SYMBOL(sym, sec)                                     \
> +#define ___EXPORT_SYMBOL(sym, sec, ns, nspost, nspost2)                        \
>         extern typeof(sym) sym;                                         \
>         __CRC_SYMBOL(sym, sec)                                          \
> -       static const char __kstrtab_##sym[]                             \
> +       static const char __kstrtab_##sym##nspost[]                     \
>         __attribute__((section("__ksymtab_strings"), aligned(1)))       \
>         = #sym;                                                         \
> -       static const struct kernel_symbol __ksymtab_##sym               \
> +       static const struct kernel_symbol __ksymtab_##sym##nspost       \
> +       asm("__ksymtab_" #sym nspost2)                                  \
>         __used                                                          \
> -       __attribute__((section("___ksymtab" sec "+" #sym), used))       \
> +       __attribute__((section("___ksymtab" sec "+" #sym #nspost)))     \
> +       __attribute__((used))                                           \
>         __attribute__((aligned(sizeof(void *))))                        \
> -       = { (unsigned long)&sym, __kstrtab_##sym }
> +       = { (unsigned long)&sym, __kstrtab_##sym##nspost, ns }
>
>  #if defined(__KSYM_DEPS__)
>
> @@ -76,52 +91,80 @@ extern struct module __this_module;
>   * system filters out from the preprocessor output (see ksym_dep_filter
>   * in scripts/Kbuild.include).
>   */
> -#define __EXPORT_SYMBOL(sym, sec)      === __KSYM_##sym ===
> +#define __EXPORT_SYMBOL(sym, sec, ns, nspost, nspost2) === __KSYM_##sym ===
>
>  #elif defined(CONFIG_TRIM_UNUSED_KSYMS)
>
>  #include <generated/autoksyms.h>
>
> -#define __EXPORT_SYMBOL(sym, sec)                              \
> -       __cond_export_sym(sym, sec, __is_defined(__KSYM_##sym))
> -#define __cond_export_sym(sym, sec, conf)                      \
> -       ___cond_export_sym(sym, sec, conf)
> -#define ___cond_export_sym(sym, sec, enabled)                  \
> -       __cond_export_sym_##enabled(sym, sec)
> -#define __cond_export_sym_1(sym, sec) ___EXPORT_SYMBOL(sym, sec)
> -#define __cond_export_sym_0(sym, sec) /* nothing */
> +#define __EXPORT_SYMBOL(sym, sec, ns, nspost, nspost2)                 \
> +       __cond_export_sym(sym, sec, ns, nspost, nspost2,                \
> +                         __is_defined(__KSYM_##sym))
> +#define __cond_export_sym(sym, sec, ns, nspost, nspost2, conf)         \
> +       ___cond_export_sym(sym, sec, ns, nspost, nspost2, conf)
> +#define ___cond_export_sym(sym, sec, ns, nspost, nspost2, enabled)     \
> +       __cond_export_sym_##enabled(sym, sec, ns, nspost, nspost2)
> +#define __cond_export_sym_1(sym, sec, ns, nspost, nspost2)             \
> +       ___EXPORT_SYMBOL(sym, sec, ns, nspost, nspost2)
> +#define __cond_export_sym_0(sym, sec, ns, nspost, nspost2) /* nothing */
>
>  #else
>  #define __EXPORT_SYMBOL ___EXPORT_SYMBOL
>  #endif
>
>  #define EXPORT_SYMBOL(sym)                                     \
> -       __EXPORT_SYMBOL(sym, "")
> +       __EXPORT_SYMBOL(sym, "", NULL, ,)
>
>  #define EXPORT_SYMBOL_GPL(sym)                                 \
> -       __EXPORT_SYMBOL(sym, "_gpl")
> +       __EXPORT_SYMBOL(sym, "_gpl", NULL, ,)
>
>  #define EXPORT_SYMBOL_GPL_FUTURE(sym)                          \
> -       __EXPORT_SYMBOL(sym, "_gpl_future")
> +       __EXPORT_SYMBOL(sym, "_gpl_future", NULL, ,)
> +
> +#define EXPORT_SYMBOL_NS(sym, ns)                               \
> +       __EXPORT_SYMBOL(sym, "", #ns, __##ns, NS_SEPARATOR #ns)
> +
> +#define EXPORT_SYMBOL_NS_GPL(sym, ns)                               \
> +       __EXPORT_SYMBOL(sym, "_gpl", #ns, __##ns, NS_SEPARATOR #ns)
>
>  #ifdef CONFIG_UNUSED_SYMBOLS
> -#define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused")
> -#define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl")
> +#define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused", , ,)
> +#define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl", , ,)
>  #else
>  #define EXPORT_UNUSED_SYMBOL(sym)
>  #define EXPORT_UNUSED_SYMBOL_GPL(sym)
>  #endif
>
> -#endif /* __GENKSYMS__ */
> +#endif /* __KERNEL__ && !__GENKSYMS__ */
> +
> +#if defined(__GENKSYMS__)
> +/*
> + * When we're running genksyms, ignore the namespace and make the _NS
> + * variants look like the normal ones. There are two reasons for this:
> + * 1) In the normal definition of EXPORT_SYMBOL_NS, the 'ns' macro
> + *    argument is itself not expanded because it's always tokenized or
> + *    concatenated; but when running genksyms, a blank definition of the
> + *    macro does allow the argument to be expanded; if a namespace
> + *    happens to collide with a #define, this can cause issues.
> + * 2) There's no need to modify genksyms to deal with the _NS variants
> + */
> +#define EXPORT_SYMBOL_NS(sym, ns)                              \
> +       EXPORT_SYMBOL(sym)
> +#define EXPORT_SYMBOL_NS_GPL(sym, ns)                          \
> +       EXPORT_SYMBOL_GPL(sym)
> +#endif
>
>  #else /* !CONFIG_MODULES... */
>
>  #define EXPORT_SYMBOL(sym)
> +#define EXPORT_SYMBOL_NS(sym, ns)
> +#define EXPORT_SYMBOL_NS_GPL(sym, ns)
>  #define EXPORT_SYMBOL_GPL(sym)
>  #define EXPORT_SYMBOL_GPL_FUTURE(sym)
>  #define EXPORT_UNUSED_SYMBOL(sym)
>  #define EXPORT_UNUSED_SYMBOL_GPL(sym)
>
> +#define MODULE_IMPORT_NS(ns)
>  #endif /* CONFIG_MODULES */
>  #endif /* !__ASSEMBLY__ */
>
> diff --git a/include/linux/module.h b/include/linux/module.h
> index d44df9b2c131..afab4e8fa188 100644
> --- a/include/linux/module.h
> +++ b/include/linux/module.h
> @@ -268,6 +268,12 @@ void *__symbol_get(const char *symbol);
>  void *__symbol_get_gpl(const char *symbol);
>  #define symbol_get(x) ((typeof(&x))(__symbol_get(VMLINUX_SYMBOL_STR(x))))
>
> +/* namespace dependencies of the module */
> +struct module_ns_dep {
> +       struct list_head ns_dep;
> +       const char *namespace;
> +};
> +
>  /* modules using other modules: kdb wants to see this. */
>  struct module_use {
>         struct list_head source_list;
> @@ -359,6 +365,13 @@ struct module {
>         const struct kernel_symbol *gpl_syms;
>         const s32 *gpl_crcs;
>
> +       /* Namespace imports */
> +       unsigned int num_ns_imports;
> +       const struct namespace_import *ns_imports;
> +
> +       /* Namespace dependencies */
> +       struct list_head ns_dependencies;
> +
>  #ifdef CONFIG_UNUSED_SYMBOLS
>         /* unused exported symbols. */
>         const struct kernel_symbol *unused_syms;
> diff --git a/kernel/module.c b/kernel/module.c
> index f475f30eed8c..63de0fe849f9 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -1166,6 +1166,51 @@ static inline int module_unload_init(struct module *mod)
>  }
>  #endif /* CONFIG_MODULE_UNLOAD */
>
> +static bool module_has_ns_dependency(struct module *mod, const char *ns)
> +{
> +       struct module_ns_dep *ns_dep;
> +
> +       list_for_each_entry(ns_dep, &mod->ns_dependencies, ns_dep) {
> +               if (strcmp(ns_dep->namespace, ns) == 0)
> +                       return true;
> +       }
> +
> +       return false;
> +}
> +
> +static int add_module_ns_dependency(struct module *mod, const char *ns)
> +{
> +       struct module_ns_dep *ns_dep;
> +
> +       if (module_has_ns_dependency(mod, ns))
> +               return 0;
> +
> +       ns_dep = kmalloc(sizeof(*ns_dep), GFP_ATOMIC);
> +       if (!ns_dep)
> +               return -ENOMEM;
> +
> +       ns_dep->namespace = ns;
> +
> +       list_add(&ns_dep->ns_dep, &mod->ns_dependencies);
> +
> +       return 0;
> +}
> +
> +static bool module_imports_ns(struct module *mod, const char *ns)
> +{
> +       size_t i;
> +
> +       if (!ns)
> +               return true;
> +
> +       for (i = 0; i < mod->num_ns_imports; ++i) {
> +               if (!strcmp(mod->ns_imports[i].namespace, ns))
> +                       return true;
> +       }
> +
> +       return false;
> +}
> +
>  static size_t module_flags_taint(struct module *mod, char *buf)
>  {
>         size_t l = 0;
> @@ -1415,6 +1460,18 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
>                 goto getname;
>         }
>
> +       /*
> +        * We can't yet verify that the module actually imports this
> +        * namespace, because the imports themselves are only available
> +        * after processing the symbol table and doing relocation; so
> +        * instead just record the dependency and check later.
> +        */
> +       if (sym->namespace) {
> +               err = add_module_ns_dependency(mod, sym->namespace);
> +               if (err)
> +                       sym = ERR_PTR(err);
> +       }
> +
>  getname:
>         /* We must make copy under the lock if we failed to get ref. */
>         strncpy(ownername, module_name(owner), MODULE_NAME_LEN);
> @@ -3061,6 +3118,11 @@ static int find_module_sections(struct module *mod, struct load_info *info)
>                                      sizeof(*mod->gpl_syms),
>                                      &mod->num_gpl_syms);
>         mod->gpl_crcs = section_addr(info, "__kcrctab_gpl");
> +
> +       mod->ns_imports = section_objs(info, "__knsimport",
> +                                      sizeof(*mod->ns_imports),
> +                                      &mod->num_ns_imports);
> +
>         mod->gpl_future_syms = section_objs(info,
>                                             "__ksymtab_gpl_future",
>                                             sizeof(*mod->gpl_future_syms),
> @@ -3381,6 +3443,19 @@ static int post_relocation(struct module *mod, const struct load_info *info)
>         return module_finalize(info->hdr, info->sechdrs, mod);
>  }
>
> +static void verify_namespace_dependencies(struct module *mod)
> +{
> +       struct module_ns_dep *ns_dep;
> +
> +       list_for_each_entry(ns_dep, &mod->ns_dependencies, ns_dep) {
> +               if (!module_imports_ns(mod, ns_dep->namespace)) {
> +                       pr_warn("%s: module uses symbols from namespace %s,"
> +                               " but does not import it.\n",
> +                               mod->name, ns_dep->namespace);
> +               }
> +       }
> +}
> +
>  /* Is this module of this name done loading?  No locks held. */
>  static bool finished_loading(const char *name)
>  {
> @@ -3682,6 +3757,8 @@ static int load_module(struct load_info *info, const char __user *uargs,
>         if (err)
>                 goto free_module;
>
> +       INIT_LIST_HEAD(&mod->ns_dependencies);
> +
>  #ifdef CONFIG_MODULE_SIG
>         mod->sig_ok = info->sig_ok;
>         if (!mod->sig_ok) {
> @@ -3730,6 +3807,8 @@ static int load_module(struct load_info *info, const char __user *uargs,
>         if (err < 0)
>                 goto free_modinfo;
>
> +       verify_namespace_dependencies(mod);
> +
>         flush_module_icache(mod);
>
>         /* Now copy in args */
> --
> 2.18.0.203.gfac676dfb9-goog
>

WARNING: multiple messages have this Message-ID (diff)
From: Martijn Coenen <maco@android.com>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Martijn Coenen <maco@android.com>,
	Masahiro Yamada <yamada.masahiro@socionext.com>,
	Michal Marek <michal.lkml@markovi.net>,
	Geert Uytterhoeven <geert@linux-m68k.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
	the arch/x86 maintainers <x86@kernel.org>,
	Alan Stern <stern@rowland.harvard.edu>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Oliver Neukum <oneukum@suse.com>, Arnd Bergmann <arnd@arndb.de>,
	Jessica Yu <jeyu@kernel.org>, Stephen Boyd <sboyd@codeaurora.org>,
	Philippe Ombredanne <pombredanne@nexb.com>,
	Kate Stewart <kstewart@linuxfoundation.org>,
	Sam Ravnborg <sam@ravnborg.org>,
	linux-kbuild@vger.kernel.org,
	linux-m68k <linux-m68k@lists.linux-m68k.org>,
	USB list <linux-usb@vger.kernel.org>,
	USB Storage list <usb-storage@lists.one-eyed-alien.net>,
	linux-scsi@vger.kernel.org,
	Linux-Arch <linux-arch@vger.kernel.org>,
	Martijn Coenen <maco@google.com>,
	Sandeep Patil <sspatil@google.com>,
	Iliyan Malchev <malchev@google.com>,
	Joel Fernandes <joelaf@google.com>
Subject: [2/6] module: add support for symbol namespaces.
Date: Tue, 24 Jul 2018 09:56:47 +0200	[thread overview]
Message-ID: <CAB0TPYEOVHcFGFLTjVvk7R0VSgSnXZRi1PjSYXONJSjqd4NewQ@mail.gmail.com> (raw)

I did find an issue with my approach:

On Mon, Jul 16, 2018 at 2:21 PM, Martijn Coenen <maco@android.com> wrote:
> The ELF symbols are renamed to include the namespace with an asm label;
> for example, symbol 'usb_stor_suspend' in namespace USB_STORAGE becomes
> 'usb_stor_suspend.USB_STORAGE'.  This allows modpost to do namespace
> checking, without having to go through all the effort of parsing ELF and
> reloction records just to get to the struct kernel_symbols.

depmod doesn't like this: if namespaced symbols are built-in to the
kernel, they will appear as 'symbol.NS' in the symbol table, whereas
modules using those symbols just depend on 'symbol'. This will cause
depmod to warn about unknown symbols. I didn't find this previously
because all the exports/imports I tested were done from modules
themselves.

One way to deal with it is to change depmod, but it looks like it
hasn't been changed in ages, and it would also introduce a dependency
on userspaces to update it to avoid these warnings. So, we'd have to
encode the symbol namespace information in another way for modpost to
use. I could just write a separate post-processing tool (much like
genksyms), or perhaps encode the information in a discardable section.
Any other suggestions welcome.

Thanks,
Martijn

>
> On x86_64 I saw no difference in binary size (compression), but at
> runtime this will require a word of memory per export to hold the
> namespace. An alternative could be to store namespaced symbols in their
> own section and use a separate 'struct namespaced_kernel_symbol' for
> that section, at the cost of making the module loader more complex.
>
> Signed-off-by: Martijn Coenen <maco@android.com>
> ---
>  include/asm-generic/export.h |  2 +-
>  include/linux/export.h       | 83 +++++++++++++++++++++++++++---------
>  include/linux/module.h       | 13 ++++++
>  kernel/module.c              | 79 ++++++++++++++++++++++++++++++++++
>  4 files changed, 156 insertions(+), 21 deletions(-)
>
> diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h
> index 68efb950a918..4c3d1afb702f 100644
> --- a/include/asm-generic/export.h
> +++ b/include/asm-generic/export.h
> @@ -29,7 +29,7 @@
>         .section ___ksymtab\sec+\name,"a"
>         .balign KSYM_ALIGN
>  __ksymtab_\name:
> -       __put \val, __kstrtab_\name
> +       __put \val, __kstrtab_\name, 0
>         .previous
>         .section __ksymtab_strings,"a"
>  __kstrtab_\name:
> diff --git a/include/linux/export.h b/include/linux/export.h
> index ad6b8e697b27..9f6e70eeb85f 100644
> --- a/include/linux/export.h
> +++ b/include/linux/export.h
> @@ -22,6 +22,11 @@ struct kernel_symbol
>  {
>         unsigned long value;
>         const char *name;
> +       const char *namespace;
> +};
> +
> +struct namespace_import {
> +       const char *namespace;
>  };
>
>  #ifdef MODULE
> @@ -54,18 +59,28 @@ extern struct module __this_module;
>  #define __CRC_SYMBOL(sym, sec)
>  #endif
>
> +#define NS_SEPARATOR "."
> +
> +#define MODULE_IMPORT_NS(ns)                                           \
> +       static const struct namespace_import __knsimport_##ns           \
> +       asm("__knsimport_" #ns)                                         \
> +       __attribute__((section("__knsimport"), used))                   \
> +       = { #ns }
> +
>  /* For every exported symbol, place a struct in the __ksymtab section */
> -#define ___EXPORT_SYMBOL(sym, sec)                                     \
> +#define ___EXPORT_SYMBOL(sym, sec, ns, nspost, nspost2)                        \
>         extern typeof(sym) sym;                                         \
>         __CRC_SYMBOL(sym, sec)                                          \
> -       static const char __kstrtab_##sym[]                             \
> +       static const char __kstrtab_##sym##nspost[]                     \
>         __attribute__((section("__ksymtab_strings"), aligned(1)))       \
>         = #sym;                                                         \
> -       static const struct kernel_symbol __ksymtab_##sym               \
> +       static const struct kernel_symbol __ksymtab_##sym##nspost       \
> +       asm("__ksymtab_" #sym nspost2)                                  \
>         __used                                                          \
> -       __attribute__((section("___ksymtab" sec "+" #sym), used))       \
> +       __attribute__((section("___ksymtab" sec "+" #sym #nspost)))     \
> +       __attribute__((used))                                           \
>         __attribute__((aligned(sizeof(void *))))                        \
> -       = { (unsigned long)&sym, __kstrtab_##sym }
> +       = { (unsigned long)&sym, __kstrtab_##sym##nspost, ns }
>
>  #if defined(__KSYM_DEPS__)
>
> @@ -76,52 +91,80 @@ extern struct module __this_module;
>   * system filters out from the preprocessor output (see ksym_dep_filter
>   * in scripts/Kbuild.include).
>   */
> -#define __EXPORT_SYMBOL(sym, sec)      === __KSYM_##sym ===
> +#define __EXPORT_SYMBOL(sym, sec, ns, nspost, nspost2) === __KSYM_##sym ===
>
>  #elif defined(CONFIG_TRIM_UNUSED_KSYMS)
>
>  #include <generated/autoksyms.h>
>
> -#define __EXPORT_SYMBOL(sym, sec)                              \
> -       __cond_export_sym(sym, sec, __is_defined(__KSYM_##sym))
> -#define __cond_export_sym(sym, sec, conf)                      \
> -       ___cond_export_sym(sym, sec, conf)
> -#define ___cond_export_sym(sym, sec, enabled)                  \
> -       __cond_export_sym_##enabled(sym, sec)
> -#define __cond_export_sym_1(sym, sec) ___EXPORT_SYMBOL(sym, sec)
> -#define __cond_export_sym_0(sym, sec) /* nothing */
> +#define __EXPORT_SYMBOL(sym, sec, ns, nspost, nspost2)                 \
> +       __cond_export_sym(sym, sec, ns, nspost, nspost2,                \
> +                         __is_defined(__KSYM_##sym))
> +#define __cond_export_sym(sym, sec, ns, nspost, nspost2, conf)         \
> +       ___cond_export_sym(sym, sec, ns, nspost, nspost2, conf)
> +#define ___cond_export_sym(sym, sec, ns, nspost, nspost2, enabled)     \
> +       __cond_export_sym_##enabled(sym, sec, ns, nspost, nspost2)
> +#define __cond_export_sym_1(sym, sec, ns, nspost, nspost2)             \
> +       ___EXPORT_SYMBOL(sym, sec, ns, nspost, nspost2)
> +#define __cond_export_sym_0(sym, sec, ns, nspost, nspost2) /* nothing */
>
>  #else
>  #define __EXPORT_SYMBOL ___EXPORT_SYMBOL
>  #endif
>
>  #define EXPORT_SYMBOL(sym)                                     \
> -       __EXPORT_SYMBOL(sym, "")
> +       __EXPORT_SYMBOL(sym, "", NULL, ,)
>
>  #define EXPORT_SYMBOL_GPL(sym)                                 \
> -       __EXPORT_SYMBOL(sym, "_gpl")
> +       __EXPORT_SYMBOL(sym, "_gpl", NULL, ,)
>
>  #define EXPORT_SYMBOL_GPL_FUTURE(sym)                          \
> -       __EXPORT_SYMBOL(sym, "_gpl_future")
> +       __EXPORT_SYMBOL(sym, "_gpl_future", NULL, ,)
> +
> +#define EXPORT_SYMBOL_NS(sym, ns)                               \
> +       __EXPORT_SYMBOL(sym, "", #ns, __##ns, NS_SEPARATOR #ns)
> +
> +#define EXPORT_SYMBOL_NS_GPL(sym, ns)                               \
> +       __EXPORT_SYMBOL(sym, "_gpl", #ns, __##ns, NS_SEPARATOR #ns)
>
>  #ifdef CONFIG_UNUSED_SYMBOLS
> -#define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused")
> -#define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl")
> +#define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused", , ,)
> +#define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl", , ,)
>  #else
>  #define EXPORT_UNUSED_SYMBOL(sym)
>  #define EXPORT_UNUSED_SYMBOL_GPL(sym)
>  #endif
>
> -#endif /* __GENKSYMS__ */
> +#endif /* __KERNEL__ && !__GENKSYMS__ */
> +
> +#if defined(__GENKSYMS__)
> +/*
> + * When we're running genksyms, ignore the namespace and make the _NS
> + * variants look like the normal ones. There are two reasons for this:
> + * 1) In the normal definition of EXPORT_SYMBOL_NS, the 'ns' macro
> + *    argument is itself not expanded because it's always tokenized or
> + *    concatenated; but when running genksyms, a blank definition of the
> + *    macro does allow the argument to be expanded; if a namespace
> + *    happens to collide with a #define, this can cause issues.
> + * 2) There's no need to modify genksyms to deal with the _NS variants
> + */
> +#define EXPORT_SYMBOL_NS(sym, ns)                              \
> +       EXPORT_SYMBOL(sym)
> +#define EXPORT_SYMBOL_NS_GPL(sym, ns)                          \
> +       EXPORT_SYMBOL_GPL(sym)
> +#endif
>
>  #else /* !CONFIG_MODULES... */
>
>  #define EXPORT_SYMBOL(sym)
> +#define EXPORT_SYMBOL_NS(sym, ns)
> +#define EXPORT_SYMBOL_NS_GPL(sym, ns)
>  #define EXPORT_SYMBOL_GPL(sym)
>  #define EXPORT_SYMBOL_GPL_FUTURE(sym)
>  #define EXPORT_UNUSED_SYMBOL(sym)
>  #define EXPORT_UNUSED_SYMBOL_GPL(sym)
>
> +#define MODULE_IMPORT_NS(ns)
>  #endif /* CONFIG_MODULES */
>  #endif /* !__ASSEMBLY__ */
>
> diff --git a/include/linux/module.h b/include/linux/module.h
> index d44df9b2c131..afab4e8fa188 100644
> --- a/include/linux/module.h
> +++ b/include/linux/module.h
> @@ -268,6 +268,12 @@ void *__symbol_get(const char *symbol);
>  void *__symbol_get_gpl(const char *symbol);
>  #define symbol_get(x) ((typeof(&x))(__symbol_get(VMLINUX_SYMBOL_STR(x))))
>
> +/* namespace dependencies of the module */
> +struct module_ns_dep {
> +       struct list_head ns_dep;
> +       const char *namespace;
> +};
> +
>  /* modules using other modules: kdb wants to see this. */
>  struct module_use {
>         struct list_head source_list;
> @@ -359,6 +365,13 @@ struct module {
>         const struct kernel_symbol *gpl_syms;
>         const s32 *gpl_crcs;
>
> +       /* Namespace imports */
> +       unsigned int num_ns_imports;
> +       const struct namespace_import *ns_imports;
> +
> +       /* Namespace dependencies */
> +       struct list_head ns_dependencies;
> +
>  #ifdef CONFIG_UNUSED_SYMBOLS
>         /* unused exported symbols. */
>         const struct kernel_symbol *unused_syms;
> diff --git a/kernel/module.c b/kernel/module.c
> index f475f30eed8c..63de0fe849f9 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -1166,6 +1166,51 @@ static inline int module_unload_init(struct module *mod)
>  }
>  #endif /* CONFIG_MODULE_UNLOAD */
>
> +static bool module_has_ns_dependency(struct module *mod, const char *ns)
> +{
> +       struct module_ns_dep *ns_dep;
> +
> +       list_for_each_entry(ns_dep, &mod->ns_dependencies, ns_dep) {
> +               if (strcmp(ns_dep->namespace, ns) == 0)
> +                       return true;
> +       }
> +
> +       return false;
> +}
> +
> +static int add_module_ns_dependency(struct module *mod, const char *ns)
> +{
> +       struct module_ns_dep *ns_dep;
> +
> +       if (module_has_ns_dependency(mod, ns))
> +               return 0;
> +
> +       ns_dep = kmalloc(sizeof(*ns_dep), GFP_ATOMIC);
> +       if (!ns_dep)
> +               return -ENOMEM;
> +
> +       ns_dep->namespace = ns;
> +
> +       list_add(&ns_dep->ns_dep, &mod->ns_dependencies);
> +
> +       return 0;
> +}
> +
> +static bool module_imports_ns(struct module *mod, const char *ns)
> +{
> +       size_t i;
> +
> +       if (!ns)
> +               return true;
> +
> +       for (i = 0; i < mod->num_ns_imports; ++i) {
> +               if (!strcmp(mod->ns_imports[i].namespace, ns))
> +                       return true;
> +       }
> +
> +       return false;
> +}
> +
>  static size_t module_flags_taint(struct module *mod, char *buf)
>  {
>         size_t l = 0;
> @@ -1415,6 +1460,18 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
>                 goto getname;
>         }
>
> +       /*
> +        * We can't yet verify that the module actually imports this
> +        * namespace, because the imports themselves are only available
> +        * after processing the symbol table and doing relocation; so
> +        * instead just record the dependency and check later.
> +        */
> +       if (sym->namespace) {
> +               err = add_module_ns_dependency(mod, sym->namespace);
> +               if (err)
> +                       sym = ERR_PTR(err);
> +       }
> +
>  getname:
>         /* We must make copy under the lock if we failed to get ref. */
>         strncpy(ownername, module_name(owner), MODULE_NAME_LEN);
> @@ -3061,6 +3118,11 @@ static int find_module_sections(struct module *mod, struct load_info *info)
>                                      sizeof(*mod->gpl_syms),
>                                      &mod->num_gpl_syms);
>         mod->gpl_crcs = section_addr(info, "__kcrctab_gpl");
> +
> +       mod->ns_imports = section_objs(info, "__knsimport",
> +                                      sizeof(*mod->ns_imports),
> +                                      &mod->num_ns_imports);
> +
>         mod->gpl_future_syms = section_objs(info,
>                                             "__ksymtab_gpl_future",
>                                             sizeof(*mod->gpl_future_syms),
> @@ -3381,6 +3443,19 @@ static int post_relocation(struct module *mod, const struct load_info *info)
>         return module_finalize(info->hdr, info->sechdrs, mod);
>  }
>
> +static void verify_namespace_dependencies(struct module *mod)
> +{
> +       struct module_ns_dep *ns_dep;
> +
> +       list_for_each_entry(ns_dep, &mod->ns_dependencies, ns_dep) {
> +               if (!module_imports_ns(mod, ns_dep->namespace)) {
> +                       pr_warn("%s: module uses symbols from namespace %s,"
> +                               " but does not import it.\n",
> +                               mod->name, ns_dep->namespace);
> +               }
> +       }
> +}
> +
>  /* Is this module of this name done loading?  No locks held. */
>  static bool finished_loading(const char *name)
>  {
> @@ -3682,6 +3757,8 @@ static int load_module(struct load_info *info, const char __user *uargs,
>         if (err)
>                 goto free_module;
>
> +       INIT_LIST_HEAD(&mod->ns_dependencies);
> +
>  #ifdef CONFIG_MODULE_SIG
>         mod->sig_ok = info->sig_ok;
>         if (!mod->sig_ok) {
> @@ -3730,6 +3807,8 @@ static int load_module(struct load_info *info, const char __user *uargs,
>         if (err < 0)
>                 goto free_modinfo;
>
> +       verify_namespace_dependencies(mod);
> +
>         flush_module_icache(mod);
>
>         /* Now copy in args */
> --
> 2.18.0.203.gfac676dfb9-goog
>
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

WARNING: multiple messages have this Message-ID (diff)
From: Martijn Coenen <maco@android.com>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Martijn Coenen <maco@android.com>,
	Masahiro Yamada <yamada.masahiro@socionext.com>,
	Michal Marek <michal.lkml@markovi.net>,
	Geert Uytterhoeven <geert@linux-m68k.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
	the arch/x86 maintainers <x86@kernel.org>,
	Alan Stern <stern@rowland.harvard.edu>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Oliver Neukum <oneukum@suse.com>, Arnd Bergmann <arnd@arndb.de>,
	Jessica Yu <jeyu@kernel.org>, Stephen Boyd <sboyd@codeaurora.org>,
	Philippe Ombredanne <pombredanne@nexb.com>,
	Kate Stewart <kstewart@linuxfoundation.org>,
	Sam Ravnborg <sam@ravnborg.org>,
	linux-kbuild@vger.kernel.org,
	linux-m68k <linux-m68k@lists.linux-m68k.org>,
	USB list <linux-usb@vger.>
Subject: Re: [PATCH 2/6] module: add support for symbol namespaces.
Date: Tue, 24 Jul 2018 09:56:47 +0200	[thread overview]
Message-ID: <CAB0TPYEOVHcFGFLTjVvk7R0VSgSnXZRi1PjSYXONJSjqd4NewQ@mail.gmail.com> (raw)
In-Reply-To: <20180716122125.175792-3-maco@android.com>

I did find an issue with my approach:

On Mon, Jul 16, 2018 at 2:21 PM, Martijn Coenen <maco@android.com> wrote:
> The ELF symbols are renamed to include the namespace with an asm label;
> for example, symbol 'usb_stor_suspend' in namespace USB_STORAGE becomes
> 'usb_stor_suspend.USB_STORAGE'.  This allows modpost to do namespace
> checking, without having to go through all the effort of parsing ELF and
> reloction records just to get to the struct kernel_symbols.

depmod doesn't like this: if namespaced symbols are built-in to the
kernel, they will appear as 'symbol.NS' in the symbol table, whereas
modules using those symbols just depend on 'symbol'. This will cause
depmod to warn about unknown symbols. I didn't find this previously
because all the exports/imports I tested were done from modules
themselves.

One way to deal with it is to change depmod, but it looks like it
hasn't been changed in ages, and it would also introduce a dependency
on userspaces to update it to avoid these warnings. So, we'd have to
encode the symbol namespace information in another way for modpost to
use. I could just write a separate post-processing tool (much like
genksyms), or perhaps encode the information in a discardable section.
Any other suggestions welcome.

Thanks,
Martijn

>
> On x86_64 I saw no difference in binary size (compression), but at
> runtime this will require a word of memory per export to hold the
> namespace. An alternative could be to store namespaced symbols in their
> own section and use a separate 'struct namespaced_kernel_symbol' for
> that section, at the cost of making the module loader more complex.
>
> Signed-off-by: Martijn Coenen <maco@android.com>
> ---
>  include/asm-generic/export.h |  2 +-
>  include/linux/export.h       | 83 +++++++++++++++++++++++++++---------
>  include/linux/module.h       | 13 ++++++
>  kernel/module.c              | 79 ++++++++++++++++++++++++++++++++++
>  4 files changed, 156 insertions(+), 21 deletions(-)
>
> diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h
> index 68efb950a918..4c3d1afb702f 100644
> --- a/include/asm-generic/export.h
> +++ b/include/asm-generic/export.h
> @@ -29,7 +29,7 @@
>         .section ___ksymtab\sec+\name,"a"
>         .balign KSYM_ALIGN
>  __ksymtab_\name:
> -       __put \val, __kstrtab_\name
> +       __put \val, __kstrtab_\name, 0
>         .previous
>         .section __ksymtab_strings,"a"
>  __kstrtab_\name:
> diff --git a/include/linux/export.h b/include/linux/export.h
> index ad6b8e697b27..9f6e70eeb85f 100644
> --- a/include/linux/export.h
> +++ b/include/linux/export.h
> @@ -22,6 +22,11 @@ struct kernel_symbol
>  {
>         unsigned long value;
>         const char *name;
> +       const char *namespace;
> +};
> +
> +struct namespace_import {
> +       const char *namespace;
>  };
>
>  #ifdef MODULE
> @@ -54,18 +59,28 @@ extern struct module __this_module;
>  #define __CRC_SYMBOL(sym, sec)
>  #endif
>
> +#define NS_SEPARATOR "."
> +
> +#define MODULE_IMPORT_NS(ns)                                           \
> +       static const struct namespace_import __knsimport_##ns           \
> +       asm("__knsimport_" #ns)                                         \
> +       __attribute__((section("__knsimport"), used))                   \
> +       = { #ns }
> +
>  /* For every exported symbol, place a struct in the __ksymtab section */
> -#define ___EXPORT_SYMBOL(sym, sec)                                     \
> +#define ___EXPORT_SYMBOL(sym, sec, ns, nspost, nspost2)                        \
>         extern typeof(sym) sym;                                         \
>         __CRC_SYMBOL(sym, sec)                                          \
> -       static const char __kstrtab_##sym[]                             \
> +       static const char __kstrtab_##sym##nspost[]                     \
>         __attribute__((section("__ksymtab_strings"), aligned(1)))       \
>         = #sym;                                                         \
> -       static const struct kernel_symbol __ksymtab_##sym               \
> +       static const struct kernel_symbol __ksymtab_##sym##nspost       \
> +       asm("__ksymtab_" #sym nspost2)                                  \
>         __used                                                          \
> -       __attribute__((section("___ksymtab" sec "+" #sym), used))       \
> +       __attribute__((section("___ksymtab" sec "+" #sym #nspost)))     \
> +       __attribute__((used))                                           \
>         __attribute__((aligned(sizeof(void *))))                        \
> -       = { (unsigned long)&sym, __kstrtab_##sym }
> +       = { (unsigned long)&sym, __kstrtab_##sym##nspost, ns }
>
>  #if defined(__KSYM_DEPS__)
>
> @@ -76,52 +91,80 @@ extern struct module __this_module;
>   * system filters out from the preprocessor output (see ksym_dep_filter
>   * in scripts/Kbuild.include).
>   */
> -#define __EXPORT_SYMBOL(sym, sec)      === __KSYM_##sym ===
> +#define __EXPORT_SYMBOL(sym, sec, ns, nspost, nspost2) === __KSYM_##sym ===
>
>  #elif defined(CONFIG_TRIM_UNUSED_KSYMS)
>
>  #include <generated/autoksyms.h>
>
> -#define __EXPORT_SYMBOL(sym, sec)                              \
> -       __cond_export_sym(sym, sec, __is_defined(__KSYM_##sym))
> -#define __cond_export_sym(sym, sec, conf)                      \
> -       ___cond_export_sym(sym, sec, conf)
> -#define ___cond_export_sym(sym, sec, enabled)                  \
> -       __cond_export_sym_##enabled(sym, sec)
> -#define __cond_export_sym_1(sym, sec) ___EXPORT_SYMBOL(sym, sec)
> -#define __cond_export_sym_0(sym, sec) /* nothing */
> +#define __EXPORT_SYMBOL(sym, sec, ns, nspost, nspost2)                 \
> +       __cond_export_sym(sym, sec, ns, nspost, nspost2,                \
> +                         __is_defined(__KSYM_##sym))
> +#define __cond_export_sym(sym, sec, ns, nspost, nspost2, conf)         \
> +       ___cond_export_sym(sym, sec, ns, nspost, nspost2, conf)
> +#define ___cond_export_sym(sym, sec, ns, nspost, nspost2, enabled)     \
> +       __cond_export_sym_##enabled(sym, sec, ns, nspost, nspost2)
> +#define __cond_export_sym_1(sym, sec, ns, nspost, nspost2)             \
> +       ___EXPORT_SYMBOL(sym, sec, ns, nspost, nspost2)
> +#define __cond_export_sym_0(sym, sec, ns, nspost, nspost2) /* nothing */
>
>  #else
>  #define __EXPORT_SYMBOL ___EXPORT_SYMBOL
>  #endif
>
>  #define EXPORT_SYMBOL(sym)                                     \
> -       __EXPORT_SYMBOL(sym, "")
> +       __EXPORT_SYMBOL(sym, "", NULL, ,)
>
>  #define EXPORT_SYMBOL_GPL(sym)                                 \
> -       __EXPORT_SYMBOL(sym, "_gpl")
> +       __EXPORT_SYMBOL(sym, "_gpl", NULL, ,)
>
>  #define EXPORT_SYMBOL_GPL_FUTURE(sym)                          \
> -       __EXPORT_SYMBOL(sym, "_gpl_future")
> +       __EXPORT_SYMBOL(sym, "_gpl_future", NULL, ,)
> +
> +#define EXPORT_SYMBOL_NS(sym, ns)                               \
> +       __EXPORT_SYMBOL(sym, "", #ns, __##ns, NS_SEPARATOR #ns)
> +
> +#define EXPORT_SYMBOL_NS_GPL(sym, ns)                               \
> +       __EXPORT_SYMBOL(sym, "_gpl", #ns, __##ns, NS_SEPARATOR #ns)
>
>  #ifdef CONFIG_UNUSED_SYMBOLS
> -#define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused")
> -#define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl")
> +#define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused", , ,)
> +#define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl", , ,)
>  #else
>  #define EXPORT_UNUSED_SYMBOL(sym)
>  #define EXPORT_UNUSED_SYMBOL_GPL(sym)
>  #endif
>
> -#endif /* __GENKSYMS__ */
> +#endif /* __KERNEL__ && !__GENKSYMS__ */
> +
> +#if defined(__GENKSYMS__)
> +/*
> + * When we're running genksyms, ignore the namespace and make the _NS
> + * variants look like the normal ones. There are two reasons for this:
> + * 1) In the normal definition of EXPORT_SYMBOL_NS, the 'ns' macro
> + *    argument is itself not expanded because it's always tokenized or
> + *    concatenated; but when running genksyms, a blank definition of the
> + *    macro does allow the argument to be expanded; if a namespace
> + *    happens to collide with a #define, this can cause issues.
> + * 2) There's no need to modify genksyms to deal with the _NS variants
> + */
> +#define EXPORT_SYMBOL_NS(sym, ns)                              \
> +       EXPORT_SYMBOL(sym)
> +#define EXPORT_SYMBOL_NS_GPL(sym, ns)                          \
> +       EXPORT_SYMBOL_GPL(sym)
> +#endif
>
>  #else /* !CONFIG_MODULES... */
>
>  #define EXPORT_SYMBOL(sym)
> +#define EXPORT_SYMBOL_NS(sym, ns)
> +#define EXPORT_SYMBOL_NS_GPL(sym, ns)
>  #define EXPORT_SYMBOL_GPL(sym)
>  #define EXPORT_SYMBOL_GPL_FUTURE(sym)
>  #define EXPORT_UNUSED_SYMBOL(sym)
>  #define EXPORT_UNUSED_SYMBOL_GPL(sym)
>
> +#define MODULE_IMPORT_NS(ns)
>  #endif /* CONFIG_MODULES */
>  #endif /* !__ASSEMBLY__ */
>
> diff --git a/include/linux/module.h b/include/linux/module.h
> index d44df9b2c131..afab4e8fa188 100644
> --- a/include/linux/module.h
> +++ b/include/linux/module.h
> @@ -268,6 +268,12 @@ void *__symbol_get(const char *symbol);
>  void *__symbol_get_gpl(const char *symbol);
>  #define symbol_get(x) ((typeof(&x))(__symbol_get(VMLINUX_SYMBOL_STR(x))))
>
> +/* namespace dependencies of the module */
> +struct module_ns_dep {
> +       struct list_head ns_dep;
> +       const char *namespace;
> +};
> +
>  /* modules using other modules: kdb wants to see this. */
>  struct module_use {
>         struct list_head source_list;
> @@ -359,6 +365,13 @@ struct module {
>         const struct kernel_symbol *gpl_syms;
>         const s32 *gpl_crcs;
>
> +       /* Namespace imports */
> +       unsigned int num_ns_imports;
> +       const struct namespace_import *ns_imports;
> +
> +       /* Namespace dependencies */
> +       struct list_head ns_dependencies;
> +
>  #ifdef CONFIG_UNUSED_SYMBOLS
>         /* unused exported symbols. */
>         const struct kernel_symbol *unused_syms;
> diff --git a/kernel/module.c b/kernel/module.c
> index f475f30eed8c..63de0fe849f9 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -1166,6 +1166,51 @@ static inline int module_unload_init(struct module *mod)
>  }
>  #endif /* CONFIG_MODULE_UNLOAD */
>
> +static bool module_has_ns_dependency(struct module *mod, const char *ns)
> +{
> +       struct module_ns_dep *ns_dep;
> +
> +       list_for_each_entry(ns_dep, &mod->ns_dependencies, ns_dep) {
> +               if (strcmp(ns_dep->namespace, ns) == 0)
> +                       return true;
> +       }
> +
> +       return false;
> +}
> +
> +static int add_module_ns_dependency(struct module *mod, const char *ns)
> +{
> +       struct module_ns_dep *ns_dep;
> +
> +       if (module_has_ns_dependency(mod, ns))
> +               return 0;
> +
> +       ns_dep = kmalloc(sizeof(*ns_dep), GFP_ATOMIC);
> +       if (!ns_dep)
> +               return -ENOMEM;
> +
> +       ns_dep->namespace = ns;
> +
> +       list_add(&ns_dep->ns_dep, &mod->ns_dependencies);
> +
> +       return 0;
> +}
> +
> +static bool module_imports_ns(struct module *mod, const char *ns)
> +{
> +       size_t i;
> +
> +       if (!ns)
> +               return true;
> +
> +       for (i = 0; i < mod->num_ns_imports; ++i) {
> +               if (!strcmp(mod->ns_imports[i].namespace, ns))
> +                       return true;
> +       }
> +
> +       return false;
> +}
> +
>  static size_t module_flags_taint(struct module *mod, char *buf)
>  {
>         size_t l = 0;
> @@ -1415,6 +1460,18 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
>                 goto getname;
>         }
>
> +       /*
> +        * We can't yet verify that the module actually imports this
> +        * namespace, because the imports themselves are only available
> +        * after processing the symbol table and doing relocation; so
> +        * instead just record the dependency and check later.
> +        */
> +       if (sym->namespace) {
> +               err = add_module_ns_dependency(mod, sym->namespace);
> +               if (err)
> +                       sym = ERR_PTR(err);
> +       }
> +
>  getname:
>         /* We must make copy under the lock if we failed to get ref. */
>         strncpy(ownername, module_name(owner), MODULE_NAME_LEN);
> @@ -3061,6 +3118,11 @@ static int find_module_sections(struct module *mod, struct load_info *info)
>                                      sizeof(*mod->gpl_syms),
>                                      &mod->num_gpl_syms);
>         mod->gpl_crcs = section_addr(info, "__kcrctab_gpl");
> +
> +       mod->ns_imports = section_objs(info, "__knsimport",
> +                                      sizeof(*mod->ns_imports),
> +                                      &mod->num_ns_imports);
> +
>         mod->gpl_future_syms = section_objs(info,
>                                             "__ksymtab_gpl_future",
>                                             sizeof(*mod->gpl_future_syms),
> @@ -3381,6 +3443,19 @@ static int post_relocation(struct module *mod, const struct load_info *info)
>         return module_finalize(info->hdr, info->sechdrs, mod);
>  }
>
> +static void verify_namespace_dependencies(struct module *mod)
> +{
> +       struct module_ns_dep *ns_dep;
> +
> +       list_for_each_entry(ns_dep, &mod->ns_dependencies, ns_dep) {
> +               if (!module_imports_ns(mod, ns_dep->namespace)) {
> +                       pr_warn("%s: module uses symbols from namespace %s,"
> +                               " but does not import it.\n",
> +                               mod->name, ns_dep->namespace);
> +               }
> +       }
> +}
> +
>  /* Is this module of this name done loading?  No locks held. */
>  static bool finished_loading(const char *name)
>  {
> @@ -3682,6 +3757,8 @@ static int load_module(struct load_info *info, const char __user *uargs,
>         if (err)
>                 goto free_module;
>
> +       INIT_LIST_HEAD(&mod->ns_dependencies);
> +
>  #ifdef CONFIG_MODULE_SIG
>         mod->sig_ok = info->sig_ok;
>         if (!mod->sig_ok) {
> @@ -3730,6 +3807,8 @@ static int load_module(struct load_info *info, const char __user *uargs,
>         if (err < 0)
>                 goto free_modinfo;
>
> +       verify_namespace_dependencies(mod);
> +
>         flush_module_icache(mod);
>
>         /* Now copy in args */
> --
> 2.18.0.203.gfac676dfb9-goog
>

  parent reply	other threads:[~2018-07-24  7:56 UTC|newest]

Thread overview: 261+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-16 12:21 [PATCH 0/6] Symbol namespaces Martijn Coenen
2018-07-16 12:21 ` Martijn Coenen
2018-07-16 12:21 ` [PATCH 1/6] export: explicitly align struct kernel_symbol Martijn Coenen
2018-07-16 12:21   ` Martijn Coenen
2018-07-16 12:21   ` [1/6] " Martijn Coenen
2018-07-16 12:21 ` [PATCH 2/6] module: add support for symbol namespaces Martijn Coenen
2018-07-16 12:21   ` Martijn Coenen
2018-07-16 12:21   ` [2/6] " Martijn Coenen
2018-07-19 16:32   ` [PATCH 2/6] " Jessica Yu
2018-07-19 16:32     ` Jessica Yu
2018-07-19 16:32     ` [2/6] " Jessica Yu
2018-07-20  7:54     ` [PATCH 2/6] " Martijn Coenen
2018-07-20  7:54       ` Martijn Coenen
2018-07-20  7:54       ` [2/6] " Martijn Coenen
2018-07-20 14:49       ` [PATCH 2/6] " Jessica Yu
2018-07-20 14:49         ` Jessica Yu
2018-07-20 14:49         ` [2/6] " Jessica Yu
2018-07-20 15:42         ` [PATCH 2/6] " Martijn Coenen
2018-07-20 15:42           ` Martijn Coenen
2018-07-20 15:42           ` [2/6] " Martijn Coenen
2018-07-23 11:12           ` [PATCH 2/6] " Jessica Yu
2018-07-23 11:12             ` Jessica Yu
2018-07-23 11:12             ` [2/6] " Jessica Yu
2018-07-24  7:44             ` [PATCH 2/6] " Martijn Coenen
2018-07-24  7:44               ` Martijn Coenen
2018-07-24  7:44               ` [2/6] " Martijn Coenen
2018-07-24  7:56   ` Martijn Coenen [this message]
2018-07-24  7:56     ` [PATCH 2/6] " Martijn Coenen
2018-07-24  7:56     ` [2/6] " Martijn Coenen
2018-07-25 15:55     ` [PATCH 2/6] " Jessica Yu
2018-07-25 15:55       ` Jessica Yu
2018-07-25 15:55       ` [2/6] " Jessica Yu
2018-07-25 16:48       ` [PATCH 2/6] " Lucas De Marchi
2018-07-25 16:48         ` [2/6] " Lucas De Marchi
2018-07-26  7:44         ` [PATCH 2/6] " Martijn Coenen
2018-07-26  7:44           ` Martijn Coenen
2018-07-26  7:44           ` [2/6] " Martijn Coenen
2018-07-16 12:21 ` [PATCH 3/6] modpost: add support for checking " Martijn Coenen
2018-07-16 12:21   ` Martijn Coenen
2018-07-16 12:21   ` [3/6] " Martijn Coenen
2018-07-16 12:21 ` [PATCH 4/6] modpost: add support for generating namespace dependencies Martijn Coenen
2018-07-16 12:21   ` Martijn Coenen
2018-07-16 12:21   ` [4/6] " Martijn Coenen
2018-07-23  6:49   ` [PATCH 4/6] " Jessica Yu
2018-07-23  6:49     ` Jessica Yu
2018-07-23  6:49     ` [4/6] " Jessica Yu
2018-07-16 12:21 ` [PATCH 5/6] scripts: Coccinelle script for " Martijn Coenen
2018-07-16 12:21   ` Martijn Coenen
2018-07-16 12:21   ` [5/6] " Martijn Coenen
2018-07-16 12:21 ` [PATCH 6/6] RFC: USB: storage: move symbols into USB_STORAGE namespace Martijn Coenen
2018-07-16 12:21   ` Martijn Coenen
2018-07-16 12:21   ` [6/6] " Martijn Coenen
2018-07-17 15:04   ` [PATCH 6/6] " Alan Stern
2018-07-17 15:04     ` [6/6] " Alan Stern
2018-07-18 13:28     ` [PATCH 6/6] " Martijn Coenen
2018-07-18 13:28       ` [6/6] " Martijn Coenen
2018-07-16 15:33 ` [PATCH 0/6] Symbol namespaces Greg Kroah-Hartman
2018-07-16 15:33   ` Greg Kroah-Hartman
2018-07-23 14:28 ` Arnd Bergmann
2018-07-23 14:28   ` Arnd Bergmann
2018-07-24  8:09   ` Martijn Coenen
2018-07-24  8:09     ` Martijn Coenen
2018-07-24  9:08     ` Arnd Bergmann
2018-07-24  9:08       ` Arnd Bergmann
2019-08-13 12:16 ` [PATCH v2 0/10] Symbol namespaces - RFC Matthias Maennich
2019-08-13 12:16   ` [Cocci] " Matthias Maennich
2019-08-13 12:16   ` Matthias Maennich
2019-08-13 12:16   ` [PATCH v2 01/10] module: support reading multiple values per modinfo tag Matthias Maennich
2019-08-13 12:40     ` Greg KH
2019-08-13 12:16   ` [PATCH v2 02/10] export: explicitly align struct kernel_symbol Matthias Maennich
2019-08-13 12:16     ` Matthias Maennich
2019-08-13 12:41     ` Greg KH
2019-08-13 12:41       ` Greg KH
2019-08-13 12:17   ` [PATCH v2 03/10] module: add support for symbol namespaces Matthias Maennich
2019-08-13 12:17     ` Matthias Maennich
2019-08-13 15:26     ` Greg KH
2019-08-13 15:26       ` Greg KH
2019-08-13 12:17   ` [PATCH v2 04/10] modpost: " Matthias Maennich
2019-08-13 15:27     ` Greg KH
2019-08-13 12:17   ` [PATCH v2 05/10] module: add config option MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS Matthias Maennich
2019-08-13 12:17     ` Matthias Maennich
2019-08-13 18:17     ` Greg KH
2019-08-13 18:17       ` Greg KH
2019-08-13 20:15     ` Saravana Kannan
2019-08-13 20:15       ` Saravana Kannan
2019-08-14 12:54       ` Matthias Maennich
2019-08-14 12:54         ` Matthias Maennich
2019-08-14 17:34         ` Saravana Kannan
2019-08-14 17:34           ` Saravana Kannan
2019-08-13 12:17   ` [PATCH v2 06/10] export: allow definition default namespaces in Makefiles or sources Matthias Maennich
2019-08-13 18:16     ` Greg KH
2019-08-13 18:16     ` Greg KH
2019-08-13 12:17   ` [PATCH v2 07/10] modpost: add support for generating namespace dependencies Matthias Maennich
2019-08-13 18:21     ` Greg KH
2019-08-13 12:17   ` [PATCH v2 08/10] scripts: Coccinelle script for " Matthias Maennich
2019-08-13 12:17     ` [Cocci] " Matthias Maennich
2019-08-13 12:17     ` Matthias Maennich
2019-08-13 12:31     ` Julia Lawall
2019-08-13 12:31       ` [Cocci] " Julia Lawall
2019-08-13 12:31       ` Julia Lawall
2019-08-13 12:44     ` Greg KH
2019-08-13 12:44       ` [Cocci] " Greg KH
2019-08-13 12:44       ` Greg KH
2019-08-14  6:36     ` [Cocci] " Himanshu Jha
2019-08-14  6:36       ` Himanshu Jha
2019-08-14  6:36       ` Himanshu Jha
2019-08-14  8:03       ` Matthias Maennich
2019-08-14  8:03         ` Matthias Maennich
2019-08-14  8:03         ` Matthias Maennich
2019-08-14 12:00     ` [v2 " Markus Elfring
2019-08-14 12:00       ` [Cocci] " Markus Elfring
2019-08-14 12:00       ` Markus Elfring
2019-08-14 12:00       ` Markus Elfring
2019-08-14 12:20       ` Matthias Maennich
2019-08-14 12:20         ` [Cocci] " Matthias Maennich
2019-08-15 13:50     ` Markus Elfring
2019-08-15 13:50       ` Markus Elfring
2019-08-15 13:50       ` Markus Elfring
2019-08-22  9:18       ` Matthias Maennich
2019-08-22  9:18         ` Matthias Maennich
2019-08-22  9:18         ` Matthias Maennich
2019-08-22 11:00         ` Markus Elfring
2019-08-22 11:00           ` Markus Elfring
2019-08-22 11:00           ` Markus Elfring
2019-08-13 12:17   ` [PATCH v2 09/10] usb-storage: remove single-use define for debugging Matthias Maennich
2019-08-13 12:42     ` Greg KH
2019-08-13 13:12       ` Greg KH
2019-08-13 12:17   ` [PATCH v2 10/10] RFC: usb-storage: export symbols in USB_STORAGE namespace Matthias Maennich
2019-08-13 12:45     ` Greg KH
2019-08-13 12:47     ` Greg KH
2019-08-13 15:02       ` Matthias Maennich
     [not found]   ` <20190813121733.52480-1-maennich-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2019-08-21 11:49     ` [PATCH v3 00/11] Symbol Namespaces Matthias Maennich
2019-08-21 11:49       ` Matthias Maennich
2019-08-21 11:49       ` Matthias Maennich
2019-08-21 11:49       ` [PATCH v3 01/11] module: support reading multiple values per modinfo tag Matthias Maennich
2019-08-21 11:49       ` [PATCH v3 02/11] export: explicitly align struct kernel_symbol Matthias Maennich
2019-08-21 11:49         ` Matthias Maennich
2019-08-21 11:49       ` [PATCH v3 03/11] module: add support for symbol namespaces Matthias Maennich
2019-08-21 11:49         ` Matthias Maennich
2019-08-27 15:37         ` Jessica Yu
2019-08-27 15:37           ` Jessica Yu
2019-08-27 16:04           ` Matthias Maennich
2019-08-27 16:04             ` Matthias Maennich
2019-08-21 11:49       ` [PATCH v3 04/11] modpost: " Matthias Maennich
2019-08-26 16:21         ` Jessica Yu
2019-08-27 14:41           ` Matthias Maennich
2019-08-28  9:43             ` Jessica Yu
2019-08-28  9:55               ` Matthias Maennich
2019-08-28 10:16                 ` Jessica Yu
2019-08-21 11:49       ` [PATCH v3 05/11] module: add config option MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS Matthias Maennich
2019-08-21 11:49         ` Matthias Maennich
2019-08-21 11:49       ` [PATCH v3 06/11] export: allow definition default namespaces in Makefiles or sources Matthias Maennich
2019-08-21 11:49         ` Matthias Maennich
2019-08-28 10:49         ` Jessica Yu
2019-08-28 10:49           ` Jessica Yu
2019-08-28 10:56           ` Matthias Maennich
2019-08-28 10:56             ` Matthias Maennich
2019-08-21 11:49       ` [PATCH v3 07/11] modpost: add support for generating namespace dependencies Matthias Maennich
2019-08-21 11:49         ` Matthias Maennich
2019-08-21 11:49       ` [PATCH v3 08/11] scripts: Coccinelle script for " Matthias Maennich
2019-08-21 11:49         ` Matthias Maennich
2019-08-22  6:09         ` [v3 " Markus Elfring
2019-08-22  6:09           ` Markus Elfring
2019-08-22  6:09           ` Markus Elfring
2019-08-29 12:13         ` [PATCH v3 " Jessica Yu
2019-08-29 12:13           ` [Cocci] " Jessica Yu
2019-08-29 12:13           ` Jessica Yu
2019-08-21 11:49       ` [PATCH v3 09/11] usb-storage: remove single-use define for debugging Matthias Maennich
2019-08-21 12:37         ` Greg KH
2019-08-21 13:21         ` Thomas Gleixner
2019-08-21 13:32           ` Greg KH
2019-08-21 11:49       ` [PATCH v3 10/11] RFC: usb-storage: export symbols in USB_STORAGE namespace Matthias Maennich
2019-08-21 12:38         ` Greg KH
2019-08-21 14:36           ` Jessica Yu
2019-08-21 23:13         ` Christoph Hellwig
2019-08-22  8:32           ` Matthias Maennich
     [not found]       ` <20190821114955.12788-1-maennich-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2019-08-21 11:49         ` [PATCH v3 11/11] RFC: watchdog: export core symbols in WATCHDOG_CORE namespace Matthias Maennich
2019-08-21 11:49           ` Matthias Maennich
2019-08-21 11:49           ` Matthias Maennich
     [not found]           ` <20190821114955.12788-12-maennich-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2019-08-21 12:39             ` Greg KH
2019-08-21 12:39               ` Greg KH
2019-08-21 12:39               ` Greg KH
2019-08-21 14:59             ` Guenter Roeck
2019-08-21 14:59               ` Guenter Roeck
2019-08-21 14:59               ` Guenter Roeck
     [not found]               ` <20190821145911.GA6521-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>
2019-08-21 16:28                 ` Matthias Maennich
2019-08-21 16:28                   ` Matthias Maennich
2019-08-21 16:28                   ` Matthias Maennich
2019-08-21 12:46         ` [PATCH v3 00/11] Symbol Namespaces Nicolas Pitre
2019-08-21 12:46           ` Nicolas Pitre
2019-08-21 12:46           ` Nicolas Pitre
     [not found]           ` <nycvar.YSQ.7.76.1908210840490.19480-fMhRO7WWcppj+hNMo8g0rg@public.gmane.org>
2019-08-21 13:37             ` Greg KH
2019-08-21 13:37               ` Greg KH
2019-08-21 13:37               ` Greg KH
     [not found]               ` <20190821133737.GB4890-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
2019-08-21 20:48                 ` Nicolas Pitre
2019-08-21 20:48                   ` Nicolas Pitre
2019-08-21 20:48                   ` Nicolas Pitre
2019-08-21 13:11         ` Peter Zijlstra
2019-08-21 13:11           ` Peter Zijlstra
2019-08-21 13:11           ` Peter Zijlstra
     [not found]           ` <20190821131140.GC2349-Nxj+rRp3nVydTX5a5knrm8zTDFooKrT+cvkQGrU6aU0@public.gmane.org>
2019-08-21 13:38             ` Greg KH
2019-08-21 13:38               ` Greg KH
2019-08-21 13:38               ` Greg KH
     [not found]               ` <20190821133846.GC4890-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
2019-08-21 14:03                 ` Matthias Maennich
2019-08-21 14:03                   ` Matthias Maennich
2019-08-21 14:03                   ` Matthias Maennich
2019-09-03 15:06 ` [PATCH v4 00/12] " Matthias Maennich
2019-09-03 15:06   ` [PATCH v4 01/12] module: support reading multiple values per modinfo tag Matthias Maennich
2019-09-03 15:06   ` [PATCH v4 02/12] export: explicitly align struct kernel_symbol Matthias Maennich
2019-09-03 15:06   ` [PATCH v4 03/12] module: add support for symbol namespaces Matthias Maennich
2019-09-03 15:06   ` [PATCH v4 04/12] modpost: " Matthias Maennich
2019-09-03 15:06   ` [PATCH v4 05/12] module: add config option MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS Matthias Maennich
2019-09-03 15:06   ` [PATCH v4 06/12] export: allow definition default namespaces in Makefiles or sources Matthias Maennich
2019-09-03 15:06   ` [PATCH v4 07/12] modpost: add support for generating namespace dependencies Matthias Maennich
2019-09-03 15:06   ` [PATCH v4 08/12] scripts: Coccinelle script for " Matthias Maennich
2019-09-04  9:53     ` Masahiro Yamada
2019-09-05 14:46       ` Matthias Maennich
2019-09-03 15:06   ` [PATCH v4 09/12] docs: Add documentation for Symbol Namespaces Matthias Maennich
2019-09-04  7:16     ` Greg KH
2019-09-03 15:06   ` [PATCH v4 10/12] usb-storage: remove single-use define for debugging Matthias Maennich
2019-09-03 15:06   ` [PATCH v4 11/12] RFC: usb-storage: export symbols in USB_STORAGE namespace Matthias Maennich
2019-09-03 15:06   ` [PATCH v4 12/12] RFC: watchdog: export core symbols in WATCHDOG_CORE namespace Matthias Maennich
2019-09-03 16:10     ` Guenter Roeck
2019-09-04  8:45       ` Masahiro Yamada
2019-09-04 12:12         ` Guenter Roeck
2019-09-04 16:16           ` [usb-storage] " Matthew Dharm
2019-09-04 16:16             ` Matthew Dharm
2019-09-05 10:41             ` Jessica Yu
2019-09-05 10:41               ` Jessica Yu
2019-09-05 10:52               ` Arnd Bergmann
2019-09-05 10:52                 ` Arnd Bergmann
2019-09-05 11:16                 ` Jessica Yu
2019-09-05 11:16                   ` Jessica Yu
2019-09-05 11:25                   ` Masahiro Yamada
2019-09-05 11:25                     ` Masahiro Yamada
2019-09-05 12:00                     ` Greg Kroah-Hartman
2019-09-05 12:00                       ` Greg Kroah-Hartman
2019-09-05 11:25               ` Matthias Maennich
2019-09-05 11:25                 ` Matthias Maennich
2019-09-04  9:37   ` [PATCH v4 00/12] Symbol Namespaces Masahiro Yamada
2019-09-06 10:32 ` [PATCH v5 00/11] " Matthias Maennich
2019-09-06 10:32   ` [PATCH v5 01/11] module: support reading multiple values per modinfo tag Matthias Maennich
2019-09-06 10:32   ` [PATCH v5 02/11] export: explicitly align struct kernel_symbol Matthias Maennich
2019-09-06 10:32   ` [PATCH v5 03/11] module: add support for symbol namespaces Matthias Maennich
2019-09-06 10:32   ` [PATCH v5 04/11] modpost: " Matthias Maennich
2019-09-26 22:24     ` [PATCH] modpost: Copy namespace string into 'struct symbol' Shaun Ruffell
2019-09-27  5:31       ` Greg Kroah-Hartman
2019-09-27  8:03       ` Matthias Maennich
2019-09-30 21:20         ` Shaun Ruffell
2019-10-01 16:19           ` Matthias Maennich
2019-10-01 19:37             ` Shaun Ruffell
2019-09-06 10:32   ` [PATCH v5 05/11] module: add config option MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS Matthias Maennich
2019-09-06 10:32   ` [PATCH v5 06/11] export: allow definition default namespaces in Makefiles or sources Matthias Maennich
2019-09-06 10:32   ` [PATCH v5 07/11] modpost: add support for generating namespace dependencies Matthias Maennich
2019-09-06 10:32   ` [PATCH v5 08/11] scripts: Coccinelle script for " Matthias Maennich
2019-09-06 10:32   ` [PATCH v5 09/11] docs: Add documentation for Symbol Namespaces Matthias Maennich
2019-09-06 10:32   ` [PATCH v5 10/11] usb-storage: remove single-use define for debugging Matthias Maennich
2019-09-06 12:59     ` Jessica Yu
2019-09-06 13:22       ` Greg KH
2019-09-06 10:32   ` [PATCH v5 11/11] usb-storage: export symbols in USB_STORAGE namespace Matthias Maennich
2019-09-09  8:35   ` [PATCH v5 00/11] Symbol Namespaces Jessica Yu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAB0TPYEOVHcFGFLTjVvk7R0VSgSnXZRi1PjSYXONJSjqd4NewQ@mail.gmail.com \
    --to=maco@android.com \
    --cc=arnd@arndb.de \
    --cc=geert@linux-m68k.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=hpa@zytor.com \
    --cc=jeyu@kernel.org \
    --cc=joelaf@google.com \
    --cc=kstewart@linuxfoundation.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-m68k@lists.linux-m68k.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=maco@google.com \
    --cc=malchev@google.com \
    --cc=michal.lkml@markovi.net \
    --cc=mingo@redhat.com \
    --cc=oneukum@suse.com \
    --cc=pombredanne@nexb.com \
    --cc=sam@ravnborg.org \
    --cc=sboyd@codeaurora.org \
    --cc=sspatil@google.com \
    --cc=stern@rowland.harvard.edu \
    --cc=tglx@linutronix.de \
    --cc=usb-storage@lists.one-eyed-alien.net \
    --cc=x86@kernel.org \
    --cc=yamada.masahiro@socionext.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.