Commit b817f6feff4a565b08f0e699a5790b4008b8f494

Authored by Sam Ravnborg
1 parent bd5cbcedf4

kbuild: check license compatibility when building modules

Modules that uses GPL symbols can no longer be build with kbuild,
the build will fail during the modpost step.
When a GPL-incompatible module uses a EXPORT_SYMBOL_GPL_FUTURE symbol
then warn during modpost so author are actually notified.

The actual license compatibility check is shared with the kernel
to make sure it is in sync.

Patch originally from: Andreas Gruenbacher <agruen@suse.de> and
Ram Pai <linuxram@us.ibm.com>

Signed-off-by: Sam Ravnborg <sam@ravnborg.org>

Showing 4 changed files with 85 additions and 12 deletions Side-by-side Diff

include/linux/license.h
  1 +#ifndef __LICENSE_H
  2 +#define __LICENSE_H
  3 +
  4 +static inline int license_is_gpl_compatible(const char *license)
  5 +{
  6 + return (strcmp(license, "GPL") == 0
  7 + || strcmp(license, "GPL v2") == 0
  8 + || strcmp(license, "GPL and additional rights") == 0
  9 + || strcmp(license, "Dual BSD/GPL") == 0
  10 + || strcmp(license, "Dual MIT/GPL") == 0
  11 + || strcmp(license, "Dual MPL/GPL") == 0);
  12 +}
  13 +
  14 +#endif
... ... @@ -43,6 +43,7 @@
43 43 #include <asm/uaccess.h>
44 44 #include <asm/semaphore.h>
45 45 #include <asm/cacheflush.h>
  46 +#include <linux/license.h>
46 47  
47 48 #if 0
48 49 #define DEBUGP printk
... ... @@ -1246,16 +1247,6 @@
1246 1247 if (m == 0)
1247 1248 mod->init_text_size = mod->init_size;
1248 1249 }
1249   -}
1250   -
1251   -static inline int license_is_gpl_compatible(const char *license)
1252   -{
1253   - return (strcmp(license, "GPL") == 0
1254   - || strcmp(license, "GPL v2") == 0
1255   - || strcmp(license, "GPL and additional rights") == 0
1256   - || strcmp(license, "Dual BSD/GPL") == 0
1257   - || strcmp(license, "Dual MIT/GPL") == 0
1258   - || strcmp(license, "Dual MPL/GPL") == 0);
1259 1250 }
1260 1251  
1261 1252 static void set_license(struct module *mod, const char *license)
scripts/mod/modpost.c
... ... @@ -13,6 +13,7 @@
13 13  
14 14 #include <ctype.h>
15 15 #include "modpost.h"
  16 +#include "../../include/linux/license.h"
16 17  
17 18 /* Are we using CONFIG_MODVERSIONS? */
18 19 int modversions = 0;
... ... @@ -99,6 +100,7 @@
99 100  
100 101 /* add to list */
101 102 mod->name = p;
  103 + mod->gpl_compatible = -1;
102 104 mod->next = modules;
103 105 modules = mod;
104 106  
105 107  
... ... @@ -493,13 +495,18 @@
493 495 return string;
494 496 }
495 497  
496   -static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
497   - const char *tag)
  498 +static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len,
  499 + const char *tag, char *info)
498 500 {
499 501 char *p;
500 502 unsigned int taglen = strlen(tag);
501 503 unsigned long size = modinfo_len;
502 504  
  505 + if (info) {
  506 + size -= info - (char *)modinfo;
  507 + modinfo = next_string(info, &size);
  508 + }
  509 +
503 510 for (p = modinfo; p; p = next_string(p, &size)) {
504 511 if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
505 512 return p + taglen + 1;
... ... @@ -507,6 +514,13 @@
507 514 return NULL;
508 515 }
509 516  
  517 +static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
  518 + const char *tag)
  519 +
  520 +{
  521 + return get_next_modinfo(modinfo, modinfo_len, tag, NULL);
  522 +}
  523 +
510 524 /**
511 525 * Test if string s ends in string sub
512 526 * return 0 if match
... ... @@ -981,6 +995,7 @@
981 995 {
982 996 const char *symname;
983 997 char *version;
  998 + char *license;
984 999 struct module *mod;
985 1000 struct elf_info info = { };
986 1001 Elf_Sym *sym;
... ... @@ -996,6 +1011,18 @@
996 1011 mod->skip = 1;
997 1012 }
998 1013  
  1014 + license = get_modinfo(info.modinfo, info.modinfo_len, "license");
  1015 + while (license) {
  1016 + if (license_is_gpl_compatible(license))
  1017 + mod->gpl_compatible = 1;
  1018 + else {
  1019 + mod->gpl_compatible = 0;
  1020 + break;
  1021 + }
  1022 + license = get_next_modinfo(info.modinfo, info.modinfo_len,
  1023 + "license", license);
  1024 + }
  1025 +
999 1026 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
1000 1027 symname = info.strtab + sym->st_name;
1001 1028  
... ... @@ -1052,6 +1079,40 @@
1052 1079 buf->pos += len;
1053 1080 }
1054 1081  
  1082 +void check_license(struct module *mod)
  1083 +{
  1084 + struct symbol *s, *exp;
  1085 +
  1086 + for (s = mod->unres; s; s = s->next) {
  1087 + if (mod->gpl_compatible == 1) {
  1088 + /* GPL-compatible modules may use all symbols */
  1089 + continue;
  1090 + }
  1091 + exp = find_symbol(s->name);
  1092 + if (!exp || exp->module == mod)
  1093 + continue;
  1094 + const char *basename = strrchr(mod->name, '/');
  1095 + if (basename)
  1096 + basename++;
  1097 + switch (exp->export) {
  1098 + case export_gpl:
  1099 + fatal("modpost: GPL-incompatible module %s "
  1100 + "uses GPL-only symbol '%s'\n",
  1101 + basename ? basename : mod->name,
  1102 + exp->name);
  1103 + break;
  1104 + case export_gpl_future:
  1105 + warn("modpost: GPL-incompatible module %s "
  1106 + "uses future GPL-only symbol '%s'\n",
  1107 + basename ? basename : mod->name,
  1108 + exp->name);
  1109 + break;
  1110 + case export_plain: /* ignore */ break;
  1111 + case export_unknown: /* ignore */ break;
  1112 + }
  1113 + }
  1114 +}
  1115 +
1055 1116 /**
1056 1117 * Header for the generated file
1057 1118 **/
... ... @@ -1323,6 +1384,12 @@
1323 1384  
1324 1385 while (optind < argc) {
1325 1386 read_symbols(argv[optind++]);
  1387 + }
  1388 +
  1389 + for (mod = modules; mod; mod = mod->next) {
  1390 + if (mod->skip)
  1391 + continue;
  1392 + check_license(mod);
1326 1393 }
1327 1394  
1328 1395 for (mod = modules; mod; mod = mod->next) {
scripts/mod/modpost.h
... ... @@ -100,6 +100,7 @@
100 100 struct module {
101 101 struct module *next;
102 102 const char *name;
  103 + int gpl_compatible;
103 104 struct symbol *unres;
104 105 int seen;
105 106 int skip;