linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andreas Gruenbacher <agruen@suse.de>
To: Ram Pai <linuxram@us.ibm.com>
Cc: Greg KH <greg@kroah.com>, Jan Beulich <jbeulich@novell.com>,
	sam@ravnborg.org, linux-kernel@vger.kernel.org
Subject: [PATCH] Check for license compliance at build time
Date: Tue, 9 May 2006 19:31:48 +0200	[thread overview]
Message-ID: <200605091931.49216.agruen@suse.de> (raw)
In-Reply-To: <1147154238.7203.62.camel@localhost>

This patch on to of Ram Pai's modpost.diff patch at 
http://sudhaa.com/~ram/misc/kernelpatch implements license compliance testing 
in modpost. This prevents kbuild from producing modules that won't load.

Signed-off-by: Andreas Gruenbacher <agruen@suse.de>

Index: linux-2.6.16/include/linux/license.h
===================================================================
--- /dev/null
+++ linux-2.6.16/include/linux/license.h
@@ -0,0 +1,14 @@
+#ifndef __LICENSE_H
+#define __LICENSE_H
+
+static inline int license_is_gpl_compatible(const char *license)
+{
+	return (strcmp(license, "GPL") == 0
+		|| strcmp(license, "GPL v2") == 0
+		|| strcmp(license, "GPL and additional rights") == 0
+		|| strcmp(license, "Dual BSD/GPL") == 0
+		|| strcmp(license, "Dual MIT/GPL") == 0
+		|| strcmp(license, "Dual MPL/GPL") == 0);
+}
+
+#endif
Index: linux-2.6.16/kernel/module.c
===================================================================
--- linux-2.6.16.orig/kernel/module.c
+++ linux-2.6.16/kernel/module.c
@@ -43,6 +43,7 @@
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
 #include <asm/cacheflush.h>
+#include <linux/license.h>
 
 #if 0
 #define DEBUGP printk
@@ -1248,16 +1249,6 @@ static void layout_sections(struct modul
 	}
 }
 
-static inline int license_is_gpl_compatible(const char *license)
-{
-	return (strcmp(license, "GPL") == 0
-		|| strcmp(license, "GPL v2") == 0
-		|| strcmp(license, "GPL and additional rights") == 0
-		|| strcmp(license, "Dual BSD/GPL") == 0
-		|| strcmp(license, "Dual MIT/GPL") == 0
-		|| strcmp(license, "Dual MPL/GPL") == 0);
-}
-
 static void set_license(struct module *mod, const char *license)
 {
 	if (!license)
Index: linux-2.6.16/scripts/mod/modpost.c
===================================================================
--- linux-2.6.16.orig/scripts/mod/modpost.c
+++ linux-2.6.16/scripts/mod/modpost.c
@@ -13,6 +13,7 @@
 
 #include <ctype.h>
 #include "modpost.h"
+#include "../../include/linux/license.h"
 
 /* Are we using CONFIG_MODVERSIONS? */
 int modversions = 0;
@@ -101,6 +102,7 @@ static struct module *new_module(char *m
 
 	/* add to list */
 	mod->name = p;
+	mod->gpl_compatible = -1;
 	mod->next = modules;
 	modules = mod;
 
@@ -454,13 +456,18 @@ static char *next_string(char *string, u
 	return string;
 }
 
-static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
-			 const char *tag)
+static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len,
+			      const char *tag, char *info)
 {
 	char *p;
 	unsigned int taglen = strlen(tag);
 	unsigned long size = modinfo_len;
 
+	if (info) {
+		size -= info - (char *)modinfo;
+		modinfo = next_string(info, &size);
+	}
+
 	for (p = modinfo; p; p = next_string(p, &size)) {
 		if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
 			return p + taglen + 1;
@@ -468,6 +475,13 @@ static char *get_modinfo(void *modinfo, 
 	return NULL;
 }
 
+static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
+			 const char *tag)
+
+{
+	return get_next_modinfo(modinfo, modinfo_len, tag, NULL);
+}
+
 /**
  * Test if string s ends in string sub
  * return 0 if match
@@ -888,6 +902,7 @@ static void read_symbols(char *modname)
 {
 	const char *symname;
 	char *version;
+	char *license;
 	struct module *mod;
 	struct elf_info info = { };
 	Elf_Sym *sym;
@@ -903,6 +918,18 @@ static void read_symbols(char *modname)
 		mod->skip = 1;
 	}
 
+	license = get_modinfo(info.modinfo, info.modinfo_len, "license");
+	while (license) {
+		if (license_is_gpl_compatible(license))
+			mod->gpl_compatible = 1;
+		else {
+			mod->gpl_compatible = 0;
+			break;
+		}
+		license = get_next_modinfo(info.modinfo, info.modinfo_len,
+					   "license", license);
+	}
+
 	for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
 		symname = info.strtab + sym->st_name;
 
@@ -959,6 +986,31 @@ void buf_write(struct buffer *buf, const
 	buf->pos += len;
 }
 
+void check_license(struct module *mod)
+{
+	struct symbol *s, *exp;
+
+	for (s = mod->unres; s; s = s->next) {
+		if (mod->gpl_compatible == 1) {
+			/* GPL-compatible modules may use all symbols */
+			continue;
+		}
+		exp = find_symbol(s->name);
+		if (!exp || exp->module == mod)
+			continue;
+		if (exp->export_type == 1) {
+			const char *basename = strrchr(mod->name, '/');
+			if (basename)
+				basename++;
+
+			fatal("modpost: GPL-incompatible module %s uses the "
+			      "GPL-only symbol %s\n",
+			      basename ? basename : mod->name,
+			      exp->name);
+		}
+        }
+}
+
 /**
  * Header for the generated file
  **/
@@ -1244,6 +1296,12 @@ int main(int argc, char **argv)
 	for (mod = modules; mod; mod = mod->next) {
 		if (mod->skip)
 			continue;
+		check_license(mod);
+	}
+
+	for (mod = modules; mod; mod = mod->next) {
+		if (mod->skip)
+			continue;
 
 		buf.pos = 0;
 
Index: linux-2.6.16/scripts/mod/modpost.h
===================================================================
--- linux-2.6.16.orig/scripts/mod/modpost.h
+++ linux-2.6.16/scripts/mod/modpost.h
@@ -81,6 +81,7 @@ buf_write(struct buffer *buf, const char
 struct module {
 	struct module *next;
 	const char *name;
+	int gpl_compatible;
 	struct symbol *unres;
 	int seen;
 	int skip;

  parent reply	other threads:[~2006-05-09 17:30 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-05-08  7:12 GPL-only symbols issue Jan Beulich
2006-05-08 20:23 ` Sam Ravnborg
2006-05-09  4:25 ` Greg KH
2006-05-09  5:57   ` Ram Pai
2006-05-09 13:11     ` Philip R. Auld
2006-05-09 17:31     ` Andreas Gruenbacher
2006-05-09 17:31     ` Andreas Gruenbacher [this message]
2006-05-09 20:55       ` [PATCH] Check for license compliance at build time Ram Pai
2006-05-09 22:24         ` Sam Ravnborg
2006-06-17 21:06   ` GPL-only symbols issue Sam Ravnborg

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=200605091931.49216.agruen@suse.de \
    --to=agruen@suse.de \
    --cc=greg@kroah.com \
    --cc=jbeulich@novell.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxram@us.ibm.com \
    --cc=sam@ravnborg.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).