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

On Tue, 2006-05-09 at 19:31 +0200, Andreas Gruenbacher wrote:
> 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.

Yes, I like this patch. Its a early warning system for a module having
no chance of getting inserted into the kernel.

Sam : do you want all these patches submitted togather? 

RP


> 
> 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;


  reply	other threads:[~2006-05-09 20:56 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     ` [PATCH] Check for license compliance at build time Andreas Gruenbacher
2006-05-09 20:55       ` Ram Pai [this message]
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=1147208158.7203.107.camel@localhost \
    --to=linuxram@us.ibm.com \
    --cc=agruen@suse.de \
    --cc=greg@kroah.com \
    --cc=jbeulich@novell.com \
    --cc=linux-kernel@vger.kernel.org \
    --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