Re: [PATCH] BSD Secure Levels: claim block dev in file struct rather than inode struct, 2.6.11-rc2-mm1 (3/8)

Chris Wright
2005-02-08T23:38:30Z

* Michael Halcrow (mhalcrow@us.ibm.com) wrote:
> [...]. This occurs because the bd_release function will
> bd_release(bdev) and set inode->i_security to NULL on the close(fd1).
> Hence, we want to place the control at the level of the file struct,
> not the inode.

This is basically what I was referring to pre-merge. And it is still
not fully sufficient. Multiple processes can share an fd. So the test
against current is broken. Also well-behaved apps that are already
using O_EXCL will break. Using filp as the holder is sufficient to fix
both of these issues. Here's a 3.5/8 that will fix this. 6/8 no longer
applies cleanly with this change.

Signed-off-by: Chris Wright <chrisw@osdl.org>

--- a/security/seclvl.c~bd_claim 2005-02-08 15:05:09.000000000 -0800
+++ b/security/seclvl.c 2005-02-08 15:05:17.000000000 -0800
@@ -492,17 +492,16 @@
*/
static int seclvl_bd_claim(struct file * filp)
{
- int holder;
struct block_device *bdev = NULL;
dev_t dev = filp->f_dentry->d_inode->i_rdev;
bdev = open_by_devnum(dev, FMODE_WRITE);
if (bdev) {
- if (bd_claim(bdev, &holder)) {
+ if (bd_claim(bdev, filp)) {
blkdev_put(bdev);
return -EPERM;
}
/* Claimed; mark it to release on close */
- filp->f_security = current;
+ filp->f_security = filp;
}
return 0;
}
@@ -597,7 +596,7 @@
if (dentry && (filp->f_mode & FMODE_WRITE)) {
struct inode * inode = dentry->d_inode;
if (inode && S_ISBLK(inode->i_mode)
- && filp->f_security == current) {
+ && filp->f_security == filp) {
struct block_device *bdev = inode->i_bdev;
if (bdev) {
bd_release(bdev);