[PATCH v9 00/10] Generate modules.builtin.alias from match ids

Allen Webb posted 10 patches 2 years, 9 months ago
There is a newer version of this series
.gitignore                         |  1 +
Documentation/kbuild/kbuild.rst    |  6 ++
Makefile                           |  1 +
drivers/mailbox/rockchip-mailbox.c |  2 +-
drivers/mfd/stmpe-spi.c            |  2 +-
drivers/scsi/BusLogic.c            |  2 -
drivers/soc/imx/imx8mp-blk-ctrl.c  |  2 +-
include/linux/module.h             | 15 ++++-
scripts/Makefile.modpost           | 17 +++++-
scripts/mod/file2alias.c           | 94 +++++++++++++++++++++++-------
scripts/mod/modpost.c              | 23 +++++++-
scripts/mod/modpost.h              |  2 +
12 files changed, 137 insertions(+), 30 deletions(-)
[PATCH v9 00/10] Generate modules.builtin.alias from match ids
Posted by Allen Webb 2 years, 9 months ago
Generate modules.builtin.alias from match ids

This patch series (v8) generates `modules.builtin.alias` during modpost.
The goal is for tools like USBGuard to leverage not only modules.aliases
but also `modules.builtin.aliases` to associate devices with the modules
that may be bound before deciding to authorize a device or not. This is
particularly useful in cases when new devices of a particular type
shouldn't be allowed part of the time like for lock screens.

Also included in this series are added documentation, style fixes and
fixes for build breakages for built-in modules that relied on
MODULE_DEVICE_TABLE being a no-op. Some of these were typos in the
device table name and one ifdef-ed out the device table.

--

# Generate modules.builtin.alias from match ids

This series (v8) adds missing `cc:stable` and `fixes:` commit tags to
the relevant commits. It is unlikely these drivers were being built as
modules because compilation would have failed. It also updates the build
documentation to cover `modules.builtin.alias`.

Note, cover letters were first added in v5.

  RFC (broken patch): https://lore.kernel.org/lkml/CAJzde042-M4UbpNYKw0eDVg4JqYmwmPYSsmgK+kCMTqsi+-2Yw@mail.gmail.com/
  v1 (missing v1 label): https://lore.kernel.org/lkml/20221111152852.2837363-1-allenwebb@google.com/
  v2 (missing v2 label): https://lore.kernel.org/lkml/20221128201332.3482092-1-allenwebb@google.com/
  v3: https://lore.kernel.org/lkml/20221129224313.455862-1-allenwebb@google.com/
  v4: https://lore.kernel.org/lkml/20221130221447.1202206-1-allenwebb@google.com/
  v5: https://lore.kernel.org/lkml/20221201211630.101541-1-allenwebb@google.com/
  v6: https://lore.kernel.org/lkml/20221202224540.1446952-1-allenwebb@google.com/
  v7: https://lore.kernel.org/lkml/20221216221703.294683-1-allenwebb@google.com/
  v8: https://lore.kernel.org/lkml/20221219191855.2010466-1-allenwebb@google.com/
  v9: This version

## Patch series status

This series is still going through revisions in response to comments.

I believe there is potential to improve the Makefile part of the patch
series as well as an open question of whether modpost should generate
`modules.built.alias` directly or create a vmlinuz.mod.c containing the
missing module info for the match-id based aliases for built-in modules.

## Acknowledgements

Thanks to Greg Kroah-Hartman, Christophe Leroy, Luis Chamberlain and the
other Linux maintainers for being patient with me as I have worked
through learning the kernel workflow to get this series into a more
presentable state.

Thanks to Luis Chamberlain for raising the alternative of using kmod to
address the primary motivation of the patch series.

Also, thanks to Intel's kernel test robot <lkp@intel.com> for catching
issues that showed up on different kernel configurations.


Allen Webb (10):
  imx: Fix typo
  rockchip-mailbox: Fix typo
  scsi/BusLogic: Always include device id table
  stmpe-spi: Fix typo
  module.h: MODULE_DEVICE_TABLE for built-in modules
  modpost: Track module name for built-in modules
  modpost: Add -b option for emitting built-in aliases
  file2alias.c: Implement builtin.alias generation
  build: Add modules.builtin.alias
  Documentation: Include modules.builtin.alias

 .gitignore                         |  1 +
 Documentation/kbuild/kbuild.rst    |  6 ++
 Makefile                           |  1 +
 drivers/mailbox/rockchip-mailbox.c |  2 +-
 drivers/mfd/stmpe-spi.c            |  2 +-
 drivers/scsi/BusLogic.c            |  2 -
 drivers/soc/imx/imx8mp-blk-ctrl.c  |  2 +-
 include/linux/module.h             | 15 ++++-
 scripts/Makefile.modpost           | 17 +++++-
 scripts/mod/file2alias.c           | 94 +++++++++++++++++++++++-------
 scripts/mod/modpost.c              | 23 +++++++-
 scripts/mod/modpost.h              |  2 +
 12 files changed, 137 insertions(+), 30 deletions(-)

-- 
2.37.3
[PATCH v10 00/11] Generate modules.builtin.alias from match ids
Posted by Allen Webb 2 years, 5 months ago
Generate modules.builtin.alias from match ids

This patch series (v10) generates `modules.builtin.alias` during modpost.
The goal is for tools like USBGuard to leverage not only modules.aliases
but also `modules.builtin.aliases` to associate devices with the modules
that may be bound before deciding to authorize a device or not. This is
particularly useful in cases when new devices of a particular type
shouldn't be allowed part of the time like for lock screens.

Also included in this series are added documentation, style fixes and
fixes for build breakages for built-in modules that relied on
MODULE_DEVICE_TABLE being a no-op. Some of these were typos in
device table name that do not need aliases and one ifdef-ed out the
device table.

---

Generate modules.builtin.alias from match ids
=============================================

This series (v10) removes the `cc:stable` commit tags since the fixes
only are needed going forward. It also includes documentation updates
and unifies the MODULE_DEVICE_TABLE macro for both the builtin and
module case.

Additionally, rather than fixing the typo-ed device table names the
commits were updated to drop the broken MODULE_DEVICE_TABLE
invocations, since they belong to device types that would not benefit
from the intended purpose of `modules.builtin.alias`.

Note, cover letters were first added in v5.

  RFC (broken patch): https://lore.kernel.org/lkml/CAJzde042-M4UbpNYKw0eDVg4JqYmwmPYSsmgK+kCMTqsi+-2Yw@mail.gmail.com/
  v1 (missing v1 label): https://lore.kernel.org/lkml/20221111152852.2837363-1-allenwebb@google.com/
  v2 (missing v2 label): https://lore.kernel.org/lkml/20221128201332.3482092-1-allenwebb@google.com/
  v3: https://lore.kernel.org/lkml/20221129224313.455862-1-allenwebb@google.com/
  v4: https://lore.kernel.org/lkml/20221130221447.1202206-1-allenwebb@google.com/
  v5: https://lore.kernel.org/lkml/20221201211630.101541-1-allenwebb@google.com/
  v6: https://lore.kernel.org/lkml/20221202224540.1446952-1-allenwebb@google.com/
  v7: https://lore.kernel.org/lkml/20221216221703.294683-1-allenwebb@google.com/
  v8: https://lore.kernel.org/lkml/20221219191855.2010466-1-allenwebb@google.com/
  v9: https://lore.kernel.org/lkml/20221219204619.2205248-1-allenwebb@google.com/
  v10: This version

Patch series status
-------------------

This series should be close to ready.

Acknowledgements
----------------

Thanks to Greg Kroah-Hartman, Christophe Leroy, Luis Chamberlain and the
other Linux maintainers for being patient with me as I have worked
through learning the kernel workflow to get this series into a more
presentable state.

Thanks to Luis Chamberlain for raising the alternative of using kmod to
address the primary motivation of the patch series.

Thanks to Dmitry Torokhov and Benson Leung for feedback on the
USB authorization documentation for the driver API.

Also, thanks to Intel's kernel test robot <lkp@intel.com> for catching
issues that showed up with different kernel configurations.

Allen Webb (11):
  rockchip-mailbox: Remove unneeded MODULE_DEVICE_TABLE
  scsi/BusLogic: Always include device id table
  stmpe-spi: Fix MODULE_DEVICE_TABLE entries
  module.h: MODULE_DEVICE_TABLE for built-in modules
  modpost: Track module name for built-in modules
  modpost: Add -b option for emitting built-in aliases
  file2alias.c: Implement builtin.alias generation
  build: Add modules.builtin.alias
  Documentation: Include modules.builtin.alias
  Documentation: Update writing_usb_driver for built-in modules
  Documentation: add USB authorization document to driver-api

 .gitignore                                    |  1 +
 .../driver-api/usb/authorization.rst          | 71 ++++++++++++++
 Documentation/driver-api/usb/index.rst        |  1 +
 .../driver-api/usb/writing_usb_driver.rst     |  3 +
 Documentation/kbuild/kbuild.rst               |  7 ++
 Makefile                                      |  1 +
 drivers/mailbox/rockchip-mailbox.c            |  1 -
 drivers/mfd/stmpe-spi.c                       |  1 -
 drivers/scsi/BusLogic.c                       |  2 -
 include/linux/module.h                        | 36 ++++++--
 scripts/Makefile.modpost                      | 15 +++
 scripts/mod/file2alias.c                      | 92 ++++++++++++++-----
 scripts/mod/modpost.c                         | 30 +++++-
 scripts/mod/modpost.h                         |  2 +
 14 files changed, 229 insertions(+), 34 deletions(-)
 create mode 100644 Documentation/driver-api/usb/authorization.rst

-- 
2.39.2
[PATCH v10 01/11] rockchip-mailbox: Remove unneeded MODULE_DEVICE_TABLE
Posted by Allen Webb 2 years, 5 months ago
A one character difference in the name supplied to MODULE_DEVICE_TABLE
breaks compilation for ROCKCHIP_MBOX after built-in modules can
generate match-id based module aliases. Since this wasn't being used
before and builtin aliases aren't needed in this case, remove it.

This was not caught earlier because ROCKCHIP_MBOX can not be built as a
module and MODULE_DEVICE_TABLE is a no-op for built-in modules.

Fixes: f70ed3b5dc8b ("mailbox: rockchip: Add Rockchip mailbox driver")
Reported-by: kernel test robot <lkp@intel.com>
Link: https://lore.kernel.org/lkml/202212171140.NB93eVvI-lkp@intel.com/
Signed-off-by: Allen Webb <allenwebb@google.com>
---
 drivers/mailbox/rockchip-mailbox.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mailbox/rockchip-mailbox.c b/drivers/mailbox/rockchip-mailbox.c
index e02d3c9e3693..1f0adc283d1b 100644
--- a/drivers/mailbox/rockchip-mailbox.c
+++ b/drivers/mailbox/rockchip-mailbox.c
@@ -159,7 +159,6 @@ static const struct of_device_id rockchip_mbox_of_match[] = {
 	{ .compatible = "rockchip,rk3368-mailbox", .data = &rk3368_drv_data},
 	{ },
 };
-MODULE_DEVICE_TABLE(of, rockchp_mbox_of_match);
 
 static int rockchip_mbox_probe(struct platform_device *pdev)
 {
-- 
2.39.2
[PATCH v10 02/11] scsi/BusLogic: Always include device id table
Posted by Allen Webb 2 years, 5 months ago
A future patch makes use of the device table for built-in modules, so
do not ifdef out the match id table.

Reported-by: kernel test robot <lkp@intel.com>
Link: https://lore.kernel.org/lkml/202212171257.0oLypyYS-lkp@intel.com/
Signed-off-by: Allen Webb <allenwebb@google.com>
---
 drivers/scsi/BusLogic.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
index f7b7ffda1161..79fc8a24e614 100644
--- a/drivers/scsi/BusLogic.c
+++ b/drivers/scsi/BusLogic.c
@@ -3713,7 +3713,6 @@ static void __exit blogic_exit(void)
 
 __setup("BusLogic=", blogic_setup);
 
-#ifdef MODULE
 /*static struct pci_device_id blogic_pci_tbl[] = {
 	{ PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
@@ -3729,7 +3728,6 @@ static const struct pci_device_id blogic_pci_tbl[] = {
 	{PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT)},
 	{0, },
 };
-#endif
 MODULE_DEVICE_TABLE(pci, blogic_pci_tbl);
 
 module_init(blogic_init);
-- 
2.39.2
[PATCH v10 03/11] stmpe-spi: Fix MODULE_DEVICE_TABLE entries
Posted by Allen Webb 2 years, 5 months ago
A one character difference in the name supplied to MODULE_DEVICE_TABLE
breaks compilation for STMPE_SPI after built-in modules can generate
match-id based module aliases. Since this wasn't being used before and
builtin aliases aren't needed in this case, remove it.

This was not caught earlier because STMPE_SPI can not be built as a
module and MODULE_DEVICE_TABLE is a no-op for built-in modules.

Fixes: e789995d5c61 ("mfd: Add support for STMPE SPI interface")
Reported-by: kernel test robot <lkp@intel.com>
Link: https://lore.kernel.org/lkml/202212171140.NB93eVvI-lkp@intel.com/
Signed-off-by: Allen Webb <allenwebb@google.com>
---
 drivers/mfd/stmpe-spi.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mfd/stmpe-spi.c b/drivers/mfd/stmpe-spi.c
index e9cbf33502b3..e9cb6a635472 100644
--- a/drivers/mfd/stmpe-spi.c
+++ b/drivers/mfd/stmpe-spi.c
@@ -129,7 +129,6 @@ static const struct spi_device_id stmpe_spi_id[] = {
 	{ "stmpe2403", STMPE2403 },
 	{ }
 };
-MODULE_DEVICE_TABLE(spi, stmpe_id);
 
 static struct spi_driver stmpe_spi_driver = {
 	.driver = {
-- 
2.39.2
Re: [PATCH v10 03/11] stmpe-spi: Fix MODULE_DEVICE_TABLE entries
Posted by Luis Chamberlain 2 years, 3 months ago
On Thu, Apr 06, 2023 at 02:00:22PM -0500, Allen Webb wrote:
> A one character difference in the name supplied to MODULE_DEVICE_TABLE
> breaks compilation for STMPE_SPI after built-in modules can generate
> match-id based module aliases. Since this wasn't being used before and
> builtin aliases aren't needed in this case, remove it.
> 
> This was not caught earlier because STMPE_SPI can not be built as a
> module and MODULE_DEVICE_TABLE is a no-op for built-in modules.
> 
> Fixes: e789995d5c61 ("mfd: Add support for STMPE SPI interface")
> Reported-by: kernel test robot <lkp@intel.com>
> Link: https://lore.kernel.org/lkml/202212171140.NB93eVvI-lkp@intel.com/
> Signed-off-by: Allen Webb <allenwebb@google.com>
> ---

I'm happy to take patches 1-3 thorugh modules-next, but please try to
Cc the driver maintainers on the next iteration of this patch series
and let them know these are related to this work and see if you can
get their ACKs to go through another tree for this purpose.

  Luis
Re: [PATCH v10 03/11] stmpe-spi: Fix MODULE_DEVICE_TABLE entries
Posted by Luis Chamberlain 2 years, 3 months ago
On Thu, Apr 06, 2023 at 02:00:22PM -0500, Allen Webb wrote:
> A one character difference in the name supplied to MODULE_DEVICE_TABLE
> breaks compilation for STMPE_SPI after built-in modules can generate
> match-id based module aliases. Since this wasn't being used before and
> builtin aliases aren't needed in this case, remove it.
> 
> This was not caught earlier because STMPE_SPI can not be built as a
> module and MODULE_DEVICE_TABLE is a no-op for built-in modules.
> 
> Fixes: e789995d5c61 ("mfd: Add support for STMPE SPI interface")
> Reported-by: kernel test robot <lkp@intel.com>
> Link: https://lore.kernel.org/lkml/202212171140.NB93eVvI-lkp@intel.com/
> Signed-off-by: Allen Webb <allenwebb@google.com>
> ---

Oh feel free to add Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
on patches 1-3.

  Luis
[PATCH v10 04/11] module.h: MODULE_DEVICE_TABLE for built-in modules
Posted by Allen Webb 2 years, 5 months ago
Implement MODULE_DEVICE_TABLE for build-in modules to make it possible
to generate a builtin.alias file to complement modules.alias.

Signed-off-by: Allen Webb <allenwebb@google.com>
---
 include/linux/module.h | 36 +++++++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/include/linux/module.h b/include/linux/module.h
index 4435ad9439ab..b1cb12e06996 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -237,14 +237,36 @@ extern void cleanup_module(void);
 /* What your module does. */
 #define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description)
 
-#ifdef MODULE
-/* Creates an alias so file2alias.c can find device table. */
+/*
+ * Creates an alias so file2alias.c can find device table.
+ *
+ * Use this in cases where a device table is used to match devices because it
+ * surfaces match-id based module aliases to userspace for:
+ *   - Automatic module loading through modules.alias.
+ *   - Tools like USBGuard which block devices based on policy such as which
+ *     modules match a device.
+ *
+ * The only use-case for built-in drivers today is to enable userspace to
+ * prevent / allow probe for devices on certain subsystems even if the driver is
+ * already loaded. An example is the USB subsystem with its authorized_default
+ * sysfs attribute. For more details refer to the kernel's Documentation for USB
+ * about authorized_default.
+ *
+ * The module name is included in the alias for two reasons:
+ *   - It avoids creating two aliases with the same name for built-in modules.
+ *     Historically MODULE_DEVICE_TABLE was a no-op for built-in modules, so
+ *     there was nothing to stop different modules from having the same device
+ *     table name and consequently the same alias when building as a module.
+ *   - The module name is needed by files2alias.c to associate a particular
+ *     device table with its associated module for built-in modules since
+ *     files2alias would otherwise see the module name as `vmlinuz.o`.
+ */
 #define MODULE_DEVICE_TABLE(type, name)					\
-extern typeof(name) __mod_##type##__##name##_device_table		\
-  __attribute__ ((unused, alias(__stringify(name))))
-#else  /* !MODULE */
-#define MODULE_DEVICE_TABLE(type, name)
-#endif
+extern void *CONCATENATE(						\
+	CONCATENATE(__mod_##type##__##name##__,				\
+		__KBUILD_MODNAME),					\
+	_device_table)							\
+	__attribute__ ((unused, alias(__stringify(name))))
 
 /* Version of form [<epoch>:]<version>[-<extra-version>].
  * Or for CVS/RCS ID version, everything but the number is stripped.
-- 
2.39.2
Re: [PATCH v10 04/11] module.h: MODULE_DEVICE_TABLE for built-in modules
Posted by Luis Chamberlain 2 years, 3 months ago
On Thu, Apr 06, 2023 at 02:00:23PM -0500, Allen Webb wrote:
> Implement MODULE_DEVICE_TABLE for build-in modules to make it possible
> to generate a builtin.alias file to complement modules.alias.
> 
> Signed-off-by: Allen Webb <allenwebb@google.com>
> ---
>  include/linux/module.h | 36 +++++++++++++++++++++++++++++-------
>  1 file changed, 29 insertions(+), 7 deletions(-)
> 
> diff --git a/include/linux/module.h b/include/linux/module.h
> index 4435ad9439ab..b1cb12e06996 100644
> --- a/include/linux/module.h
> +++ b/include/linux/module.h
> @@ -237,14 +237,36 @@ extern void cleanup_module(void);
>  /* What your module does. */
>  #define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description)
>  
> -#ifdef MODULE
> -/* Creates an alias so file2alias.c can find device table. */
> +/*
> + * Creates an alias so file2alias.c can find device table.
> + *
> + * Use this in cases where a device table is used to match devices because it
> + * surfaces match-id based module aliases to userspace for:
> + *   - Automatic module loading through modules.alias.
> + *   - Tools like USBGuard which block devices based on policy such as which
> + *     modules match a device.
> + *
> + * The only use-case for built-in drivers today is to enable userspace to
> + * prevent / allow probe for devices on certain subsystems even if the driver is
> + * already loaded. An example is the USB subsystem with its authorized_default
> + * sysfs attribute. For more details refer to the kernel's Documentation for USB
> + * about authorized_default.
> + *
> + * The module name is included in the alias for two reasons:
> + *   - It avoids creating two aliases with the same name for built-in modules.
> + *     Historically MODULE_DEVICE_TABLE was a no-op for built-in modules, so
> + *     there was nothing to stop different modules from having the same device
> + *     table name and consequently the same alias when building as a module.
> + *   - The module name is needed by files2alias.c to associate a particular
> + *     device table with its associated module for built-in modules since
> + *     files2alias would otherwise see the module name as `vmlinuz.o`.
> + */
>  #define MODULE_DEVICE_TABLE(type, name)					\
> -extern typeof(name) __mod_##type##__##name##_device_table		\
> -  __attribute__ ((unused, alias(__stringify(name))))
> -#else  /* !MODULE */
> -#define MODULE_DEVICE_TABLE(type, name)
> -#endif
> +extern void *CONCATENATE(						\
> +	CONCATENATE(__mod_##type##__##name##__,				\
> +		__KBUILD_MODNAME),					\
> +	_device_table)							\
> +	__attribute__ ((unused, alias(__stringify(name))))

Why does it seem like we're changing extern typeof(name) to a void *?
Also the addition of CONCATENATE() makes it not clear if you are
modifying the definition before, so it would be good to first add
CONCATENATE() to replace the old way without making any functional
changes first. Then a secondary patch which extends the world for
built-in.

  Luis
[PATCH v10 05/11] modpost: Track module name for built-in modules
Posted by Allen Webb 2 years, 5 months ago
Keep track of the module name when processing match table symbols.

Signed-off-by: Allen Webb <allenwebb@google.com>
---
 scripts/mod/file2alias.c | 39 +++++++++++++++++++++++++++++++++++----
 scripts/mod/modpost.h    |  1 +
 2 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 91c2e7ba5e52..b392d51c3b06 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -28,6 +28,7 @@ typedef Elf64_Addr	kernel_ulong_t;
 #include <stdint.h>
 #endif
 
+#include <assert.h>
 #include <ctype.h>
 #include <stdbool.h>
 
@@ -1540,9 +1541,9 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
 			Elf_Sym *sym, const char *symname)
 {
 	void *symval;
-	char *zeros = NULL;
-	const char *name, *identifier;
-	unsigned int namelen;
+	char *zeros = NULL, *modname_str = NULL;
+	const char *name, *identifier, *modname;
+	unsigned int namelen, modnamelen;
 
 	/* We're looking for a section relative symbol */
 	if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
@@ -1552,7 +1553,12 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
 	if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
 		return;
 
-	/* All our symbols are of form __mod_<name>__<identifier>_device_table. */
+	/*
+	 * All our symbols are either of form
+	 *   __mod_<name>__<identifier>_device_table
+	 * or
+	 *   __mod_<name>__<identifier>__kmod_<builtin-name>_device_table
+	 */
 	if (strncmp(symname, "__mod_", strlen("__mod_")))
 		return;
 	name = symname + strlen("__mod_");
@@ -1564,8 +1570,30 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
 	identifier = strstr(name, "__");
 	if (!identifier)
 		return;
+	modnamelen = namelen;
 	namelen = identifier - name;
 
+	/*
+	 * In the vmlinuz.o case we want to handle __kmod_ so aliases from
+	 * builtin modules are attributed correctly.
+	 */
+	modname = strstr(identifier + 2, "__kmod_");
+	if (modname) {
+		modname += strlen("__kmod_");
+		modnamelen -= (modname - name) + strlen("_device_table");
+		modname_str = malloc(modnamelen + 1);
+		/* We don't want to continue if the allocation fails. */
+		assert(modname_str);
+		memcpy(modname_str, modname, modnamelen);
+		modname_str[modnamelen] = '\0';
+	}
+
+	if (modname_str)
+		modname = modname_str;
+	else
+		modname = mod->name;
+	mod->builtin_name = modname;
+
 	/* Handle all-NULL symbols allocated into .bss */
 	if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
 		zeros = calloc(1, sym->st_size);
@@ -1597,6 +1625,9 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
 		}
 	}
 	free(zeros);
+	mod->builtin_name = NULL;
+	if (modname_str)
+		free(modname_str);
 }
 
 /* Now add out buffered information to the generated C source */
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 1178f40a73f3..34fe5fc0b02c 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -128,6 +128,7 @@ struct module {
 	struct list_head missing_namespaces;
 	// Actual imported namespaces
 	struct list_head imported_namespaces;
+	const char *builtin_name;
 	char name[];
 };
 
-- 
2.39.2
Re: [PATCH v10 05/11] modpost: Track module name for built-in modules
Posted by Luis Chamberlain 2 years, 3 months ago
On Thu, Apr 06, 2023 at 02:00:24PM -0500, Allen Webb wrote:
> Keep track of the module name when processing match table symbols.

This should mention why this would be good. Otherwise, think about it,
ok, it's done but why? If the reason is that it will be needed later
you need to say that in this commit log entry. If its not used now, it
also needs to say that in this commit log so it is easier to review
and set expecataions correctly for the reviewer.

  Luis

> Signed-off-by: Allen Webb <allenwebb@google.com>
> ---
>  scripts/mod/file2alias.c | 39 +++++++++++++++++++++++++++++++++++----
>  scripts/mod/modpost.h    |  1 +
>  2 files changed, 36 insertions(+), 4 deletions(-)
> 
> diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
> index 91c2e7ba5e52..b392d51c3b06 100644
> --- a/scripts/mod/file2alias.c
> +++ b/scripts/mod/file2alias.c
> @@ -28,6 +28,7 @@ typedef Elf64_Addr	kernel_ulong_t;
>  #include <stdint.h>
>  #endif
>  
> +#include <assert.h>
>  #include <ctype.h>
>  #include <stdbool.h>
>  
> @@ -1540,9 +1541,9 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
>  			Elf_Sym *sym, const char *symname)
>  {
>  	void *symval;
> -	char *zeros = NULL;
> -	const char *name, *identifier;
> -	unsigned int namelen;
> +	char *zeros = NULL, *modname_str = NULL;
> +	const char *name, *identifier, *modname;
> +	unsigned int namelen, modnamelen;
>  
>  	/* We're looking for a section relative symbol */
>  	if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
> @@ -1552,7 +1553,12 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
>  	if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
>  		return;
>  
> -	/* All our symbols are of form __mod_<name>__<identifier>_device_table. */
> +	/*
> +	 * All our symbols are either of form
> +	 *   __mod_<name>__<identifier>_device_table
> +	 * or
> +	 *   __mod_<name>__<identifier>__kmod_<builtin-name>_device_table
> +	 */
>  	if (strncmp(symname, "__mod_", strlen("__mod_")))
>  		return;
>  	name = symname + strlen("__mod_");
> @@ -1564,8 +1570,30 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
>  	identifier = strstr(name, "__");
>  	if (!identifier)
>  		return;
> +	modnamelen = namelen;
>  	namelen = identifier - name;
>  
> +	/*
> +	 * In the vmlinuz.o case we want to handle __kmod_ so aliases from
> +	 * builtin modules are attributed correctly.
> +	 */
> +	modname = strstr(identifier + 2, "__kmod_");
> +	if (modname) {
> +		modname += strlen("__kmod_");
> +		modnamelen -= (modname - name) + strlen("_device_table");
> +		modname_str = malloc(modnamelen + 1);
> +		/* We don't want to continue if the allocation fails. */
> +		assert(modname_str);
> +		memcpy(modname_str, modname, modnamelen);
> +		modname_str[modnamelen] = '\0';
> +	}
> +
> +	if (modname_str)
> +		modname = modname_str;
> +	else
> +		modname = mod->name;
> +	mod->builtin_name = modname;
> +
>  	/* Handle all-NULL symbols allocated into .bss */
>  	if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
>  		zeros = calloc(1, sym->st_size);
> @@ -1597,6 +1625,9 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
>  		}
>  	}
>  	free(zeros);
> +	mod->builtin_name = NULL;
> +	if (modname_str)
> +		free(modname_str);
>  }
>  
>  /* Now add out buffered information to the generated C source */
> diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
> index 1178f40a73f3..34fe5fc0b02c 100644
> --- a/scripts/mod/modpost.h
> +++ b/scripts/mod/modpost.h
> @@ -128,6 +128,7 @@ struct module {
>  	struct list_head missing_namespaces;
>  	// Actual imported namespaces
>  	struct list_head imported_namespaces;
> +	const char *builtin_name;
>  	char name[];
>  };
>  
> -- 
> 2.39.2
>
Re: [PATCH v10 05/11] modpost: Track module name for built-in modules
Posted by Greg KH 2 years, 5 months ago
On Thu, Apr 06, 2023 at 02:00:24PM -0500, Allen Webb wrote:
> Keep track of the module name when processing match table symbols.

This describes _what_ you are doing here, but no explanation for _why_
you want to do this.

thanks,

greg k-h
[PATCH v10 06/11] modpost: Add -b option for emitting built-in aliases
Posted by Allen Webb 2 years, 5 months ago
This adds a command line option for writing the match-id based built-in
aliases to a file. A future patch extends file2alias.c to support this
command.

The -b option accepts the output path as a parameter and requires
vmlinuz.o to be one of the input files for the aliases to be found.

Signed-off-by: Allen Webb <allenwebb@google.com>
---
 scripts/mod/modpost.c | 30 ++++++++++++++++++++++++++++--
 scripts/mod/modpost.h |  1 +
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index efff8078e395..2e452aec0fc6 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -2173,6 +2173,19 @@ static void write_if_changed(struct buffer *b, const char *fname)
 	write_buf(b, fname);
 }
 
+/* Write the builtin aliases to the specified file. */
+static void write_builtin(const char *fname)
+{
+	struct buffer buf = { };
+	struct module *mod;
+
+	list_for_each_entry(mod, &modules, list)
+		buf_write(&buf, mod->modalias_buf.p, mod->modalias_buf.pos);
+
+	write_if_changed(&buf, fname);
+	free(buf.p);
+}
+
 static void write_vmlinux_export_c_file(struct module *mod)
 {
 	struct buffer buf = { };
@@ -2329,13 +2342,23 @@ int main(int argc, char **argv)
 {
 	struct module *mod;
 	char *missing_namespace_deps = NULL;
-	char *dump_write = NULL, *files_source = NULL;
+	char *builtin_write = NULL, *dump_write = NULL, *files_source = NULL;
 	int opt;
 	LIST_HEAD(dump_lists);
 	struct dump_list *dl, *dl2;
 
-	while ((opt = getopt(argc, argv, "ei:mnT:o:awENd:")) != -1) {
+	while ((opt = getopt(argc, argv, "b:ei:mnT:o:awENd:")) != -1) {
 		switch (opt) {
+		case 'b':
+			/*
+			 * Writes the match-id based built-in module aliases to
+			 * the specified path.
+			 *
+			 * vmlinuz.o needs to be one of the input files for the
+			 * aliases to be found.
+			 */
+			builtin_write = optarg;
+			break;
 		case 'e':
 			external_module = true;
 			break;
@@ -2398,6 +2421,9 @@ int main(int argc, char **argv)
 			write_mod_c_file(mod);
 	}
 
+	if (builtin_write)
+		write_builtin(builtin_write);
+
 	if (missing_namespace_deps)
 		write_namespace_deps_files(missing_namespace_deps);
 
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 34fe5fc0b02c..c55a6aeb46bf 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -123,6 +123,7 @@ struct module {
 	bool has_init;
 	bool has_cleanup;
 	struct buffer dev_table_buf;
+	struct buffer modalias_buf;
 	char	     srcversion[25];
 	// Missing namespace dependencies
 	struct list_head missing_namespaces;
-- 
2.39.2
Re: [PATCH v10 06/11] modpost: Add -b option for emitting built-in aliases
Posted by Luis Chamberlain 2 years, 3 months ago
On Thu, Apr 06, 2023 at 02:00:25PM -0500, Allen Webb wrote:
> This adds a command line option for writing the match-id based 

Can you explain in your commit log and in code what is "match-id" ?
Do we not have this documeted anywhere perhaps where we can point to
what it is?

> built-in
> aliases to a file. A future patch extends file2alias.c to support this
> command.
> 
> The -b option accepts the output path as a parameter and requires
> vmlinuz.o to be one of the input files for the aliases to be found.
> 
> Signed-off-by: Allen Webb <allenwebb@google.com>
> ---
>  scripts/mod/modpost.c | 30 ++++++++++++++++++++++++++++--
>  scripts/mod/modpost.h |  1 +
>  2 files changed, 29 insertions(+), 2 deletions(-)
> 
> diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> index efff8078e395..2e452aec0fc6 100644
> --- a/scripts/mod/modpost.c
> +++ b/scripts/mod/modpost.c
> @@ -2173,6 +2173,19 @@ static void write_if_changed(struct buffer *b, const char *fname)
>  	write_buf(b, fname);
>  }
>  
> +/* Write the builtin aliases to the specified file. */
> +static void write_builtin(const char *fname)
> +{
> +	struct buffer buf = { };
> +	struct module *mod;
> +
> +	list_for_each_entry(mod, &modules, list)
> +		buf_write(&buf, mod->modalias_buf.p, mod->modalias_buf.pos);
> +
> +	write_if_changed(&buf, fname);
> +	free(buf.p);
> +}
> +
>  static void write_vmlinux_export_c_file(struct module *mod)
>  {
>  	struct buffer buf = { };
> @@ -2329,13 +2342,23 @@ int main(int argc, char **argv)
>  {
>  	struct module *mod;
>  	char *missing_namespace_deps = NULL;
> -	char *dump_write = NULL, *files_source = NULL;
> +	char *builtin_write = NULL, *dump_write = NULL, *files_source = NULL;
>  	int opt;
>  	LIST_HEAD(dump_lists);
>  	struct dump_list *dl, *dl2;
>  
> -	while ((opt = getopt(argc, argv, "ei:mnT:o:awENd:")) != -1) {
> +	while ((opt = getopt(argc, argv, "b:ei:mnT:o:awENd:")) != -1) {
>  		switch (opt) {
> +		case 'b':
> +			/*
> +			 * Writes the match-id based built-in module aliases to
> +			 * the specified path.
> +			 *
> +			 * vmlinuz.o needs to be one of the input files for the
> +			 * aliases to be found.
> +			 */
> +			builtin_write = optarg;
> +			break;
>  		case 'e':
>  			external_module = true;
>  			break;
> @@ -2398,6 +2421,9 @@ int main(int argc, char **argv)
>  			write_mod_c_file(mod);
>  	}
>  
> +	if (builtin_write)
> +		write_builtin(builtin_write);
> +
>  	if (missing_namespace_deps)
>  		write_namespace_deps_files(missing_namespace_deps);
>  
> diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
> index 34fe5fc0b02c..c55a6aeb46bf 100644
> --- a/scripts/mod/modpost.h
> +++ b/scripts/mod/modpost.h
> @@ -123,6 +123,7 @@ struct module {
>  	bool has_init;
>  	bool has_cleanup;
>  	struct buffer dev_table_buf;
> +	struct buffer modalias_buf;
>  	char	     srcversion[25];
>  	// Missing namespace dependencies
>  	struct list_head missing_namespaces;
> -- 
> 2.39.2
>
[PATCH v10 07/11] file2alias.c: Implement builtin.alias generation
Posted by Allen Webb 2 years, 5 months ago
This populates the mod->modalias_buf with aliases for built-in modules
when modpost is run against vmlinuz.o.

Signed-off-by: Allen Webb <allenwebb@google.com>
---
 scripts/mod/file2alias.c | 61 ++++++++++++++++++++++++++--------------
 1 file changed, 40 insertions(+), 21 deletions(-)

diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index b392d51c3b06..3793d4632b94 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -233,6 +233,8 @@ static void do_usb_entry(void *symval,
 	add_wildcard(alias);
 	buf_printf(&mod->dev_table_buf,
 		   "MODULE_ALIAS(\"%s\");\n", alias);
+	if (mod->builtin_name)
+		buf_printf(&mod->modalias_buf, "alias %s %s\n", alias, mod->builtin_name);
 }
 
 /* Handles increment/decrement of BCD formatted integers */
@@ -377,9 +379,13 @@ static void do_of_entry_multi(void *symval, struct module *mod)
 			*tmp = '_';
 
 	buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias);
+	if (mod->builtin_name)
+		buf_printf(&mod->modalias_buf, "alias %s %s\n", alias, mod->builtin_name);
 	strcat(alias, "C");
 	add_wildcard(alias);
 	buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias);
+	if (mod->builtin_name)
+		buf_printf(&mod->modalias_buf, "alias %s %s\n", alias, mod->builtin_name);
 }
 
 static void do_of_table(void *symval, unsigned long size,
@@ -611,12 +617,18 @@ static void do_pnp_device_entry(void *symval, unsigned long size,
 
 		buf_printf(&mod->dev_table_buf,
 			   "MODULE_ALIAS(\"pnp:d%s*\");\n", *id);
+		if (mod->builtin_name)
+			buf_printf(&mod->modalias_buf, "alias pnp:d%s* %s\n",
+				   *id, mod->builtin_name);
 
 		/* fix broken pnp bus lowercasing */
 		for (j = 0; j < sizeof(acpi_id); j++)
 			acpi_id[j] = toupper((*id)[j]);
 		buf_printf(&mod->dev_table_buf,
 			   "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id);
+		if (mod->builtin_name)
+			buf_printf(&mod->modalias_buf, "alias acpi*:%s:* %s\n",
+				   acpi_id, mod->builtin_name);
 	}
 }
 
@@ -638,6 +650,8 @@ static void do_pnp_card_entries(void *symval, unsigned long size,
 			const char *id = (char *)(*devs)[j].id;
 			int i2, j2;
 			int dup = 0;
+			char acpi_id[PNP_ID_LEN];
+			int k;
 
 			if (!id[0])
 				break;
@@ -663,19 +677,23 @@ static void do_pnp_card_entries(void *symval, unsigned long size,
 			}
 
 			/* add an individual alias for every device entry */
-			if (!dup) {
-				char acpi_id[PNP_ID_LEN];
-				int k;
-
-				buf_printf(&mod->dev_table_buf,
-					   "MODULE_ALIAS(\"pnp:d%s*\");\n", id);
-
-				/* fix broken pnp bus lowercasing */
-				for (k = 0; k < sizeof(acpi_id); k++)
-					acpi_id[k] = toupper(id[k]);
-				buf_printf(&mod->dev_table_buf,
-					   "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id);
-			}
+			if (dup)
+				continue;
+
+			buf_printf(&mod->dev_table_buf,
+				   "MODULE_ALIAS(\"pnp:d%s*\");\n", id);
+			if (mod->builtin_name)
+				buf_printf(&mod->modalias_buf, "alias pnp:d%s* %s\n",
+					   id, mod->builtin_name);
+
+			/* fix broken pnp bus lowercasing */
+			for (k = 0; k < sizeof(acpi_id); k++)
+				acpi_id[k] = toupper(id[k]);
+			buf_printf(&mod->dev_table_buf,
+				   "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id);
+			if (mod->builtin_name)
+				buf_printf(&mod->modalias_buf, "alias acpi*:%s:* %s\n",
+					   acpi_id, mod->builtin_name);
 		}
 	}
 }
@@ -1476,10 +1494,13 @@ static void do_table(void *symval, unsigned long size,
 	size -= id_size;
 
 	for (i = 0; i < size; i += id_size) {
-		if (do_entry(mod->name, symval+i, alias)) {
-			buf_printf(&mod->dev_table_buf,
-				   "MODULE_ALIAS(\"%s\");\n", alias);
-		}
+		if (!do_entry(mod->name, symval + i, alias))
+			continue;
+		buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias);
+		if (!mod->builtin_name)
+			continue;
+		buf_printf(&mod->modalias_buf, "alias %s %s\n", alias,
+			   mod->builtin_name);
 	}
 }
 
@@ -1554,10 +1575,8 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
 		return;
 
 	/*
-	 * All our symbols are either of form
-	 *   __mod_<name>__<identifier>_device_table
-	 * or
-	 *   __mod_<name>__<identifier>__kmod_<builtin-name>_device_table
+	 * All our symbols are of form
+	 *   __mod_<name>__<identifier>__kmod_<modname>_device_table
 	 */
 	if (strncmp(symname, "__mod_", strlen("__mod_")))
 		return;
-- 
2.39.2
Re: [PATCH v10 07/11] file2alias.c: Implement builtin.alias generation
Posted by Luis Chamberlain 2 years, 3 months ago
On Thu, Apr 06, 2023 at 02:00:26PM -0500, Allen Webb wrote:
> This populates the mod->modalias_buf with aliases for built-in modules
> when modpost is run against vmlinuz.o.

The commit log should describe why. And if its not used now why is it
being introduced separately. If its to make changes eaiser to read it
shoudl say so.

So builtin thing is set but is it used at this point? Does this patch
make any functional changes? If not why not?

> Signed-off-by: Allen Webb <allenwebb@google.com>
> ---
>  scripts/mod/file2alias.c | 61 ++++++++++++++++++++++++++--------------
>  1 file changed, 40 insertions(+), 21 deletions(-)
> 
> diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
> index b392d51c3b06..3793d4632b94 100644
> --- a/scripts/mod/file2alias.c
> +++ b/scripts/mod/file2alias.c
> @@ -233,6 +233,8 @@ static void do_usb_entry(void *symval,
>  	add_wildcard(alias);
>  	buf_printf(&mod->dev_table_buf,
>  		   "MODULE_ALIAS(\"%s\");\n", alias);
> +	if (mod->builtin_name)
> +		buf_printf(&mod->modalias_buf, "alias %s %s\n", alias, mod->builtin_name);
>  }
>  
>  /* Handles increment/decrement of BCD formatted integers */
> @@ -377,9 +379,13 @@ static void do_of_entry_multi(void *symval, struct module *mod)
>  			*tmp = '_';
>  
>  	buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias);
> +	if (mod->builtin_name)
> +		buf_printf(&mod->modalias_buf, "alias %s %s\n", alias, mod->builtin_name);
>  	strcat(alias, "C");
>  	add_wildcard(alias);
>  	buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias);
> +	if (mod->builtin_name)
> +		buf_printf(&mod->modalias_buf, "alias %s %s\n", alias, mod->builtin_name);
>  }
>  
>  static void do_of_table(void *symval, unsigned long size,
> @@ -611,12 +617,18 @@ static void do_pnp_device_entry(void *symval, unsigned long size,
>  
>  		buf_printf(&mod->dev_table_buf,
>  			   "MODULE_ALIAS(\"pnp:d%s*\");\n", *id);
> +		if (mod->builtin_name)
> +			buf_printf(&mod->modalias_buf, "alias pnp:d%s* %s\n",
> +				   *id, mod->builtin_name);
>  
>  		/* fix broken pnp bus lowercasing */
>  		for (j = 0; j < sizeof(acpi_id); j++)
>  			acpi_id[j] = toupper((*id)[j]);
>  		buf_printf(&mod->dev_table_buf,
>  			   "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id);
> +		if (mod->builtin_name)
> +			buf_printf(&mod->modalias_buf, "alias acpi*:%s:* %s\n",
> +				   acpi_id, mod->builtin_name);
>  	}
>  }
>  
> @@ -638,6 +650,8 @@ static void do_pnp_card_entries(void *symval, unsigned long size,
>  			const char *id = (char *)(*devs)[j].id;
>  			int i2, j2;
>  			int dup = 0;
> +			char acpi_id[PNP_ID_LEN];
> +			int k;
>  
>  			if (!id[0])
>  				break;
> @@ -663,19 +677,23 @@ static void do_pnp_card_entries(void *symval, unsigned long size,
>  			}
>  
>  			/* add an individual alias for every device entry */
> -			if (!dup) {
> -				char acpi_id[PNP_ID_LEN];
> -				int k;
> -
> -				buf_printf(&mod->dev_table_buf,
> -					   "MODULE_ALIAS(\"pnp:d%s*\");\n", id);
> -
> -				/* fix broken pnp bus lowercasing */
> -				for (k = 0; k < sizeof(acpi_id); k++)
> -					acpi_id[k] = toupper(id[k]);
> -				buf_printf(&mod->dev_table_buf,
> -					   "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id);
> -			}
> +			if (dup)
> +				continue;

The change from !dup to (dup) continue makes your changes harder to
read. It would be good to make that change separately so to make it
easier to read what you are doing differently.

> +
> +			buf_printf(&mod->dev_table_buf,
> +				   "MODULE_ALIAS(\"pnp:d%s*\");\n", id);
> +			if (mod->builtin_name)
> +				buf_printf(&mod->modalias_buf, "alias pnp:d%s* %s\n",
> +					   id, mod->builtin_name);
> +
> +			/* fix broken pnp bus lowercasing */
> +			for (k = 0; k < sizeof(acpi_id); k++)
> +				acpi_id[k] = toupper(id[k]);
> +			buf_printf(&mod->dev_table_buf,
> +				   "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id);
> +			if (mod->builtin_name)
> +				buf_printf(&mod->modalias_buf, "alias acpi*:%s:* %s\n",
> +					   acpi_id, mod->builtin_name);
>  		}
>  	}
>  }
> @@ -1476,10 +1494,13 @@ static void do_table(void *symval, unsigned long size,
>  	size -= id_size;
>  
>  	for (i = 0; i < size; i += id_size) {
> -		if (do_entry(mod->name, symval+i, alias)) {
> -			buf_printf(&mod->dev_table_buf,
> -				   "MODULE_ALIAS(\"%s\");\n", alias);
> -		}
> +		if (!do_entry(mod->name, symval + i, alias))
> +			continue;

Same here. You could just fold the changes which negate the check into
and shif the code into one patch with 0 functional changes. Then a
second patch with your changes.

> +		buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias);
> +		if (!mod->builtin_name)
> +			continue;
> +		buf_printf(&mod->modalias_buf, "alias %s %s\n", alias,
> +			   mod->builtin_name);
>  	}
>  }
>  
> @@ -1554,10 +1575,8 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
>  		return;
>  
>  	/*
> -	 * All our symbols are either of form
> -	 *   __mod_<name>__<identifier>_device_table
> -	 * or
> -	 *   __mod_<name>__<identifier>__kmod_<builtin-name>_device_table
> +	 * All our symbols are of form
> +	 *   __mod_<name>__<identifier>__kmod_<modname>_device_table
>  	 */
>  	if (strncmp(symname, "__mod_", strlen("__mod_")))
>  		return;
> -- 
> 2.39.2
>
[PATCH v10 08/11] build: Add modules.builtin.alias
Posted by Allen Webb 2 years, 5 months ago
Generate modules.builtin.alias using modpost and install it with the
modules.

Signed-off-by: Allen Webb <allenwebb@google.com>
---
 .gitignore               |  1 +
 Makefile                 |  1 +
 scripts/Makefile.modpost | 15 +++++++++++++++
 3 files changed, 17 insertions(+)

diff --git a/.gitignore b/.gitignore
index 13a7f08a3d73..ddaa622bddac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -71,6 +71,7 @@ modules.order
 /System.map
 /Module.markers
 /modules.builtin
+/modules.builtin.alias
 /modules.builtin.modinfo
 /modules.nsdeps
 
diff --git a/Makefile b/Makefile
index a2c310df2145..43dcc1ea5fcf 100644
--- a/Makefile
+++ b/Makefile
@@ -1578,6 +1578,7 @@ __modinst_pre:
 	fi
 	@sed 's:^\(.*\)\.o$$:kernel/\1.ko:' modules.order > $(MODLIB)/modules.order
 	@cp -f modules.builtin $(MODLIB)/
+	@cp -f modules.builtin.alias $(MODLIB)/
 	@cp -f $(objtree)/modules.builtin.modinfo $(MODLIB)/
 
 endif # CONFIG_MODULES
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 0980c58d8afc..e3ecc17a7a19 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -15,6 +15,7 @@
 # 2) modpost is then used to
 # 3)  create one <module>.mod.c file per module
 # 4)  create one Module.symvers file with CRC for all exported symbols
+# 5)  create modules.builtin.alias the aliases for built-in modules
 
 # Step 3 is used to place certain information in the module's ELF
 # section, including information such as:
@@ -63,6 +64,20 @@ modpost-args += -T $(MODORDER)
 modpost-deps += $(MODORDER)
 endif
 
+ifneq ($(wildcard vmlinux.o),)
+output-builtin.alias := modules.builtin.alias
+modpost-args += -b .modules.builtin.alias.in
+.modules.builtin.alias.in: $(output-symdump)
+	@# Building $(output-symdump) generates .modules.builtin.alias.in as a
+	@# side effect.
+	@[ -e $@ ] || $(MODPOST) -b .modules.builtin.alias.in vmlinux.o
+
+$(output-builtin.alias): .modules.builtin.alias.in
+	sort -o $@ $^
+
+__modpost: $(output-builtin.alias)
+endif
+
 ifeq ($(KBUILD_EXTMOD),)
 
 # Generate the list of in-tree objects in vmlinux
-- 
2.39.2
Re: [PATCH v10 08/11] build: Add modules.builtin.alias
Posted by Luis Chamberlain 2 years, 3 months ago
On Thu, Apr 06, 2023 at 02:00:27PM -0500, Allen Webb wrote:
> Generate modules.builtin.alias using modpost and install it with the
> modules.

Why? This is probably one of the more important commits and the
commit log is pretty slim.

> Signed-off-by: Allen Webb <allenwebb@google.com>
> ---
>  .gitignore               |  1 +
>  Makefile                 |  1 +
>  scripts/Makefile.modpost | 15 +++++++++++++++
>  3 files changed, 17 insertions(+)
> 
> diff --git a/.gitignore b/.gitignore
> index 13a7f08a3d73..ddaa622bddac 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -71,6 +71,7 @@ modules.order
>  /System.map
>  /Module.markers
>  /modules.builtin
> +/modules.builtin.alias
>  /modules.builtin.modinfo
>  /modules.nsdeps
>  
> diff --git a/Makefile b/Makefile
> index a2c310df2145..43dcc1ea5fcf 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1578,6 +1578,7 @@ __modinst_pre:
>  	fi
>  	@sed 's:^\(.*\)\.o$$:kernel/\1.ko:' modules.order > $(MODLIB)/modules.order
>  	@cp -f modules.builtin $(MODLIB)/
> +	@cp -f modules.builtin.alias $(MODLIB)/
>  	@cp -f $(objtree)/modules.builtin.modinfo $(MODLIB)/
>  
>  endif # CONFIG_MODULES
> diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
> index 0980c58d8afc..e3ecc17a7a19 100644
> --- a/scripts/Makefile.modpost
> +++ b/scripts/Makefile.modpost
> @@ -15,6 +15,7 @@
>  # 2) modpost is then used to
>  # 3)  create one <module>.mod.c file per module
>  # 4)  create one Module.symvers file with CRC for all exported symbols
> +# 5)  create modules.builtin.alias the aliases for built-in modules

Does everyone want that file?

>  # Step 3 is used to place certain information in the module's ELF
>  # section, including information such as:
> @@ -63,6 +64,20 @@ modpost-args += -T $(MODORDER)
>  modpost-deps += $(MODORDER)
>  endif
>  
> +ifneq ($(wildcard vmlinux.o),)
> +output-builtin.alias := modules.builtin.alias
> +modpost-args += -b .modules.builtin.alias.in
> +.modules.builtin.alias.in: $(output-symdump)
> +	@# Building $(output-symdump) generates .modules.builtin.alias.in as a
> +	@# side effect.
> +	@[ -e $@ ] || $(MODPOST) -b .modules.builtin.alias.in vmlinux.o

Does using -b create a delay in builds ? What is the effect on build
time on a typical 4-core or 8-core build? Does everyone want it?

Should we add a new option which lets people decide if they want this
at build time or not?

  Luis

> +
> +$(output-builtin.alias): .modules.builtin.alias.in
> +	sort -o $@ $^
> +
> +__modpost: $(output-builtin.alias)
> +endif
> +
>  ifeq ($(KBUILD_EXTMOD),)
>  
>  # Generate the list of in-tree objects in vmlinux
> -- 
> 2.39.2
>
Re: [PATCH v10 08/11] build: Add modules.builtin.alias
Posted by Allen Webb 2 years, 1 month ago
I finally got a chance to go through the comments and work on a
follow-up to this series, but it probably makes sense to get this
sorted ahead of the follow-up (if possible).

On Wed, May 24, 2023 at 2:02 AM Luis Chamberlain <mcgrof@kernel.org> wrote:
>
> On Thu, Apr 06, 2023 at 02:00:27PM -0500, Allen Webb wrote:
> > Generate modules.builtin.alias using modpost and install it with the
> > modules.
>
> Why? This is probably one of the more important commits and the
> commit log is pretty slim.
>
> > Signed-off-by: Allen Webb <allenwebb@google.com>
> > ---
> >  .gitignore               |  1 +
> >  Makefile                 |  1 +
> >  scripts/Makefile.modpost | 15 +++++++++++++++
> >  3 files changed, 17 insertions(+)
> >
> > diff --git a/.gitignore b/.gitignore
> > index 13a7f08a3d73..ddaa622bddac 100644
> > --- a/.gitignore
> > +++ b/.gitignore
> > @@ -71,6 +71,7 @@ modules.order
> >  /System.map
> >  /Module.markers
> >  /modules.builtin
> > +/modules.builtin.alias
> >  /modules.builtin.modinfo
> >  /modules.nsdeps
> >
> > diff --git a/Makefile b/Makefile
> > index a2c310df2145..43dcc1ea5fcf 100644
> > --- a/Makefile
> > +++ b/Makefile
> > @@ -1578,6 +1578,7 @@ __modinst_pre:
> >       fi
> >       @sed 's:^\(.*\)\.o$$:kernel/\1.ko:' modules.order > $(MODLIB)/modules.order
> >       @cp -f modules.builtin $(MODLIB)/
> > +     @cp -f modules.builtin.alias $(MODLIB)/
> >       @cp -f $(objtree)/modules.builtin.modinfo $(MODLIB)/
> >
> >  endif # CONFIG_MODULES
> > diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
> > index 0980c58d8afc..e3ecc17a7a19 100644
> > --- a/scripts/Makefile.modpost
> > +++ b/scripts/Makefile.modpost
> > @@ -15,6 +15,7 @@
> >  # 2) modpost is then used to
> >  # 3)  create one <module>.mod.c file per module
> >  # 4)  create one Module.symvers file with CRC for all exported symbols
> > +# 5)  create modules.builtin.alias the aliases for built-in modules
>
> Does everyone want that file?

Not everyone needs it so we could exclude it, but the cost of adding
it isn't that high. I am fine with putting it behind a config, though
we would need to decide whether to have it default on/off.

>
> >  # Step 3 is used to place certain information in the module's ELF
> >  # section, including information such as:
> > @@ -63,6 +64,20 @@ modpost-args += -T $(MODORDER)
> >  modpost-deps += $(MODORDER)
> >  endif
> >
> > +ifneq ($(wildcard vmlinux.o),)
> > +output-builtin.alias := modules.builtin.alias
> > +modpost-args += -b .modules.builtin.alias.in
> > +.modules.builtin.alias.in: $(output-symdump)
> > +     @# Building $(output-symdump) generates .modules.builtin.alias.in as a
> > +     @# side effect.
> > +     @[ -e $@ ] || $(MODPOST) -b .modules.builtin.alias.in vmlinux.o
>
> Does using -b create a delay in builds ? What is the effect on build
> time on a typical 4-core or 8-core build? Does everyone want it?

Here is some data I collected related to build time and memory usage impact:

Without builtin.alias:
TIME="real %e\nuser %U\nsys %S\nres-max %M" time scripts/mod/modpost
-E -o Module.symvers -T modules.order
ERROR: modpost: "__x86_return_thunk"
[arch/x86/crypto/chacha-x86_64.ko] undefined!
ERROR: modpost: "kernel_fpu_end" [arch/x86/crypto/chacha-x86_64.ko] undefined!
ERROR: modpost: "hchacha_block_generic"
[arch/x86/crypto/chacha-x86_64.ko] undefined!
ERROR: modpost: "boot_cpu_data" [arch/x86/crypto/chacha-x86_64.ko] undefined!
ERROR: modpost: "static_key_enable" [arch/x86/crypto/chacha-x86_64.ko]
undefined!
ERROR: modpost: "cpu_has_xfeatures" [arch/x86/crypto/chacha-x86_64.ko]
undefined!
ERROR: modpost: "crypto_register_skciphers"
[arch/x86/crypto/chacha-x86_64.ko] undefined!
ERROR: modpost: "crypto_unregister_skciphers"
[arch/x86/crypto/chacha-x86_64.ko] undefined!
ERROR: modpost: "__stack_chk_fail" [arch/x86/crypto/chacha-x86_64.ko] undefined!
ERROR: modpost: "memset" [arch/x86/crypto/chacha-x86_64.ko] undefined!
WARNING: modpost: suppressed 17432 unresolved symbol warnings because
there were too many)
Command exited with non-zero status 1
real 0.44
user 0.43
sys 0.01
res-max 4896

With builtin.alias:
TIME="real %e\nuser %U\nsys %S\nres-max %M" time scripts/mod/modpost
-E -o Module.symvers -T modules.order -b .modules.builtin.alias.in
vmlinux.o
real 1.43
user 1.38
sys 0.05
res-max 51920

Notice that modpost only uses a single core, so multicore isn't really
as much of a factor here. While it more than triples the time required
for the modpost operation the difference is only about one second of
CPU time. The memory usage is much larger when generating
modules.builtin.alias because of the size of vmlinux.o.

My biggest performance related concern is actually the size difference
of vmlinux caused by the modules.h changes, but it looks like that is
negligible (24KiB):

Without builtin.alias:
du vmlinux.o
663048  vmlinux.o

With builtin.alias:
du vmlinux.o
663072  vmlinux.o

>
> Should we add a new option which lets people decide if they want this
> at build time or not?

I don't feel strongly that there should or should not be a config for
this. On the side for a config the extra second of CPU time and space
taken up by the modules.builtin.alias file would add up across all the
builds and machines, so removing it where it isn't used would help
mitigate that. On the flip side if it isn't used widely enough, it is
more likely that breakages are missed until someone who actually uses
it notices.

Please let me know if you feel strongly either way given the data.

Thanks,
Allen

>
>   Luis
>
> > +
> > +$(output-builtin.alias): .modules.builtin.alias.in
> > +     sort -o $@ $^
> > +
> > +__modpost: $(output-builtin.alias)
> > +endif
> > +
> >  ifeq ($(KBUILD_EXTMOD),)
> >
> >  # Generate the list of in-tree objects in vmlinux
> > --
> > 2.39.2
> >
Re: [PATCH v10 08/11] build: Add modules.builtin.alias
Posted by Luis Chamberlain 2 years, 1 month ago
Please cc Alexander and Alessandro in future patch series as well,
as they could likley be interested in your work too.

On Wed, Jul 19, 2023 at 02:51:48PM -0500, Allen Webb wrote:
> I finally got a chance to go through the comments and work on a
> follow-up to this series, but it probably makes sense to get this
> sorted ahead of the follow-up (if possible).
> 
> On Wed, May 24, 2023 at 2:02 AM Luis Chamberlain <mcgrof@kernel.org> wrote:
> >
> > On Thu, Apr 06, 2023 at 02:00:27PM -0500, Allen Webb wrote:
> > > Generate modules.builtin.alias using modpost and install it with the
> > > modules.
> >
> > Why? This is probably one of the more important commits and the
> > commit log is pretty slim.
> >
> > > Signed-off-by: Allen Webb <allenwebb@google.com>
> > > ---
> > >  .gitignore               |  1 +
> > >  Makefile                 |  1 +
> > >  scripts/Makefile.modpost | 15 +++++++++++++++
> > >  3 files changed, 17 insertions(+)
> > >
> > > diff --git a/.gitignore b/.gitignore
> > > index 13a7f08a3d73..ddaa622bddac 100644
> > > --- a/.gitignore
> > > +++ b/.gitignore
> > > @@ -71,6 +71,7 @@ modules.order
> > >  /System.map
> > >  /Module.markers
> > >  /modules.builtin
> > > +/modules.builtin.alias
> > >  /modules.builtin.modinfo
> > >  /modules.nsdeps
> > >
> > > diff --git a/Makefile b/Makefile
> > > index a2c310df2145..43dcc1ea5fcf 100644
> > > --- a/Makefile
> > > +++ b/Makefile
> > > @@ -1578,6 +1578,7 @@ __modinst_pre:
> > >       fi
> > >       @sed 's:^\(.*\)\.o$$:kernel/\1.ko:' modules.order > $(MODLIB)/modules.order
> > >       @cp -f modules.builtin $(MODLIB)/
> > > +     @cp -f modules.builtin.alias $(MODLIB)/
> > >       @cp -f $(objtree)/modules.builtin.modinfo $(MODLIB)/
> > >
> > >  endif # CONFIG_MODULES
> > > diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
> > > index 0980c58d8afc..e3ecc17a7a19 100644
> > > --- a/scripts/Makefile.modpost
> > > +++ b/scripts/Makefile.modpost
> > > @@ -15,6 +15,7 @@
> > >  # 2) modpost is then used to
> > >  # 3)  create one <module>.mod.c file per module
> > >  # 4)  create one Module.symvers file with CRC for all exported symbols
> > > +# 5)  create modules.builtin.alias the aliases for built-in modules
> >
> > Does everyone want that file?
> 
> Not everyone needs it so we could exclude it, but the cost of adding
> it isn't that high. I am fine with putting it behind a config, though
> we would need to decide whether to have it default on/off.

We didn't know the cost until I asked, it was the point of asking.
Perhaps Nick, Alessandro or Alexander could use it too later.

> > >  # Step 3 is used to place certain information in the module's ELF
> > >  # section, including information such as:
> > > @@ -63,6 +64,20 @@ modpost-args += -T $(MODORDER)
> > >  modpost-deps += $(MODORDER)
> > >  endif
> > >
> > > +ifneq ($(wildcard vmlinux.o),)
> > > +output-builtin.alias := modules.builtin.alias
> > > +modpost-args += -b .modules.builtin.alias.in
> > > +.modules.builtin.alias.in: $(output-symdump)
> > > +     @# Building $(output-symdump) generates .modules.builtin.alias.in as a
> > > +     @# side effect.
> > > +     @[ -e $@ ] || $(MODPOST) -b .modules.builtin.alias.in vmlinux.o
> >
> > Does using -b create a delay in builds ? What is the effect on build
> > time on a typical 4-core or 8-core build? Does everyone want it?
> 
> Here is some data I collected related to build time and memory usage impact:
> 
> Without builtin.alias:
> TIME="real %e\nuser %U\nsys %S\nres-max %M" time scripts/mod/modpost
> -E -o Module.symvers -T modules.order
> ERROR: modpost: "__x86_return_thunk"
> [arch/x86/crypto/chacha-x86_64.ko] undefined!
> ERROR: modpost: "kernel_fpu_end" [arch/x86/crypto/chacha-x86_64.ko] undefined!
> ERROR: modpost: "hchacha_block_generic"
> [arch/x86/crypto/chacha-x86_64.ko] undefined!
> ERROR: modpost: "boot_cpu_data" [arch/x86/crypto/chacha-x86_64.ko] undefined!
> ERROR: modpost: "static_key_enable" [arch/x86/crypto/chacha-x86_64.ko]
> undefined!
> ERROR: modpost: "cpu_has_xfeatures" [arch/x86/crypto/chacha-x86_64.ko]
> undefined!
> ERROR: modpost: "crypto_register_skciphers"
> [arch/x86/crypto/chacha-x86_64.ko] undefined!
> ERROR: modpost: "crypto_unregister_skciphers"
> [arch/x86/crypto/chacha-x86_64.ko] undefined!
> ERROR: modpost: "__stack_chk_fail" [arch/x86/crypto/chacha-x86_64.ko] undefined!
> ERROR: modpost: "memset" [arch/x86/crypto/chacha-x86_64.ko] undefined!
> WARNING: modpost: suppressed 17432 unresolved symbol warnings because
> there were too many)
> Command exited with non-zero status 1
> real 0.44
> user 0.43
> sys 0.01
> res-max 4896
> 
> With builtin.alias:
> TIME="real %e\nuser %U\nsys %S\nres-max %M" time scripts/mod/modpost
> -E -o Module.symvers -T modules.order -b .modules.builtin.alias.in
> vmlinux.o
> real 1.43
> user 1.38
> sys 0.05
> res-max 51920
> 
> Notice that modpost only uses a single core, so multicore isn't really
> as much of a factor here. While it more than triples the time required
> for the modpost operation the difference is only about one second of
> CPU time. The memory usage is much larger when generating
> modules.builtin.alias because of the size of vmlinux.o.

The modpost impact time of about 1 second for a type of config you used
should be described in your commit log and or kconfig entry to enable
this.

> My biggest performance related concern is actually the size difference
> of vmlinux caused by the modules.h changes, but it looks like that is
> negligible (24KiB):

And this size too.

24 KiB is not that small, so I'd prefer we kconfig'ize it for now and
have those who need it to select it. If we later all want it, we can
default to yes but for now default to no. The default today by
kconfig is to no so an empty default is fine.

> Without builtin.alias:
> du vmlinux.o
> 663048  vmlinux.o
> 
> With builtin.alias:
> du vmlinux.o
> 663072  vmlinux.o

What type of configuration was used? allyesconfig?

> >
> > Should we add a new option which lets people decide if they want this
> > at build time or not?
> 
> I don't feel strongly that there should or should not be a config for
> this. On the side for a config the extra second of CPU time and space
> taken up by the modules.builtin.alias file would add up across all the
> builds and machines, so removing it where it isn't used would help
> mitigate that. On the flip side if it isn't used widely enough, it is
> more likely that breakages are missed until someone who actually uses
> it notices.
> 
> Please let me know if you feel strongly either way given the data.

For now I'd prefer a kconfig option, it's easy to default to y later,
but saving 64 KiB seems like a desirable thing for some folks.

  Luis
[PATCH v10 09/11] Documentation: Include modules.builtin.alias
Posted by Allen Webb 2 years, 5 months ago
Update the documentation to include the presense and use case of
modules.builtin.alias.

Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
Signed-off-by: Allen Webb <allenwebb@google.com>
---
 Documentation/kbuild/kbuild.rst | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/kbuild/kbuild.rst b/Documentation/kbuild/kbuild.rst
index 5202186728b4..b27c66c3ca9e 100644
--- a/Documentation/kbuild/kbuild.rst
+++ b/Documentation/kbuild/kbuild.rst
@@ -17,6 +17,13 @@ modules.builtin
 This file lists all modules that are built into the kernel. This is used
 by modprobe to not fail when trying to load something builtin.
 
+modules.builtin.alias
+---------------------
+This file lists all match-id based aliases for modules built into the kernel.
+An example usage of the built-in aliases is to enable software such as
+USBGuard to allow or block devices outside of just the vendor, product, and
+device ID. This enables more flexible security policies in userspace.
+
 modules.builtin.modinfo
 -----------------------
 This file contains modinfo from all modules that are built into the kernel.
-- 
2.39.2
[PATCH v10 10/11] Documentation: Update writing_usb_driver for built-in modules
Posted by Allen Webb 2 years, 5 months ago
Built-in modules that set id_table need to set MODULE_DEVICE_TABLE so
update the documentation accordingly.

Signed-off-by: Allen Webb <allenwebb@google.com>
---
 Documentation/driver-api/usb/writing_usb_driver.rst | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/driver-api/usb/writing_usb_driver.rst b/Documentation/driver-api/usb/writing_usb_driver.rst
index 95c4f5d14052..5f38e3bd469a 100644
--- a/Documentation/driver-api/usb/writing_usb_driver.rst
+++ b/Documentation/driver-api/usb/writing_usb_driver.rst
@@ -128,6 +128,9 @@ single device with a specific vendor and product ID::
     };
     MODULE_DEVICE_TABLE (usb, skel_table);
 
+The ``MODULE_DEVICE_TABLE`` should also be set for built-in USB drivers
+that provide an id_table, so that tools like USBGuard can properly
+associate devices with your driver.
 
 There are other macros that can be used in describing a struct
 :c:type:`usb_device_id` for drivers that support a whole class of USB
-- 
2.39.2
[PATCH v10 11/11] Documentation: add USB authorization document to driver-api
Posted by Allen Webb 2 years, 5 months ago
There is a user-facing USB authorization document, but it is midding
details a driver should have developer, so add them in a new document.

Signed-off-by: Allen Webb <allenwebb@google.com>
---
 .../driver-api/usb/authorization.rst          | 71 +++++++++++++++++++
 Documentation/driver-api/usb/index.rst        |  1 +
 2 files changed, 72 insertions(+)
 create mode 100644 Documentation/driver-api/usb/authorization.rst

diff --git a/Documentation/driver-api/usb/authorization.rst b/Documentation/driver-api/usb/authorization.rst
new file mode 100644
index 000000000000..383dcc037a15
--- /dev/null
+++ b/Documentation/driver-api/usb/authorization.rst
@@ -0,0 +1,71 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+====================
+Device Authorization
+====================
+
+This document is intended for driver developers. See
+Documentation/usb/authorization.rst if you are looking for how to use
+USB authorization.
+
+Authorization provides userspace a way to allow or block configuring
+devices early during enumeration before any modules are probed for the
+device. While it is possible to block a device by not loading the
+required modules, this also prevents other devices from using the
+module as well. For example someone might have an unattended computer
+downloading installation media to a USB drive. Presumably this computer
+would be locked to make it more difficult for a bad actor to access the
+computer. Since USB storage devices are not needed to interact with the
+lock screen, the authorized_default sysfs attribute can be set to not
+authorize new USB devices by default. A userspace tool like USBGuard
+can then vet the devices. Mice, keyboards, etc can be allowed by
+writing to their authorized sysfs attribute so that the lock screen can
+still be used (this important in cases like suspend+resume or docks)
+while other devices can be blocked as long as the lock screen is shown.
+
+Sysfs Attributes
+================
+
+Userspace can control USB device authorization through the
+authorized_default and authorized sysfs attributes.
+
+authorized_default
+------------------
+
+Defined in ``drivers/usb/core/hcd.c``
+
+The authorized_default sysfs attribute is only present for host
+controllers. It determines the initial state of the authorized sysfs
+attribute of USB devices newly connected to the corresponding host
+controller. It can take on the following values:
+
++---------------------------------------------------+
+| Value | Behavior                                  |
++=======+===========================================+
+|    -1 | Authorize all devices except wireless USB |
++-------+-------------------------------------------+
+|     0 | Do not authorize new devices              |
++-------+-------------------------------------------+
+|     1 | Authorize new devices                     |
++-------+-------------------------------------------+
+|     2 | Authorize new internal devices only       |
++---------------------------------------------------+
+
+Note that firmware platform code determines if a device is internal or
+not and this is reported as the connect_type sysfs attribute of the USB
+port. This is currently supported by ACPI, but device tree still needs
+an implementation. Authorizing new internal devices only can be useful
+to work around issues with devices that misbehave if there are delays
+in probing their module.
+
+authorized
+----------
+
+Defined in ``drivers/usb/core/sysfs.c``
+
+Every USB device has an authorized sysfs attribute which can take the
+values 0 and 1. When authorized is 0, the device still is present in
+sysfs, but none of its interfaces can be associated with drivers and
+modules will not be probed. When authorized is 1 (or set to one) a
+configuration is chosen for the device and its interfaces are
+registered allowing drivers to bind to them.
diff --git a/Documentation/driver-api/usb/index.rst b/Documentation/driver-api/usb/index.rst
index cfa8797ea614..ffe37916f99f 100644
--- a/Documentation/driver-api/usb/index.rst
+++ b/Documentation/driver-api/usb/index.rst
@@ -7,6 +7,7 @@ Linux USB API
    usb
    gadget
    anchors
+   authorization
    bulk-streams
    callbacks
    dma
-- 
2.39.2
Re: [PATCH v10 11/11] Documentation: add USB authorization document to driver-api
Posted by Greg KH 2 years, 4 months ago
On Thu, Apr 06, 2023 at 02:00:30PM -0500, Allen Webb wrote:
> There is a user-facing USB authorization document, but it is midding
> details a driver should have developer, so add them in a new document.

I'm sorry, but I can not parse this sentence :(

Can you rephrase it?

> Signed-off-by: Allen Webb <allenwebb@google.com>
> ---
>  .../driver-api/usb/authorization.rst          | 71 +++++++++++++++++++
>  Documentation/driver-api/usb/index.rst        |  1 +
>  2 files changed, 72 insertions(+)
>  create mode 100644 Documentation/driver-api/usb/authorization.rst
> 
> diff --git a/Documentation/driver-api/usb/authorization.rst b/Documentation/driver-api/usb/authorization.rst
> new file mode 100644
> index 000000000000..383dcc037a15
> --- /dev/null
> +++ b/Documentation/driver-api/usb/authorization.rst
> @@ -0,0 +1,71 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +====================
> +Device Authorization
> +====================
> +
> +This document is intended for driver developers. See
> +Documentation/usb/authorization.rst if you are looking for how to use
> +USB authorization.
> +
> +Authorization provides userspace a way to allow or block configuring
> +devices early during enumeration before any modules are probed for the
> +device. While it is possible to block a device by not loading the
> +required modules, this also prevents other devices from using the
> +module as well. For example someone might have an unattended computer
> +downloading installation media to a USB drive. Presumably this computer
> +would be locked to make it more difficult for a bad actor to access the
> +computer. Since USB storage devices are not needed to interact with the
> +lock screen, the authorized_default sysfs attribute can be set to not
> +authorize new USB devices by default. A userspace tool like USBGuard
> +can then vet the devices. Mice, keyboards, etc can be allowed by
> +writing to their authorized sysfs attribute so that the lock screen can
> +still be used (this important in cases like suspend+resume or docks)
> +while other devices can be blocked as long as the lock screen is shown.
> +
> +Sysfs Attributes
> +================
> +
> +Userspace can control USB device authorization through the
> +authorized_default and authorized sysfs attributes.
> +
> +authorized_default
> +------------------
> +
> +Defined in ``drivers/usb/core/hcd.c``
> +
> +The authorized_default sysfs attribute is only present for host
> +controllers. It determines the initial state of the authorized sysfs
> +attribute of USB devices newly connected to the corresponding host
> +controller. It can take on the following values:
> +
> ++---------------------------------------------------+
> +| Value | Behavior                                  |
> ++=======+===========================================+
> +|    -1 | Authorize all devices except wireless USB |
> ++-------+-------------------------------------------+
> +|     0 | Do not authorize new devices              |
> ++-------+-------------------------------------------+
> +|     1 | Authorize new devices                     |
> ++-------+-------------------------------------------+
> +|     2 | Authorize new internal devices only       |
> ++---------------------------------------------------+
> +
> +Note that firmware platform code determines if a device is internal or
> +not and this is reported as the connect_type sysfs attribute of the USB
> +port. This is currently supported by ACPI, but device tree still needs
> +an implementation. Authorizing new internal devices only can be useful
> +to work around issues with devices that misbehave if there are delays
> +in probing their module.
> +
> +authorized
> +----------
> +
> +Defined in ``drivers/usb/core/sysfs.c``
> +
> +Every USB device has an authorized sysfs attribute which can take the
> +values 0 and 1. When authorized is 0, the device still is present in
> +sysfs, but none of its interfaces can be associated with drivers and
> +modules will not be probed. When authorized is 1 (or set to one) a
> +configuration is chosen for the device and its interfaces are
> +registered allowing drivers to bind to them.

Why would a driver author care about any of this?  It's all user-facing,
so shouldn't it go into the other document?

thanks,

greg k-h