1

I was trying to write the assignment in Operating System Concept 9th, chapter 2, which is writing a simple linux module. I write the code following the example in the book, but got a null pointer dereference error while deleting items in the linked list. Here is my code.

  1 #include <linux/module.h>
  2 #include <linux/kernel.h>
  3 #include <linux/list.h>
  4 #include <linux/slab.h>
  5 /* This function is called when the module is loaded. */
  6 
  7 struct birthday{
  8     int day;
  9     int month;
 10     int year;
 11     struct list_head list;
 12 };
 13 
 14 struct list_head birthday_list;
 15 
 16 int simple_init(void)
 17 {
 18        printk(KERN_INFO "Loading Module\n");
 19        LIST_HEAD(birthday_list);
 20        struct birthday *person;
 21        person = kmalloc(sizeof(*person), GFP_KERNEL);
 22        person->day=24;
 23        person->month=1;
 24        person->year=2000;
 25        INIT_LIST_HEAD(&person->list);
 26        list_add_tail(&person->list, &birthday_list); 
 27        struct birthday *ptr;
 28        list_for_each_entry(ptr, &birthday_list, list){
 29            printk(KERN_INFO "Birthday: %d/%d/%d\n", ptr->year, ptr->month, ptr->day);
 30        }
 31        return 0;
 32 }
 33 
 34 /* This function is called when the module is removed. */
 35 void simple_exit(void) {
 36         printk(KERN_INFO "Removing Module\n");
 37         struct birthday *ptr, *next;
 38 
 39         list_for_each_entry_safe(ptr, next, &birthday_list, list){
 40             printk(KERN_INFO "Birthday: %d/%d/%d\n", ptr->year, ptr->month, ptr->day);
 41             list_del(&(ptr->list));
 42             kfree(ptr);
 43         }
 44 
 45         printk(KERN_INFO "Removing Successfully\n");
 46 }
 47 module_init( simple_init );
 48 module_exit( simple_exit );
 49 
 50 MODULE_LICENSE("GPL");
 51 MODULE_DESCRIPTION("Simple Module");
 52 MODULE_AUTHOR("SGG");```

1 Answer 1

2

Initialize global variable birthday_list

The global variable birthday_list has implicit initialization {NULL, NULL} which is not a valid empty list. That is the cause of the null pointer dereference in simple_exit(). A valid empty list has the head node's next and prev members pointing to the head node itself.

You can define and initialize the global birthday_list variable using the LIST_HEAD macro:

LIST_HEAD(birthday_list);

However, it is preferable to declare it static:

static LIST_HEAD(birthday_list);

Remove LIST_HEAD(birthday_list); from simple_init()

In simple_init(), LIST_HEAD(birthday_list); is creating a local variable birthday_list, but you should be using the global variable of the same name. So just remove LIST_HEAD(birthday_list); from simple_init().

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.