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

2005-02-08 Thread Chris Wright
* Michael Halcrow ([EMAIL PROTECTED]) 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 <[EMAIL PROTECTED]>

--- a/security/seclvl.c~bd_claim2005-02-08 15:05:09.0 -0800
+++ b/security/seclvl.c 2005-02-08 15:05:17.0 -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, )) {
+   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);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2005-02-08 Thread Serge E. Hallyn
Quoting [EMAIL PROTECTED] ([EMAIL PROTECTED]):
> On Tue, 08 Feb 2005 11:24:50 CST, Michael Halcrow said:
> 
> > While the program is waiting for a keystroke, mount the block device.
> > Enter a keystroke.  The result without the patch is 1, which is a
> > security violation.  This occurs because the bd_release function will
> > bd_release(bdev) and set inode->i_security to NULL on the close(fd1).
> 
> Sounds like a bug, not a feature.  Should it be zeroing out inode->i_security
> for an inode with a non-zero reference count?

Valdis,

inode->i_security is no longer used after the patch.  Does your question
still apply with the proposed patch, %s/inode->i_security/file->f_security/?

Nevertheless, note that the thing being enforced is "no simultaneous
write access to a block device and mount of that block device."  The
file->f_security is just used as a flag to seclvl that when this file
is closed, we can bd_release the device to allow a mount or another
open(O_RDWR) of the file.  So references to the inode don't matter,
provided the other references are read accesses.  Which they have to
be, since otherwise the seclvl_bd_claim() would have failed on the
second open(O_RDWR) call.

I hope I'm at least remotely answering your question :)

-serge

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2005-02-08 Thread Valdis . Kletnieks
On Tue, 08 Feb 2005 11:24:50 CST, Michael Halcrow said:

> While the program is waiting for a keystroke, mount the block device.
> Enter a keystroke.  The result without the patch is 1, which is a
> security violation.  This occurs because the bd_release function will
> bd_release(bdev) and set inode->i_security to NULL on the close(fd1).

Sounds like a bug, not a feature.  Should it be zeroing out inode->i_security
for an inode with a non-zero reference count?


pgprTLY1VZm0q.pgp
Description: PGP signature


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

2005-02-08 Thread Michael Halcrow
On Mon, Feb 07, 2005 at 02:26:03PM -0800, Chris Wright wrote:
> * Michael Halcrow ([EMAIL PROTECTED]) wrote:
> > This is the third in a series of eight patches to the BSD Secure
> > Levels LSM.  It moves the claim on the block device from the inode
> > struct to the file struct in order to address a potential
> > circumvention of the control via hard links to block devices.  Thanks
> > to Serge Hallyn for pointing this out.
> 
> Hard links still point to same inode, what's the issue that this
> addresses?

Actually, it turns out that hard links have nothing to do with the
vulnerability that this patch addresses:

#include 
#include 
#include 
#include 

int main()
{
int fd1, fd2;
int rc;
fd1 = open( "/dev/device", O_RDONLY );
fd2 = open( "/dev/device", O_RDWR );
close(fd1);
getchar();
rc = write( fd2, "0", 1 );
printf( "write result: [%d]\n", rc );
close( fd2 );
return 0;
}

While the program is waiting for a keystroke, mount the block device.
Enter a keystroke.  The result without the patch is 1, which is a
security violation.  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.

Mike
.___.
 Michael A. Halcrow  
   Security Software Engineer, IBM Linux Technology Center   
GnuPG Fingerprint: 05B5 08A8 713A 64C1 D35D  2371 2D3C FDDA 3EB6 601D

The hokey pokey... What if that's really what it's all about? 


signature.asc
Description: Digital signature


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

2005-02-08 Thread David Wagner
>The attack is to hardlink some tempfile name to some file you want
>over-written.  This usually involves just a little bit of work, such as
>recognizing that a given root cronjob uses an unsafe predictable filename
>in /tmp (look at the Bugtraq or Full-Disclosure archives, there's plenty).
>Then you set a little program that sleep()s till a few seconds before
>the cronjob runs, does a getpid(), and then sprays hardlinks into the
>next 15 or 20 things that mktemp() will generate...

Got it.  Very good -- now I see.  Thanks for the explanation.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2005-02-08 Thread David Wagner
The attack is to hardlink some tempfile name to some file you want
over-written.  This usually involves just a little bit of work, such as
recognizing that a given root cronjob uses an unsafe predictable filename
in /tmp (look at the Bugtraq or Full-Disclosure archives, there's plenty).
Then you set a little program that sleep()s till a few seconds before
the cronjob runs, does a getpid(), and then sprays hardlinks into the
next 15 or 20 things that mktemp() will generate...

Got it.  Very good -- now I see.  Thanks for the explanation.
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2005-02-08 Thread Michael Halcrow
On Mon, Feb 07, 2005 at 02:26:03PM -0800, Chris Wright wrote:
 * Michael Halcrow ([EMAIL PROTECTED]) wrote:
  This is the third in a series of eight patches to the BSD Secure
  Levels LSM.  It moves the claim on the block device from the inode
  struct to the file struct in order to address a potential
  circumvention of the control via hard links to block devices.  Thanks
  to Serge Hallyn for pointing this out.
 
 Hard links still point to same inode, what's the issue that this
 addresses?

Actually, it turns out that hard links have nothing to do with the
vulnerability that this patch addresses:

#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include stdio.h

int main()
{
int fd1, fd2;
int rc;
fd1 = open( /dev/device, O_RDONLY );
fd2 = open( /dev/device, O_RDWR );
close(fd1);
getchar();
rc = write( fd2, 0, 1 );
printf( write result: [%d]\n, rc );
close( fd2 );
return 0;
}

While the program is waiting for a keystroke, mount the block device.
Enter a keystroke.  The result without the patch is 1, which is a
security violation.  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.

Mike
.___.
 Michael A. Halcrow  
   Security Software Engineer, IBM Linux Technology Center   
GnuPG Fingerprint: 05B5 08A8 713A 64C1 D35D  2371 2D3C FDDA 3EB6 601D

The hokey pokey... What if that's really what it's all about? 


signature.asc
Description: Digital signature


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

2005-02-08 Thread Valdis . Kletnieks
On Tue, 08 Feb 2005 11:24:50 CST, Michael Halcrow said:

 While the program is waiting for a keystroke, mount the block device.
 Enter a keystroke.  The result without the patch is 1, which is a
 security violation.  This occurs because the bd_release function will
 bd_release(bdev) and set inode-i_security to NULL on the close(fd1).

Sounds like a bug, not a feature.  Should it be zeroing out inode-i_security
for an inode with a non-zero reference count?


pgprTLY1VZm0q.pgp
Description: PGP signature


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

2005-02-08 Thread Serge E. Hallyn
Quoting [EMAIL PROTECTED] ([EMAIL PROTECTED]):
 On Tue, 08 Feb 2005 11:24:50 CST, Michael Halcrow said:
 
  While the program is waiting for a keystroke, mount the block device.
  Enter a keystroke.  The result without the patch is 1, which is a
  security violation.  This occurs because the bd_release function will
  bd_release(bdev) and set inode-i_security to NULL on the close(fd1).
 
 Sounds like a bug, not a feature.  Should it be zeroing out inode-i_security
 for an inode with a non-zero reference count?

Valdis,

inode-i_security is no longer used after the patch.  Does your question
still apply with the proposed patch, %s/inode-i_security/file-f_security/?

Nevertheless, note that the thing being enforced is no simultaneous
write access to a block device and mount of that block device.  The
file-f_security is just used as a flag to seclvl that when this file
is closed, we can bd_release the device to allow a mount or another
open(O_RDWR) of the file.  So references to the inode don't matter,
provided the other references are read accesses.  Which they have to
be, since otherwise the seclvl_bd_claim() would have failed on the
second open(O_RDWR) call.

I hope I'm at least remotely answering your question :)

-serge

-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2005-02-08 Thread Chris Wright
* Michael Halcrow ([EMAIL PROTECTED]) 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 [EMAIL PROTECTED]

--- a/security/seclvl.c~bd_claim2005-02-08 15:05:09.0 -0800
+++ b/security/seclvl.c 2005-02-08 15:05:17.0 -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);
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2005-02-07 Thread Valdis . Kletnieks
On Mon, 07 Feb 2005 18:20:36 PST, Chris Wright said:
> * [EMAIL PROTECTED] ([EMAIL PROTECTED]) wrote:
> > open("/tmp/sh-thd-1107848098", O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_LARGEFILE,
 0600) = 3
> 
> O_EXCL
> 
> > Wow - if my /tmp was on the same partition, and I'd hard-linked that
> > file to /etc/passwd, it would be toast now if root had run it.
> 
> So, in fact, it wouldn't ;-)

Well.. Yeah.  bash gets it right, a lot of programs botch it. ;)


pgpW8EazQy2Vi.pgp
Description: PGP signature


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

2005-02-07 Thread Chris Wright
* [EMAIL PROTECTED] ([EMAIL PROTECTED]) wrote:
> open("/tmp/sh-thd-1107848098", O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_LARGEFILE, 
> 0600) = 3

O_EXCL

> Wow - if my /tmp was on the same partition, and I'd hard-linked that
> file to /etc/passwd, it would be toast now if root had run it.

So, in fact, it wouldn't ;-)

thanks,
-chris
-- 
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2005-02-07 Thread Valdis . Kletnieks
On Tue, 08 Feb 2005 01:48:40 GMT, David Wagner said:

> How would /etc/passwd get clobbered?  Are you thinking that a tmp
> cleaner run by cron might delete /tmp/whatever (i.e., delete the hardlink
> you created above)?  But deleting /tmp/whatever is safe; it doesn't affect
> /etc/passwd.  I'm guessing I'm probably missing something.

The attack is to hardlink some tempfile name to some file you want over-written.
This usually involves just a little bit of work, such as recognizing that a 
given
root cronjob uses an unsafe predictable filename in /tmp (look at the Bugtraq or
Full-Disclosure archives, there's plenty).  Then you set a little program that
sleep()s till a few seconds before the cronjob runs, does a getpid(), and then
sprays hardlinks into the next 15 or 20 things that mktemp() will generate...

Consider how bash implements "here" scripts:

#!/bin/bash
echo << EOF
some trash
EOF

Now let's look at the strace (snipped for brevity..)

statfs("/tmp", {f_type="EXT2_SUPER_MAGIC", f_bsize=1024, f_blocks=253871, 
f_bfree=213773, f_bavail=200666, f_files=65536, f_ffree=65445, f_fsid={0, 0}, 
f_namelen=255, f_frsize=1024}) = 0
time(NULL)  = 1107828098
open("/tmp/sh-thd-1107848098", O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_LARGEFILE, 
0600) = 3
dup(3)  = 4
fcntl64(4, F_GETFL) = 0x8001 (flags O_WRONLY|O_LARGEFILE)
fstat64(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 
0xb7d71000
_llseek(4, 0, [0], SEEK_CUR)= 0
write(4, "some trash\n", 11)= 11
close(4)= 0
munmap(0xb7d71000, 4096)= 0
open("/tmp/sh-thd-1107848098", O_RDONLY|O_LARGEFILE) = 4
close(3)= 0
unlink("/tmp/sh-thd-1107848098")= 0
fcntl64(0, F_GETFD) = 0
fcntl64(0, F_DUPFD, 10) = 10
fcntl64(0, F_GETFD) = 0
fcntl64(10, F_SETFD, FD_CLOEXEC)= 0
dup2(4, 0)  = 0
close(4)= 0

Wow - if my /tmp was on the same partition, and I'd hard-linked that
file to /etc/passwd, it would be toast now if root had run it.

You usually can't control what gets written - but often it's sufficient for the
attacker to simply get a file clobbered


pgp1unSohNbRA.pgp
Description: PGP signature


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

2005-02-07 Thread David Wagner
>For those systems that have everything on one big partition, you can often
>do stuff like:
>
>ln /etc/passwd /tmp/
>
>and wait for /etc/passwd to get clobbered by a cron job run by root...

How would /etc/passwd get clobbered?  Are you thinking that a tmp
cleaner run by cron might delete /tmp/whatever (i.e., delete the hardlink
you created above)?  But deleting /tmp/whatever is safe; it doesn't affect
/etc/passwd.  I'm guessing I'm probably missing something.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2005-02-07 Thread Valdis . Kletnieks
On Mon, 07 Feb 2005 14:26:03 PST, Chris Wright said:
> * Michael Halcrow ([EMAIL PROTECTED]) wrote:
> > This is the third in a series of eight patches to the BSD Secure
> > Levels LSM.  It moves the claim on the block device from the inode
> > struct to the file struct in order to address a potential
> > circumvention of the control via hard links to block devices.  Thanks
> > to Serge Hallyn for pointing this out.
> 
> Hard links still point to same inode, what's the issue that this
> addresses?

Ignore that last - I thought it was the "filesystem linking permissions"
thread rather than the BSD Secure linking permissions thread. ;)



pgpHd0UzzrMjl.pgp
Description: PGP signature


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

2005-02-07 Thread Valdis . Kletnieks
On Mon, 07 Feb 2005 14:26:03 PST, Chris Wright said:

> Hard links still point to same inode, what's the issue that this
> addresses?

For those systems that have everything on one big partition, you can often
do stuff like:

ln /etc/passwd /tmp/

and wait for /etc/passwd to get clobbered by a cron job run by root...


pgpv1juO6RgIl.pgp
Description: PGP signature


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

2005-02-07 Thread Chris Wright
* Michael Halcrow ([EMAIL PROTECTED]) wrote:
> This is the third in a series of eight patches to the BSD Secure
> Levels LSM.  It moves the claim on the block device from the inode
> struct to the file struct in order to address a potential
> circumvention of the control via hard links to block devices.  Thanks
> to Serge Hallyn for pointing this out.

Hard links still point to same inode, what's the issue that this
addresses?

thanks,
-chris
-- 
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2005-02-07 Thread Michael Halcrow
This is the third in a series of eight patches to the BSD Secure
Levels LSM.  It moves the claim on the block device from the inode
struct to the file struct in order to address a potential
circumvention of the control via hard links to block devices.  Thanks
to Serge Hallyn for pointing this out.

Signed off by: Michael Halcrow <[EMAIL PROTECTED]>
Index: linux-2.6.11-rc2-mm1-modules/security/seclvl.c
===
--- linux-2.6.11-rc2-mm1-modules.orig/security/seclvl.c 2005-02-03 
15:36:43.925683472 -0600
+++ linux-2.6.11-rc2-mm1-modules/security/seclvl.c  2005-02-03 
16:41:55.075098384 -0600
@@ -487,46 +487,35 @@
return 0;
 }
 
-/* claim the blockdev to exclude mounters, release on file close */
-static int seclvl_bd_claim(struct inode *inode)
+/**
+ * Claim the blockdev to exclude mounters; release on file close.
+ */
+static int seclvl_bd_claim(struct file * filp)
 {
int holder;
struct block_device *bdev = NULL;
-   dev_t dev = inode->i_rdev;
+   dev_t dev = filp->f_dentry->d_inode->i_rdev;
bdev = open_by_devnum(dev, FMODE_WRITE);
if (bdev) {
if (bd_claim(bdev, )) {
blkdev_put(bdev);
return -EPERM;
}
-   /* claimed, mark it to release on close */
-   inode->i_security = current;
+   /* Claimed; mark it to release on close */
+   filp->f_security = current;
}
return 0;
 }
 
-/* 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;
-   }
-   }
-}
-
 /**
  * Security for writes to block devices is regulated by this seclvl
  * function.  Deny all writes to block devices in seclvl 2.  In
  * seclvl 1, we only deny writes to *mounted* block devices.
  */
-static int
-seclvl_inode_permission(struct inode *inode, int mask, struct nameidata *nd)
+static int seclvl_file_permission(struct file * filp, int mask)
 {
-   if (current->pid != 1 && S_ISBLK(inode->i_mode) && (mask & MAY_WRITE)) {
+   if (current->pid != 1 && S_ISBLK(filp->f_dentry->d_inode->i_mode)
+   && (mask & MAY_WRITE)) {
switch (seclvl) {
case 2:
seclvl_printk(1, KERN_WARNING "%s: Write to block "
@@ -534,7 +523,7 @@
  __FUNCTION__, seclvl);
return -EPERM;
case 1:
-   if (seclvl_bd_claim(inode)) {
+   if (seclvl_bd_claim(filp)) {
seclvl_printk(1, KERN_WARNING "%s: Write to "
  "mounted block device denied in "
  "secure level [%d]\n",
@@ -549,7 +538,7 @@
 /**
  * The SUID and SGID bits cannot be set in seclvl >= 1
  */
-static int seclvl_inode_setattr(struct dentry *dentry, struct iattr *iattr)
+static int seclvl_inode_setattr(struct dentry * dentry, struct iattr * iattr)
 {
if (seclvl > 0) {
if (dentry && dentry->d_inode
@@ -599,15 +588,23 @@
 return 0;
 }
 
-/* release busied block devices */
-static void seclvl_file_free_security(struct file *filp)
+/**
+ * Release busied block devices.
+ */
+static void seclvl_file_free_security(struct file * filp)
 {
-   struct dentry *dentry = filp->f_dentry;
-   struct inode *inode = NULL;
-
-   if (dentry) {
-   inode = dentry->d_inode;
-   seclvl_bd_release(inode);
+   struct dentry * dentry = filp->f_dentry;
+   if (dentry && (filp->f_mode & FMODE_WRITE)) {
+   struct inode * inode = dentry->d_inode;
+   if (inode && S_ISBLK(inode->i_mode)
+   && filp->f_security == current) {
+   struct block_device *bdev = inode->i_bdev;
+   if (bdev) {
+   bd_release(bdev);
+   blkdev_put(bdev);
+   filp->f_security = NULL;
+   }
+   }
}
 }
 
@@ -630,7 +627,7 @@
 static struct security_operations seclvl_ops = {
.ptrace = seclvl_ptrace,
.capable = seclvl_capable,
-   .inode_permission = seclvl_inode_permission,
+   .file_permission = seclvl_file_permission,
.inode_setattr = seclvl_inode_setattr,
.inode_mknod = seclvl_inode_mknod,
.inode_create = seclvl_inode_create,


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

2005-02-07 Thread Michael Halcrow
This is the third in a series of eight patches to the BSD Secure
Levels LSM.  It moves the claim on the block device from the inode
struct to the file struct in order to address a potential
circumvention of the control via hard links to block devices.  Thanks
to Serge Hallyn for pointing this out.

Signed off by: Michael Halcrow [EMAIL PROTECTED]
Index: linux-2.6.11-rc2-mm1-modules/security/seclvl.c
===
--- linux-2.6.11-rc2-mm1-modules.orig/security/seclvl.c 2005-02-03 
15:36:43.925683472 -0600
+++ linux-2.6.11-rc2-mm1-modules/security/seclvl.c  2005-02-03 
16:41:55.075098384 -0600
@@ -487,46 +487,35 @@
return 0;
 }
 
-/* claim the blockdev to exclude mounters, release on file close */
-static int seclvl_bd_claim(struct inode *inode)
+/**
+ * Claim the blockdev to exclude mounters; release on file close.
+ */
+static int seclvl_bd_claim(struct file * filp)
 {
int holder;
struct block_device *bdev = NULL;
-   dev_t dev = inode-i_rdev;
+   dev_t dev = filp-f_dentry-d_inode-i_rdev;
bdev = open_by_devnum(dev, FMODE_WRITE);
if (bdev) {
if (bd_claim(bdev, holder)) {
blkdev_put(bdev);
return -EPERM;
}
-   /* claimed, mark it to release on close */
-   inode-i_security = current;
+   /* Claimed; mark it to release on close */
+   filp-f_security = current;
}
return 0;
 }
 
-/* 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;
-   }
-   }
-}
-
 /**
  * Security for writes to block devices is regulated by this seclvl
  * function.  Deny all writes to block devices in seclvl 2.  In
  * seclvl 1, we only deny writes to *mounted* block devices.
  */
-static int
-seclvl_inode_permission(struct inode *inode, int mask, struct nameidata *nd)
+static int seclvl_file_permission(struct file * filp, int mask)
 {
-   if (current-pid != 1  S_ISBLK(inode-i_mode)  (mask  MAY_WRITE)) {
+   if (current-pid != 1  S_ISBLK(filp-f_dentry-d_inode-i_mode)
+(mask  MAY_WRITE)) {
switch (seclvl) {
case 2:
seclvl_printk(1, KERN_WARNING %s: Write to block 
@@ -534,7 +523,7 @@
  __FUNCTION__, seclvl);
return -EPERM;
case 1:
-   if (seclvl_bd_claim(inode)) {
+   if (seclvl_bd_claim(filp)) {
seclvl_printk(1, KERN_WARNING %s: Write to 
  mounted block device denied in 
  secure level [%d]\n,
@@ -549,7 +538,7 @@
 /**
  * The SUID and SGID bits cannot be set in seclvl = 1
  */
-static int seclvl_inode_setattr(struct dentry *dentry, struct iattr *iattr)
+static int seclvl_inode_setattr(struct dentry * dentry, struct iattr * iattr)
 {
if (seclvl  0) {
if (dentry  dentry-d_inode
@@ -599,15 +588,23 @@
 return 0;
 }
 
-/* release busied block devices */
-static void seclvl_file_free_security(struct file *filp)
+/**
+ * Release busied block devices.
+ */
+static void seclvl_file_free_security(struct file * filp)
 {
-   struct dentry *dentry = filp-f_dentry;
-   struct inode *inode = NULL;
-
-   if (dentry) {
-   inode = dentry-d_inode;
-   seclvl_bd_release(inode);
+   struct dentry * dentry = filp-f_dentry;
+   if (dentry  (filp-f_mode  FMODE_WRITE)) {
+   struct inode * inode = dentry-d_inode;
+   if (inode  S_ISBLK(inode-i_mode)
+filp-f_security == current) {
+   struct block_device *bdev = inode-i_bdev;
+   if (bdev) {
+   bd_release(bdev);
+   blkdev_put(bdev);
+   filp-f_security = NULL;
+   }
+   }
}
 }
 
@@ -630,7 +627,7 @@
 static struct security_operations seclvl_ops = {
.ptrace = seclvl_ptrace,
.capable = seclvl_capable,
-   .inode_permission = seclvl_inode_permission,
+   .file_permission = seclvl_file_permission,
.inode_setattr = seclvl_inode_setattr,
.inode_mknod = seclvl_inode_mknod,
.inode_create = seclvl_inode_create,


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

2005-02-07 Thread Chris Wright
* Michael Halcrow ([EMAIL PROTECTED]) wrote:
 This is the third in a series of eight patches to the BSD Secure
 Levels LSM.  It moves the claim on the block device from the inode
 struct to the file struct in order to address a potential
 circumvention of the control via hard links to block devices.  Thanks
 to Serge Hallyn for pointing this out.

Hard links still point to same inode, what's the issue that this
addresses?

thanks,
-chris
-- 
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2005-02-07 Thread Valdis . Kletnieks
On Mon, 07 Feb 2005 14:26:03 PST, Chris Wright said:

 Hard links still point to same inode, what's the issue that this
 addresses?

For those systems that have everything on one big partition, you can often
do stuff like:

ln /etc/passwd /tmp/filename_generated_by_mktemp

and wait for /etc/passwd to get clobbered by a cron job run by root...


pgpv1juO6RgIl.pgp
Description: PGP signature


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

2005-02-07 Thread Valdis . Kletnieks
On Mon, 07 Feb 2005 14:26:03 PST, Chris Wright said:
 * Michael Halcrow ([EMAIL PROTECTED]) wrote:
  This is the third in a series of eight patches to the BSD Secure
  Levels LSM.  It moves the claim on the block device from the inode
  struct to the file struct in order to address a potential
  circumvention of the control via hard links to block devices.  Thanks
  to Serge Hallyn for pointing this out.
 
 Hard links still point to same inode, what's the issue that this
 addresses?

Ignore that last - I thought it was the filesystem linking permissions
thread rather than the BSD Secure linking permissions thread. ;)



pgpHd0UzzrMjl.pgp
Description: PGP signature


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

2005-02-07 Thread David Wagner
For those systems that have everything on one big partition, you can often
do stuff like:

ln /etc/passwd /tmp/filename_generated_by_mktemp

and wait for /etc/passwd to get clobbered by a cron job run by root...

How would /etc/passwd get clobbered?  Are you thinking that a tmp
cleaner run by cron might delete /tmp/whatever (i.e., delete the hardlink
you created above)?  But deleting /tmp/whatever is safe; it doesn't affect
/etc/passwd.  I'm guessing I'm probably missing something.
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2005-02-07 Thread Valdis . Kletnieks
On Tue, 08 Feb 2005 01:48:40 GMT, David Wagner said:

 How would /etc/passwd get clobbered?  Are you thinking that a tmp
 cleaner run by cron might delete /tmp/whatever (i.e., delete the hardlink
 you created above)?  But deleting /tmp/whatever is safe; it doesn't affect
 /etc/passwd.  I'm guessing I'm probably missing something.

The attack is to hardlink some tempfile name to some file you want over-written.
This usually involves just a little bit of work, such as recognizing that a 
given
root cronjob uses an unsafe predictable filename in /tmp (look at the Bugtraq or
Full-Disclosure archives, there's plenty).  Then you set a little program that
sleep()s till a few seconds before the cronjob runs, does a getpid(), and then
sprays hardlinks into the next 15 or 20 things that mktemp() will generate...

Consider how bash implements here scripts:

#!/bin/bash
echo  EOF
some trash
EOF

Now let's look at the strace (snipped for brevity..)

statfs(/tmp, {f_type=EXT2_SUPER_MAGIC, f_bsize=1024, f_blocks=253871, 
f_bfree=213773, f_bavail=200666, f_files=65536, f_ffree=65445, f_fsid={0, 0}, 
f_namelen=255, f_frsize=1024}) = 0
time(NULL)  = 1107828098
open(/tmp/sh-thd-1107848098, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_LARGEFILE, 
0600) = 3
dup(3)  = 4
fcntl64(4, F_GETFL) = 0x8001 (flags O_WRONLY|O_LARGEFILE)
fstat64(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 
0xb7d71000
_llseek(4, 0, [0], SEEK_CUR)= 0
write(4, some trash\n, 11)= 11
close(4)= 0
munmap(0xb7d71000, 4096)= 0
open(/tmp/sh-thd-1107848098, O_RDONLY|O_LARGEFILE) = 4
close(3)= 0
unlink(/tmp/sh-thd-1107848098)= 0
fcntl64(0, F_GETFD) = 0
fcntl64(0, F_DUPFD, 10) = 10
fcntl64(0, F_GETFD) = 0
fcntl64(10, F_SETFD, FD_CLOEXEC)= 0
dup2(4, 0)  = 0
close(4)= 0

Wow - if my /tmp was on the same partition, and I'd hard-linked that
file to /etc/passwd, it would be toast now if root had run it.

You usually can't control what gets written - but often it's sufficient for the
attacker to simply get a file clobbered


pgp1unSohNbRA.pgp
Description: PGP signature


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

2005-02-07 Thread Chris Wright
* [EMAIL PROTECTED] ([EMAIL PROTECTED]) wrote:
 open(/tmp/sh-thd-1107848098, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_LARGEFILE, 
 0600) = 3

O_EXCL

 Wow - if my /tmp was on the same partition, and I'd hard-linked that
 file to /etc/passwd, it would be toast now if root had run it.

So, in fact, it wouldn't ;-)

thanks,
-chris
-- 
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


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

2005-02-07 Thread Valdis . Kletnieks
On Mon, 07 Feb 2005 18:20:36 PST, Chris Wright said:
 * [EMAIL PROTECTED] ([EMAIL PROTECTED]) wrote:
  open(/tmp/sh-thd-1107848098, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_LARGEFILE,
 0600) = 3
 
 O_EXCL
 
  Wow - if my /tmp was on the same partition, and I'd hard-linked that
  file to /etc/passwd, it would be toast now if root had run it.
 
 So, in fact, it wouldn't ;-)

Well.. Yeah.  bash gets it right, a lot of programs botch it. ;)


pgpW8EazQy2Vi.pgp
Description: PGP signature