| @@ -607,6 +607,36 @@ static const struct module_attribute modinfo_##field = { \ · 606 unmodified lines |
| 607 | 607 | MODINFO_ATTR(version); |
| 608 | 608 | MODINFO_ATTR(srcversion); |
| 609 | 609 | |
| 610 | +static void setup_modinfo_import_ns(struct module *mod, const char *s) |
| 611 | +{ |
| 612 | + mod->imported_namespaces = NULL; |
| 613 | +} |
| 614 | + |
| 615 | +static ssize_t show_modinfo_import_ns(const struct module_attribute *mattr, |
| 616 | + struct module_kobject *mk, char *buffer) |
| 617 | +{ |
| 618 | + return sysfs_emit(buffer, "%s\n", mk->mod->imported_namespaces); |
| 619 | +} |
| 620 | + |
| 621 | +static int modinfo_import_ns_exists(struct module *mod) |
| 622 | +{ |
| 623 | + return mod->imported_namespaces != NULL; |
| 624 | +} |
| 625 | + |
| 626 | +static void free_modinfo_import_ns(struct module *mod) |
| 627 | +{ |
| 628 | + kfree(mod->imported_namespaces); |
| 629 | + mod->imported_namespaces = NULL; |
| 630 | +} |
| 631 | + |
| 632 | +static const struct module_attribute modinfo_import_ns = { |
| 633 | + .attr = { .name = "import_ns", .mode = 0444 }, |
| 634 | + .show = show_modinfo_import_ns, |
| 635 | + .setup = setup_modinfo_import_ns, |
| 636 | + .test = modinfo_import_ns_exists, |
| 637 | + .free = free_modinfo_import_ns, |
| 638 | +}; |
| 639 | + |
| 610 | 640 | static struct { |
| 611 | 641 | char name[MODULE_NAME_LEN]; |
| 612 | 642 | char taints[MODULE_FLAGS_BUF_SIZE]; |
| @@ -1058,6 +1088,7 @@ const struct module_attribute *const modinfo_attrs[] = { · 445 unmodified lines |
| 1058 | 1088 | &module_uevent, |
| 1059 | 1089 | &modinfo_version, |
| 1060 | 1090 | &modinfo_srcversion, |
| 1091 | + &modinfo_import_ns, |
| 1061 | 1092 | &modinfo_initstate, |
| 1062 | 1093 | &modinfo_coresize, |
| 1063 | 1094 | #ifdef CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC |
| @@ -1760,11 +1791,43 @@ static void module_license_taint_check(struct module *mod, const char *license) · 696 unmodified lines |
| 1760 | 1791 | } |
| 1761 | 1792 | } |
| 1762 | 1793 | |
| 1794 | +static int copy_modinfo_import_ns(struct module *mod, struct load_info *info) |
| 1795 | +{ |
| 1796 | + char *ns; |
| 1797 | + size_t len, total_len = 0; |
| 1798 | + char *buf, *p; |
| 1799 | + |
| 1800 | + for_each_modinfo_entry(ns, info, "import_ns") |
| 1801 | + total_len += strlen(ns) + 1; |
| 1802 | + |
| 1803 | + if (!total_len) { |
| 1804 | + mod->imported_namespaces = NULL; |
| 1805 | + return 0; |
| 1806 | + } |
| 1807 | + |
| 1808 | + buf = kmalloc(total_len, GFP_KERNEL); |
| 1809 | + if (!buf) |
| 1810 | + return -ENOMEM; |
| 1811 | + |
| 1812 | + p = buf; |
| 1813 | + for_each_modinfo_entry(ns, info, "import_ns") { |
| 1814 | + len = strlen(ns); |
| 1815 | + memcpy(p, ns, len); |
| 1816 | + p += len; |
| 1817 | + *p++ = '\n'; |
| 1818 | + } |
| 1819 | + /* Replace trailing newline with null terminator. */ |
| 1820 | + *(p - 1) = '\0'; |
| 1821 | + |
| 1822 | + mod->imported_namespaces = buf; |
| 1823 | + return 0; |
| 1824 | +} |
| 1825 | + |
| 1763 | 1826 | static int setup_modinfo(struct module *mod, struct load_info *info) |
| 1764 | 1827 | { |
| 1765 | 1828 | const struct module_attribute *attr; |
| 1766 | 1829 | char *imported_namespace; |
| 1767 | | − int i; |
| 1830 | + int i, err; |
| 1768 | 1831 | |
| 1769 | 1832 | for (i = 0; (attr = modinfo_attrs[i]); i++) { |
| 1770 | 1833 | if (attr->setup) |
| @@ -1783,6 +1846,10 @@ static int setup_modinfo(struct module *mod, struct load_info *info) · 12 unmodified lines |
| 1783 | 1846 | } |
| 1784 | 1847 | } |
| 1785 | 1848 | |
| 1849 | + err = copy_modinfo_import_ns(mod, info); |
| 1850 | + if (err) |
| 1851 | + return err; |
| 1852 | + |
| 1786 | 1853 | return 0; |
| 1787 | 1854 | } |
| 1788 | 1855 | |