While developing a driver for a hot pluggable device
we wound up crashing the kernel when registering
as a devfs device.
A malformed driver has to try harder to crash the kernel
when base.c has the following changes.
The diff is against a 2.4 Hardhat mips distribution
but 2.4.7 fs/devfs/base.c is similar.
Richard Broberg
diff -c -r1.1 base.c
*** base.c 2001/03/30 23:58:41 1.1
--- base.c 2001/07/26 16:01:58
***************
*** 505,510 ****
--- 505,511 ----
#include <linux/smp_lock.h>
#include <linux/smp.h>
#include <linux/version.h>
+ #include <linux/interrupt.h> /* for in_interrupt () */
#include <asm/uaccess.h>
#include <asm/io.h>
***************
*** 522,527 ****
--- 523,530 ----
#define INODE_TABLE_INC 250
#define FIRST_INODE 1
+ #define KM_ALLOC_FLAG (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL)
+
#define STRING_LENGTH 256
#define MIN_DEVNUM 36864 /* Use major numbers 144 */
***************
*** 771,777 ****
{
if ( ( table = kmalloc (sizeof *table *
(fs_info.table_size + INODE_TABLE_INC),
! GFP_KERNEL) ) == NULL ) return NULL;
fs_info.table_size += INODE_TABLE_INC;
#ifdef CONFIG_DEVFS_DEBUG
if (devfs_debug & DEBUG_I_CREATE)
--- 774,780 ----
{
if ( ( table = kmalloc (sizeof *table *
(fs_info.table_size + INODE_TABLE_INC),
! KM_ALLOC_FLAG) ) == NULL ) return NULL;
fs_info.table_size += INODE_TABLE_INC;
#ifdef CONFIG_DEVFS_DEBUG
if (devfs_debug & DEBUG_I_CREATE)
***************
*** 786,792 ****
fs_info.table = table;
}
if ( name && (namelen < 1) ) namelen = strlen (name);
! if ( ( new = kmalloc (sizeof *new + namelen, GFP_KERNEL) ) == NULL )
return NULL;
/* Magic: this will set the ctime to zero, thus subsequent lookups will
trigger the call to <update_devfs_inode_from_entry> */
--- 789,795 ----
fs_info.table = table;
}
if ( name && (namelen < 1) ) namelen = strlen (name);
! if ( ( new = kmalloc (sizeof *new + namelen,KM_ALLOC_FLAG) ) == NULL )
return NULL;
/* Magic: this will set the ctime to zero, thus subsequent lookups will
trigger the call to <update_devfs_inode_from_entry> */
***************
|