Index: linux-2.6.9/security/seclvl.c =================================================================== --- linux-2.6.9.orig/security/seclvl.c 2004-11-21 06:41:57.000000000 -0600 +++ linux-2.6.9/security/seclvl.c 2004-11-21 07:04:55.260035216 -0600 @@ -35,6 +35,7 @@ #include #define SHA1_DIGEST_SIZE 20 +#define SECLVL_LSM_ID 0xF45 /** * Module parameter that defines the initial secure level. @@ -485,11 +486,18 @@ return 0; } +struct seclvl_i_sec { + struct security_list lsm_list; + struct task_struct *task; +}; + /* claim the blockdev to exclude mounters, release on file close */ static int seclvl_bd_claim(struct inode *inode) { int holder; struct block_device *bdev = NULL; + struct seclvl_i_sec *sec, *osec; + dev_t dev = inode->i_rdev; bdev = open_by_devnum(dev, FMODE_WRITE); if (bdev) { @@ -498,7 +506,15 @@ return -EPERM; } /* claimed, mark it to release on close */ - inode->i_security = current; + sec = kmalloc(sizeof(struct seclvl_i_sec), GFP_KERNEL); + if (!sec) { + blkdev_put(bdev); + return -EPERM; + } + sec->task = current; + osec = security_set_value_type(&inode->i_security, + SECLVL_LSM_ID, sec, struct seclvl_i_sec); + kfree(osec); } return 0; } @@ -506,12 +522,24 @@ /* release the blockdev if you claimed it */ static void seclvl_bd_release(struct inode *inode) { - if (inode && S_ISBLK(inode->i_mode) && inode->i_security == current) { - struct block_device *bdev = inode->i_bdev; - if (bdev) { - bd_release(bdev); - blkdev_put(bdev); - inode->i_security = NULL; + if (inode && S_ISBLK(inode->i_mode)) { + struct seclvl_i_sec *sec; + + sec = security_get_value_type(&inode->i_security, + SECLVL_LSM_ID, struct seclvl_i_sec); + if (!sec) + return; + if (sec->task == current) { + struct block_device *bdev = inode->i_bdev; + if (bdev) { + bd_release(bdev); + blkdev_put(bdev); + sec = security_del_value_type( + &inode->i_security, + SECLVL_LSM_ID, + struct seclvl_i_sec); + kfree(sec); + } } } }