From: Jeff Mahoney 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. Signed-off-by: Jeff Mahoney diff -ruNpX dontdiff linux-2.6.9.base/include/linux/fs.h linux-2.6.9.private/include/linux/fs.h --- linux-2.6.9.base/include/linux/fs.h 2004-11-19 14:40:56.000000000 -0500 +++ linux-2.6.9.private/include/linux/fs.h 2004-11-30 15:04:24.000000000 -0500 @@ -146,6 +146,7 @@ extern int leases_enable, dir_notify_ena #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 @@ -180,6 +181,7 @@ extern int leases_enable, dir_notify_ena #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.9.base/include/linux/security.h linux-2.6.9.private/include/linux/security.h --- linux-2.6.9.base/include/linux/security.h 2004-08-14 01:37:30.000000000 -0400 +++ linux-2.6.9.private/include/linux/security.h 2004-12-01 14:14:07.000000000 -0500 @@ -1406,11 +1406,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); } @@ -1418,6 +1422,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); } @@ -1425,6 +1431,8 @@ static inline void security_inode_post_c struct dentry *dentry, int mode) { + if (unlikely (IS_PRIVATE (dentry->d_inode))) + return; security_ops->inode_post_create (dir, dentry, mode); } @@ -1432,6 +1440,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); } @@ -1439,12 +1449,16 @@ static inline void security_inode_post_l struct inode *dir, struct dentry *new_dentry) { + if (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); } @@ -1452,6 +1466,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); } @@ -1459,6 +1475,8 @@ static inline void security_inode_post_s struct dentry *dentry, const char *old_name) { + if (unlikely (IS_PRIVATE (dentry->d_inode))) + return; security_ops->inode_post_symlink (dir, dentry, old_name); } @@ -1466,6 +1484,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); } @@ -1473,12 +1493,16 @@ static inline void security_inode_post_m struct dentry *dentry, int mode) { + if (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); } @@ -1486,6 +1510,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); } @@ -1493,6 +1519,8 @@ static inline void security_inode_post_m struct dentry *dentry, int mode, dev_t dev) { + if (unlikely (IS_PRIVATE (dentry->d_inode))) + return; security_ops->inode_post_mknod (dir, dentry, mode, dev); } @@ -1501,6 +1529,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); } @@ -1510,83 +1541,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 dentry *dentry, const char *name, void *buffer, size_t size) { + if (unlikely (IS_PRIVATE (dentry->d_inode))) + return 0; return security_ops->inode_getsecurity(dentry, name, buffer, size); } static inline int security_inode_setsecurity(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { + if (unlikely (IS_PRIVATE (dentry->d_inode))) + return 0; return security_ops->inode_setsecurity(dentry, name, value, size, flags); } static inline int security_inode_listsecurity(struct dentry *dentry, char *buffer) { + if (unlikely (IS_PRIVATE (dentry->d_inode))) + return 0; return security_ops->inode_listsecurity(dentry, buffer); } @@ -1863,6 +1925,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); }