No Tainted-kernel Warnings
March 12, 2003


A while ago i started fooling around with device-driver writing in plain assembly language. It seems that the programmers of *nix world have some ancestral fear of ASM and because i really wanted to understand the inner-workings of the linux kernel and i have some experience in writing programs using assembly i tried to find some good documents which could help me in this task. I managed to find a small source of a very simple "skeleton" module and i tried it to see how it works. Let me give you here the first version of that module :


;----------------------------------------
; simple_module.asm
;----------------------------------------
section .text
global init_module
global cleanup_module
global kernel_version

extern printk

init_module:
    push dword str1
    call printk
    pop eax
    xor eax,eax
    ret
    
cleanup_module:
    push dword str2
    call printk
    pop eax
    ret
    
str1    db "Skeleton module loaded",0ah,0
str2    db "Skeleton module unloaded",0ah,0

kernel_version db "2.4.19-16mdk",0

Just replace the "kernel_version" string with your own kernel version and compile the program using :


nasm -f elf -o simple_module.obj simple_module.asm
ld -r -o simple_module.o simple_module.obj

After this you will have in the same directory as your source two more files. You can safely delete simple_module.obj from your folder and try to load your module now into the kernel space :


insmod simple_module.o

Oooops :) This operation returns a warning message :


Warning: loading simple_module.o will taint the kernel: no license
See http://www.tux.org/lkml/#export-tainted for information about tainted modules
Module tainted loaded, with warnings

Hmmm, this must be something you might think. But is my module loaded or not ? you might ask. Yes, it is. If you just try this you will see :


tail /var/log/messages

The last line (or one near by) will be :
....kernel: Skeleton module loaded
WOW ! Ok, now what about that warning ? Well, you shoulf firstly go to that URL and try to understand what is written there. I will show you how can you fix your module so that it is recognised and loaded properly without any warnings. This message is printed whenever you try to load a binary module which is has no information about its license. Usually linux kernel modules are distributed along with the sources under some GPL-type license. All the valid and accepted by linux licenses are listed in linux/include/modules.h. I will quote here what is written in my modules.h file :


/*
 * The following license idents are currently accepted as indicating free
 * software modules
 *
 *  "GPL"               [GNU Public License v2 or later]
 *  "GPL and additional rights" [GNU Public License v2 rights and more]
 *  "Dual BSD/GPL"          [GNU Public License v2 or BSD license choice]
 *  "Dual MPL/GPL"          [GNU Public License v2 or Mozilla license choice]
 *
 * The following other idents are available
 *
 *  "Proprietary"           [Non free products]
 *
 * There are dual licensed components, but when running with Linux it is the
 * GPL that is relevant so this is a non issue. Similarly LGPL linked with GPL
 * is a GPL combined work.
 *
 * This exists for several reasons
 * 1.   So modinfo can show license info for users wanting to vet their setup 
 *  is free
 * 2.   So the community can ignore bug reports including proprietary modules
 * 3.   So vendors can do likewise based on their own policies
 */

Ok, now what ? :) Well, generally if you make a kernel module using "C" language you have MODULE_LICENSE macro and can set the license like this :


MODULE_LICENSE("GPL");

This is the C way of doing things but how can we implement this in assembly ? Let's take a little time and parse the code for this macro :


#define MODULE_LICENSE(license)    \
static const char __module_license[] __attribute__((section(".modinfo"))) =   \
"license=" license

This basically means that it adds a variable named __module_license which is actually a pointer to a string located in .modinfo section. So, the string should be "license=GPL" and it should be located in another section. Well, let's try to add that section. I will try to modify our basic skeleton module to fit our need :


;----------------------------------------
; licensed_module.asm
;----------------------------------------
section .text
global init_module
global cleanup_module
global kernel_version

extern printk

init_module:
    push dword str1
    call printk
    pop eax
    xor eax,eax
    ret
    
cleanup_module:
    push dword str2
    call printk
    pop eax
    ret
    
str1    db "Licensed module loaded",0ah,0
str2    db "Licensed module unloaded",0ah,0

kernel_version db "2.4.19-16mdk",0
__module_license    dd lic_string

section .modinfo
lic_string  db "license=GPL",0

Let's try now and see if it works :


nasm -f elf -o licensed_module.obj licensed_module.asm
ld -r -o licensed_module.o licensed_module.obj
insmod licensed_module.o

WOW ! No Warnings ! Let's see if it is really loaded


tail /var/log/messages

....kernel: Licensed module loaded Perfect. Problem solved.




The author can be contacted at : dics@completeinfo.net