2005-03-04 20:11:29

by Jeff Mahoney

[permalink] [raw]
Subject: [PATCH 1/4] vfs: adds the S_PRIVATE flag and adds use to security

This patch adds an S_PRIVATE flag to inode->i_flags to mark an inode as
filesystem-internal. As such, it should be excepted from the security
infrastructure to allow the filesystem to perform its own access control.

Changes:
- Post-operations for calls that generally instantiate the dentry but
aren't obligated to now allow for a NULL dentry->d_inode

Signed-off-by: Jeff Mahoney <[email protected]>

diff -ruNpX dontdiff linux-2.6.11.orig/include/linux/fs.h linux-2.6.11.devel/include/linux/fs.h
--- linux-2.6.11.orig/include/linux/fs.h 2005-03-02 02:37:50.000000000 -0500
+++ linux-2.6.11.devel/include/linux/fs.h 2005-03-04 09:58:45.000000000 -0500
@@ -129,6 +129,7 @@ extern int dir_notify_enable;
#define S_DIRSYNC 64 /* Directory modifications are synchronous */
#define S_NOCMTIME 128 /* Do not update file c/mtime */
#define S_SWAPFILE 256 /* Do not truncate: swapon got its bmaps */
+#define S_PRIVATE 512 /* Inode is fs-internal */

/*
* Note that nosuid etc flags are inode-specific: setting some file-system
@@ -162,6 +163,7 @@ extern int dir_notify_enable;
#define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
#define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME)
#define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE)
+#define IS_PRIVATE(inode) ((inode)->i_flags & S_PRIVATE)

/* the read-only stuff doesn't really belong here, but any other place is
probably as bad and I don't want to create yet another include file. */
diff -ruNpX dontdiff linux-2.6.11.orig/include/linux/security.h linux-2.6.11.devel/include/linux/security.h
--- linux-2.6.11.orig/include/linux/security.h 2005-03-02 02:38:17.000000000 -0500
+++ linux-2.6.11.devel/include/linux/security.h 2005-03-04 10:02:40.000000000 -0500
@@ -1426,11 +1426,15 @@ static inline void security_sb_post_pivo

static inline int security_inode_alloc (struct inode *inode)
{
+ if (unlikely (IS_PRIVATE (inode)))
+ return 0;
return security_ops->inode_alloc_security (inode);
}

static inline void security_inode_free (struct inode *inode)
{
+ if (unlikely (IS_PRIVATE (inode)))
+ return;
security_ops->inode_free_security (inode);
}

@@ -1438,6 +1442,8 @@ static inline int security_inode_create
struct dentry *dentry,
int mode)
{
+ if (unlikely (IS_PRIVATE (dir)))
+ return 0;
return security_ops->inode_create (dir, dentry, mode);
}

@@ -1445,6 +1451,8 @@ static inline void security_inode_post_c
struct dentry *dentry,
int mode)
{
+ if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode)))
+ return;
security_ops->inode_post_create (dir, dentry, mode);
}

@@ -1452,6 +1460,8 @@ static inline int security_inode_link (s
struct inode *dir,
struct dentry *new_dentry)
{
+ if (unlikely (IS_PRIVATE (old_dentry->d_inode)))
+ return 0;
return security_ops->inode_link (old_dentry, dir, new_dentry);
}

@@ -1459,12 +1469,16 @@ static inline void security_inode_post_l
struct inode *dir,
struct dentry *new_dentry)
{
+ if (new_dentry->d_inode && unlikely (IS_PRIVATE (new_dentry->d_inode)))
+ return;
security_ops->inode_post_link (old_dentry, dir, new_dentry);
}

static inline int security_inode_unlink (struct inode *dir,
struct dentry *dentry)
{
+ if (unlikely (IS_PRIVATE (dentry->d_inode)))
+ return 0;
return security_ops->inode_unlink (dir, dentry);
}

@@ -1472,6 +1486,8 @@ static inline int security_inode_symlink
struct dentry *dentry,
const char *old_name)
{
+ if (unlikely (IS_PRIVATE (dir)))
+ return 0;
return security_ops->inode_symlink (dir, dentry, old_name);
}

@@ -1479,6 +1495,8 @@ static inline void security_inode_post_s
struct dentry *dentry,
const char *old_name)
{
+ if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode)))
+ return;
security_ops->inode_post_symlink (dir, dentry, old_name);
}

@@ -1486,6 +1504,8 @@ static inline int security_inode_mkdir (
struct dentry *dentry,
int mode)
{
+ if (unlikely (IS_PRIVATE (dir)))
+ return 0;
return security_ops->inode_mkdir (dir, dentry, mode);
}

@@ -1493,12 +1513,16 @@ static inline void security_inode_post_m
struct dentry *dentry,
int mode)
{
+ if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode)))
+ return;
security_ops->inode_post_mkdir (dir, dentry, mode);
}

static inline int security_inode_rmdir (struct inode *dir,
struct dentry *dentry)
{
+ if (unlikely (IS_PRIVATE (dentry->d_inode)))
+ return 0;
return security_ops->inode_rmdir (dir, dentry);
}

@@ -1506,6 +1530,8 @@ static inline int security_inode_mknod (
struct dentry *dentry,
int mode, dev_t dev)
{
+ if (unlikely (IS_PRIVATE (dir)))
+ return 0;
return security_ops->inode_mknod (dir, dentry, mode, dev);
}

@@ -1513,6 +1539,8 @@ static inline void security_inode_post_m
struct dentry *dentry,
int mode, dev_t dev)
{
+ if (dentry->d_inode && unlikely (IS_PRIVATE (dentry->d_inode)))
+ return;
security_ops->inode_post_mknod (dir, dentry, mode, dev);
}

@@ -1521,6 +1549,9 @@ static inline int security_inode_rename
struct inode *new_dir,
struct dentry *new_dentry)
{
+ if (unlikely (IS_PRIVATE (old_dentry->d_inode) ||
+ (new_dentry->d_inode && IS_PRIVATE (new_dentry->d_inode))))
+ return 0;
return security_ops->inode_rename (old_dir, old_dentry,
new_dir, new_dentry);
}
@@ -1530,83 +1561,114 @@ static inline void security_inode_post_r
struct inode *new_dir,
struct dentry *new_dentry)
{
+ if (unlikely (IS_PRIVATE (old_dentry->d_inode) ||
+ (new_dentry->d_inode && IS_PRIVATE (new_dentry->d_inode))))
+ return;
security_ops->inode_post_rename (old_dir, old_dentry,
new_dir, new_dentry);
}

static inline int security_inode_readlink (struct dentry *dentry)
{
+ if (unlikely (IS_PRIVATE (dentry->d_inode)))
+ return 0;
return security_ops->inode_readlink (dentry);
}

static inline int security_inode_follow_link (struct dentry *dentry,
struct nameidata *nd)
{
+ if (unlikely (IS_PRIVATE (dentry->d_inode)))
+ return 0;
return security_ops->inode_follow_link (dentry, nd);
}

static inline int security_inode_permission (struct inode *inode, int mask,
struct nameidata *nd)
{
+ if (unlikely (IS_PRIVATE (inode)))
+ return 0;
return security_ops->inode_permission (inode, mask, nd);
}

static inline int security_inode_setattr (struct dentry *dentry,
struct iattr *attr)
{
+ if (unlikely (IS_PRIVATE (dentry->d_inode)))
+ return 0;
return security_ops->inode_setattr (dentry, attr);
}

static inline int security_inode_getattr (struct vfsmount *mnt,
struct dentry *dentry)
{
+ if (unlikely (IS_PRIVATE (dentry->d_inode)))
+ return 0;
return security_ops->inode_getattr (mnt, dentry);
}

static inline void security_inode_delete (struct inode *inode)
{
+ if (unlikely (IS_PRIVATE (inode)))
+ return;
security_ops->inode_delete (inode);
}

static inline int security_inode_setxattr (struct dentry *dentry, char *name,
void *value, size_t size, int flags)
{
+ if (unlikely (IS_PRIVATE (dentry->d_inode)))
+ return 0;
return security_ops->inode_setxattr (dentry, name, value, size, flags);
}

static inline void security_inode_post_setxattr (struct dentry *dentry, char *name,
void *value, size_t size, int flags)
{
+ if (unlikely (IS_PRIVATE (dentry->d_inode)))
+ return;
security_ops->inode_post_setxattr (dentry, name, value, size, flags);
}

static inline int security_inode_getxattr (struct dentry *dentry, char *name)
{
+ if (unlikely (IS_PRIVATE (dentry->d_inode)))
+ return 0;
return security_ops->inode_getxattr (dentry, name);
}

static inline int security_inode_listxattr (struct dentry *dentry)
{
+ if (unlikely (IS_PRIVATE (dentry->d_inode)))
+ return 0;
return security_ops->inode_listxattr (dentry);
}

static inline int security_inode_removexattr (struct dentry *dentry, char *name)
{
+ if (unlikely (IS_PRIVATE (dentry->d_inode)))
+ return 0;
return security_ops->inode_removexattr (dentry, name);
}

static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
{
+ if (unlikely (IS_PRIVATE (inode)))
+ return 0;
return security_ops->inode_getsecurity(inode, name, buffer, size);
}

static inline int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags)
{
+ if (unlikely (IS_PRIVATE (inode)))
+ return 0;
return security_ops->inode_setsecurity(inode, name, value, size, flags);
}

static inline int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size)
{
+ if (unlikely (IS_PRIVATE (inode)))
+ return 0;
return security_ops->inode_listsecurity(inode, buffer, buffer_size);
}

@@ -1883,6 +1945,8 @@ static inline int security_sem_semop (st

static inline void security_d_instantiate (struct dentry *dentry, struct inode *inode)
{
+ if (unlikely (inode && IS_PRIVATE (inode)))
+ return;
security_ops->d_instantiate (dentry, inode);
}

--
Jeff Mahoney
SuSE Labs


2005-03-05 05:42:32

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 1/4] vfs: adds the S_PRIVATE flag and adds use to security

Jeffrey Mahoney <[email protected]> wrote:
>
> This patch adds an S_PRIVATE flag to inode->i_flags to mark an inode as
> filesystem-internal. As such, it should be excepted from the security
> infrastructure to allow the filesystem to perform its own access control.

OK, thanks. I'll assume that the other three patches are unchanged.

I don't think we've heard from the SELinux team regarding these patches?

(See http://www.zip.com.au/~akpm/linux/patches/stuff/selinux-reiserfs/)

2005-03-05 17:41:31

by Jeff Mahoney

[permalink] [raw]
Subject: Re: [PATCH 1/4] vfs: adds the S_PRIVATE flag and adds use to security

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Andrew Morton wrote:
> Jeffrey Mahoney <[email protected]> wrote:
>
>> This patch adds an S_PRIVATE flag to inode->i_flags to mark an inode as
>> filesystem-internal. As such, it should be excepted from the security
>> infrastructure to allow the filesystem to perform its own access control.
>
>
> OK, thanks. I'll assume that the other three patches are unchanged.
>
> I don't think we've heard from the SELinux team regarding these patches?
>
> (See http://www.zip.com.au/~akpm/linux/patches/stuff/selinux-reiserfs/)

That's correct, the others are unchanged.

- -Jeff

- --
Jeff Mahoney
SuSE Labs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)

iD8DBQFCKe+XLPWxlyuTD7IRApGeAJ9UWMIQSV1WlKlJg1Ml/hP36zSW0ACePTDW
qGUzKyItFVw9DFp9UoyaNHQ=
=LdAr
-----END PGP SIGNATURE-----

2005-03-07 15:00:53

by Stephen Smalley

[permalink] [raw]
Subject: Re: [PATCH 1/4] vfs: adds the S_PRIVATE flag and adds use to security

On Fri, 2005-03-04 at 21:28 -0800, Andrew Morton wrote:
> Jeffrey Mahoney <[email protected]> wrote:
> >
> > This patch adds an S_PRIVATE flag to inode->i_flags to mark an inode as
> > filesystem-internal. As such, it should be excepted from the security
> > infrastructure to allow the filesystem to perform its own access control.
>
> OK, thanks. I'll assume that the other three patches are unchanged.
>
> I don't think we've heard from the SELinux team regarding these patches?
>
> (See http://www.zip.com.au/~akpm/linux/patches/stuff/selinux-reiserfs/)

Acked-by: Stephen Smalley <[email protected]>

--
Stephen Smalley <[email protected]>
National Security Agency

2005-03-08 03:47:28

by Chris Wright

[permalink] [raw]
Subject: Re: [PATCH 1/4] vfs: adds the S_PRIVATE flag and adds use to security

* Andrew Morton ([email protected]) wrote:
> Jeffrey Mahoney <[email protected]> wrote:
> >
> > This patch adds an S_PRIVATE flag to inode->i_flags to mark an inode as
> > filesystem-internal. As such, it should be excepted from the security
> > infrastructure to allow the filesystem to perform its own access control.
>
> OK, thanks. I'll assume that the other three patches are unchanged.
>
> I don't think we've heard from the SELinux team regarding these patches?

I've no issue with these patches.

Acked-by: Chris Wright <[email protected]>
--
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net