Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9f28bb7e authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

[PATCH] add EXPORT_SYMBOL_GPL_FUTURE()



This patch adds the ability to mark symbols that will be changed in the
future, so that kernel modules that don't include MODULE_LICENSE("GPL")
and use the symbols, will be flagged and printed out to the system log.

Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 3fd6805f
Loading
Loading
Loading
Loading
+10 −0
Original line number Original line Diff line number Diff line
@@ -269,6 +269,11 @@ SECTIONS {
		*(__ksymtab_gpl)
		*(__ksymtab_gpl)
		__stop___ksymtab_gpl = .;
		__stop___ksymtab_gpl = .;


		/* Kernel symbol table: GPL-future symbols */
		__start___ksymtab_gpl_future = .;
		*(__ksymtab_gpl_future)
		__stop___ksymtab_gpl_future = .;

		/* Kernel symbol table: Normal symbols */
		/* Kernel symbol table: Normal symbols */
		__start___kcrctab = .;
		__start___kcrctab = .;
		*(__kcrctab)
		*(__kcrctab)
@@ -279,6 +284,11 @@ SECTIONS {
		*(__kcrctab_gpl)
		*(__kcrctab_gpl)
		__stop___kcrctab_gpl = .;
		__stop___kcrctab_gpl = .;


		/* Kernel symbol table: GPL-future symbols */
		__start___kcrctab_gpl_future = .;
		*(__kcrctab_gpl_future)
		__stop___kcrctab_gpl_future = .;

		/* Kernel symbol table: strings */
		/* Kernel symbol table: strings */
		*(__ksymtab_strings)
		*(__ksymtab_strings)


+8 −0
Original line number Original line Diff line number Diff line
@@ -64,6 +64,10 @@
		___start___ksymtab_gpl = .;				      \
		___start___ksymtab_gpl = .;				      \
			*(__ksymtab_gpl)				      \
			*(__ksymtab_gpl)				      \
		___stop___ksymtab_gpl = .;				      \
		___stop___ksymtab_gpl = .;				      \
		/* Kernel symbol table: GPL-future symbols */		      \
		___start___ksymtab_gpl_future = .;			      \
			*(__ksymtab_gpl_future)				      \
		___stop___ksymtab_gpl_future = .;			      \
		/* Kernel symbol table: strings */			      \
		/* Kernel symbol table: strings */			      \
			*(__ksymtab_strings)				      \
			*(__ksymtab_strings)				      \
		/* Kernel symbol table: Normal symbols */		      \
		/* Kernel symbol table: Normal symbols */		      \
@@ -74,6 +78,10 @@
		___start___kcrctab_gpl = .;				      \
		___start___kcrctab_gpl = .;				      \
			*(__kcrctab_gpl)				      \
			*(__kcrctab_gpl)				      \
		___stop___kcrctab_gpl = .;				      \
		___stop___kcrctab_gpl = .;				      \
		/* Kernel symbol table: GPL-future symbols */		      \
		___start___kcrctab_gpl_future = .;			      \
			*(__kcrctab_gpl_future)				      \
		___stop___kcrctab_gpl_future = .;			      \
		/* Built-in module parameters */			      \
		/* Built-in module parameters */			      \
		. = ALIGN (4) ;						      \
		. = ALIGN (4) ;						      \
		___start___param = .;					      \
		___start___param = .;					      \
+14 −0
Original line number Original line Diff line number Diff line
@@ -58,6 +58,13 @@
		VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .;		\
		VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .;		\
	}								\
	}								\
									\
									\
	/* Kernel symbol table: GPL-future-only symbols */		\
	__ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \
		VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .;	\
		*(__ksymtab_gpl_future)					\
		VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .;	\
	}								\
									\
	/* Kernel symbol table: Normal symbols */			\
	/* Kernel symbol table: Normal symbols */			\
	__kcrctab         : AT(ADDR(__kcrctab) - LOAD_OFFSET) {		\
	__kcrctab         : AT(ADDR(__kcrctab) - LOAD_OFFSET) {		\
		VMLINUX_SYMBOL(__start___kcrctab) = .;			\
		VMLINUX_SYMBOL(__start___kcrctab) = .;			\
@@ -72,6 +79,13 @@
		VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .;		\
		VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .;		\
	}								\
	}								\
									\
									\
	/* Kernel symbol table: GPL-future-only symbols */		\
	__kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \
		VMLINUX_SYMBOL(__start___kcrctab_gpl_future) = .;	\
		*(__kcrctab_gpl_future)					\
		VMLINUX_SYMBOL(__stop___kcrctab_gpl_future) = .;	\
	}								\
									\
	/* Kernel symbol table: strings */				\
	/* Kernel symbol table: strings */				\
        __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {	\
        __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {	\
		*(__ksymtab_strings)					\
		*(__ksymtab_strings)					\
+9 −0
Original line number Original line Diff line number Diff line
@@ -198,6 +198,9 @@ void *__symbol_get_gpl(const char *symbol);
#define EXPORT_SYMBOL_GPL(sym)					\
#define EXPORT_SYMBOL_GPL(sym)					\
	__EXPORT_SYMBOL(sym, "_gpl")
	__EXPORT_SYMBOL(sym, "_gpl")


#define EXPORT_SYMBOL_GPL_FUTURE(sym)				\
	__EXPORT_SYMBOL(sym, "_gpl_future")

#endif
#endif


struct module_ref
struct module_ref
@@ -255,6 +258,11 @@ struct module
	unsigned int num_gpl_syms;
	unsigned int num_gpl_syms;
	const unsigned long *gpl_crcs;
	const unsigned long *gpl_crcs;


	/* symbols that will be GPL-only in the near future. */
	const struct kernel_symbol *gpl_future_syms;
	unsigned int num_gpl_future_syms;
	const unsigned long *gpl_future_crcs;

	/* Exception table */
	/* Exception table */
	unsigned int num_exentries;
	unsigned int num_exentries;
	const struct exception_table_entry *extable;
	const struct exception_table_entry *extable;
@@ -441,6 +449,7 @@ void module_remove_driver(struct device_driver *);
#else /* !CONFIG_MODULES... */
#else /* !CONFIG_MODULES... */
#define EXPORT_SYMBOL(sym)
#define EXPORT_SYMBOL(sym)
#define EXPORT_SYMBOL_GPL(sym)
#define EXPORT_SYMBOL_GPL(sym)
#define EXPORT_SYMBOL_GPL_FUTURE(sym)


/* Given an address, look for it in the exception tables. */
/* Given an address, look for it in the exception tables. */
static inline const struct exception_table_entry *
static inline const struct exception_table_entry *
+47 −2
Original line number Original line Diff line number Diff line
@@ -126,8 +126,11 @@ extern const struct kernel_symbol __start___ksymtab[];
extern const struct kernel_symbol __stop___ksymtab[];
extern const struct kernel_symbol __stop___ksymtab[];
extern const struct kernel_symbol __start___ksymtab_gpl[];
extern const struct kernel_symbol __start___ksymtab_gpl[];
extern const struct kernel_symbol __stop___ksymtab_gpl[];
extern const struct kernel_symbol __stop___ksymtab_gpl[];
extern const struct kernel_symbol __start___ksymtab_gpl_future[];
extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
extern const unsigned long __start___kcrctab[];
extern const unsigned long __start___kcrctab[];
extern const unsigned long __start___kcrctab_gpl[];
extern const unsigned long __start___kcrctab_gpl[];
extern const unsigned long __start___kcrctab_gpl_future[];


#ifndef CONFIG_MODVERSIONS
#ifndef CONFIG_MODVERSIONS
#define symversion(base, idx) NULL
#define symversion(base, idx) NULL
@@ -172,6 +175,22 @@ static unsigned long __find_symbol(const char *name,
			return ks->value;
			return ks->value;
		}
		}
	}
	}
	ks = lookup_symbol(name, __start___ksymtab_gpl_future,
				 __stop___ksymtab_gpl_future);
	if (ks) {
		if (!gplok) {
			printk(KERN_WARNING "Symbol %s is being used "
			       "by a non-GPL module, which will not "
			       "be allowed in the future\n", name);
			printk(KERN_WARNING "Please see the file "
			       "Documentation/feature-removal-schedule.txt "
			       "in the kernel source tree for more "
			       "details.\n");
		}
		*crc = symversion(__start___kcrctab_gpl_future,
				  (ks - __start___ksymtab_gpl_future));
		return ks->value;
	}


	/* Now try modules. */ 
	/* Now try modules. */ 
	list_for_each_entry(mod, &modules, list) {
	list_for_each_entry(mod, &modules, list) {
@@ -191,6 +210,23 @@ static unsigned long __find_symbol(const char *name,
				return ks->value;
				return ks->value;
			}
			}
		}
		}
		ks = lookup_symbol(name, mod->gpl_future_syms,
				   (mod->gpl_future_syms +
				    mod->num_gpl_future_syms));
		if (ks) {
			if (!gplok) {
				printk(KERN_WARNING "Symbol %s is being used "
				       "by a non-GPL module, which will not "
				       "be allowed in the future\n", name);
				printk(KERN_WARNING "Please see the file "
				       "Documentation/feature-removal-schedule.txt "
				       "in the kernel source tree for more "
				       "details.\n");
			}
			*crc = symversion(mod->gpl_future_crcs,
					  (ks - mod->gpl_future_syms));
			return ks->value;
		}
	}
	}
	DEBUGP("Failed to find symbol %s\n", name);
	DEBUGP("Failed to find symbol %s\n", name);
 	return 0;
 	return 0;
@@ -1546,7 +1582,8 @@ static struct module *load_module(void __user *umod,
	char *secstrings, *args, *modmagic, *strtab = NULL;
	char *secstrings, *args, *modmagic, *strtab = NULL;
	unsigned int i, symindex = 0, strindex = 0, setupindex, exindex,
	unsigned int i, symindex = 0, strindex = 0, setupindex, exindex,
		exportindex, modindex, obsparmindex, infoindex, gplindex,
		exportindex, modindex, obsparmindex, infoindex, gplindex,
		crcindex, gplcrcindex, versindex, pcpuindex;
		crcindex, gplcrcindex, versindex, pcpuindex, gplfutureindex,
		gplfuturecrcindex;
	long arglen;
	long arglen;
	struct module *mod;
	struct module *mod;
	long err = 0;
	long err = 0;
@@ -1627,8 +1664,10 @@ static struct module *load_module(void __user *umod,
	/* Optional sections */
	/* Optional sections */
	exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");
	exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");
	gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");
	gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");
	gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future");
	crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab");
	crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab");
	gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl");
	gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl");
	gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future");
	setupindex = find_sec(hdr, sechdrs, secstrings, "__param");
	setupindex = find_sec(hdr, sechdrs, secstrings, "__param");
	exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");
	exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");
	obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");
	obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");
@@ -1784,10 +1823,16 @@ static struct module *load_module(void __user *umod,
	mod->gpl_syms = (void *)sechdrs[gplindex].sh_addr;
	mod->gpl_syms = (void *)sechdrs[gplindex].sh_addr;
	if (gplcrcindex)
	if (gplcrcindex)
		mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr;
		mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr;
	mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size /
					sizeof(*mod->gpl_future_syms);
	mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr;
	if (gplfuturecrcindex)
		mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr;


#ifdef CONFIG_MODVERSIONS
#ifdef CONFIG_MODVERSIONS
	if ((mod->num_syms && !crcindex) || 
	if ((mod->num_syms && !crcindex) || 
	    (mod->num_gpl_syms && !gplcrcindex)) {
	    (mod->num_gpl_syms && !gplcrcindex) ||
	    (mod->num_gpl_future_syms && !gplfuturecrcindex)) {
		printk(KERN_WARNING "%s: No versions for exported symbols."
		printk(KERN_WARNING "%s: No versions for exported symbols."
		       " Tainting kernel.\n", mod->name);
		       " Tainting kernel.\n", mod->name);
		add_taint(TAINT_FORCED_MODULE);
		add_taint(TAINT_FORCED_MODULE);
Loading