...and this attached patch, relative to the head of the lsm-2.5 tree, adds d_instantiate and removes inode_post_lookup from the lsm-2.5 tree. The only significant difference between this patch and the one for 2.4 is the need to cover the case in d_splice_alias with a security_d_instantiate call. Also, this patch includes minor fixes to enable DTE to compile in the 2.5 tree, removing its sys_security entry and adding a #include. > The attached patch, relative to the back port of LSM changes from 2.5 patch, > adds a d_instantiate hook and removes the inode_post_lookup hook from the > lsm-2.4 tree. The patch removes the stub inode_post_lookup hook functions from > modules that are not using the hook. It updates the SELinux code to use the > d_instantiate hook rather than inode_post_lookup. It also updates the DTE code > with an initial cut at a d_instantiate hook mostly derived from the existing > dte_real_postlookup function, modified as necessary for differences between the > two hooks. I left the dte_post_lookup function and dte_real_postlookup function > unchanged since they are still called from other functions within the DTE > module. Caveat: The DTE changes were only minimally tested with a trivial > dte.conf, also attached. -- Stephen Smalley, NSA sdsat_private ===== fs/dcache.c 1.28 vs edited ===== --- 1.28/fs/dcache.c Fri Nov 22 08:41:18 2002 +++ edited/fs/dcache.c Thu Jan 2 15:54:09 2003 @@ -25,6 +25,7 @@ #include <linux/module.h> #include <linux/mount.h> #include <asm/uaccess.h> +#include <linux/security.h> #define DCACHE_PARANOIA 1 /* #define DCACHE_DEBUG 1 */ @@ -699,6 +700,7 @@ void d_instantiate(struct dentry *entry, struct inode * inode) { if (!list_empty(&entry->d_alias)) BUG(); + security_d_instantiate(entry, inode); spin_lock(&dcache_lock); if (inode) list_add(&entry->d_alias, &inode->i_dentry); @@ -825,6 +827,7 @@ struct dentry *new = NULL; if (inode && S_ISDIR(inode->i_mode)) { + security_d_instantiate(dentry, inode); spin_lock(&dcache_lock); if (!list_empty(&inode->i_dentry)) { new = list_entry(inode->i_dentry.next, struct dentry, d_alias); ===== fs/namei.c 1.51 vs edited ===== --- 1.51/fs/namei.c Fri Dec 13 13:34:21 2002 +++ edited/fs/namei.c Thu Jan 2 15:53:25 2003 @@ -372,10 +372,8 @@ result = dir->i_op->lookup(dir, dentry); if (result) dput(dentry); - else { + else result = dentry; - security_inode_post_lookup(dir, result); - } } up(&dir->i_sem); return result; @@ -916,10 +914,9 @@ if (!new) goto out; dentry = inode->i_op->lookup(inode, new); - if (!dentry) { + if (!dentry) dentry = new; - security_inode_post_lookup(inode, dentry); - } else + else dput(new); } out: ===== include/linux/security.h 1.22 vs edited ===== --- 1.22/include/linux/security.h Fri Dec 6 07:53:02 2002 +++ edited/include/linux/security.h Fri Jan 3 09:12:38 2003 @@ -347,10 +347,6 @@ * @mnt is the vfsmount where the dentry was looked up * @dentry contains the dentry structure for the file. * Return 0 if permission is granted. - * @inode_post_lookup: - * Set the security attributes for a file after it has been looked up. - * @inode contains the inode structure for parent directory. - * @d contains the dentry structure for the file. * @inode_delete: * @inode contains the inode structure for deleted inode. * This hook is called when a deleted inode is released (i.e. an inode @@ -1239,7 +1235,6 @@ int (*inode_permission_lite) (struct inode *inode, int mask); int (*inode_setattr) (struct dentry *dentry, struct iattr *attr); int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry); - void (*inode_post_lookup) (struct inode *inode, struct dentry *d); void (*inode_delete) (struct inode *inode); int (*inode_setxattr) (struct dentry *dentry, char *name, void *value, size_t size, int flags); @@ -1375,6 +1370,8 @@ struct security_operations *ops); int (*unregister_security) (const char *name, struct security_operations *ops); + + void (*d_instantiate) (struct dentry * dentry, struct inode * inode); }; /* global variables */ @@ -1748,12 +1745,6 @@ return security_ops->inode_getattr (mnt, dentry); } -static inline void security_inode_post_lookup (struct inode *inode, - struct dentry *dentry) -{ - security_ops->inode_post_lookup (inode, dentry); -} - static inline void security_inode_delete (struct inode *inode) { security_ops->inode_delete (inode); @@ -2244,6 +2235,10 @@ return security_ops->sem_semctl(sma, cmd); } +static inline void security_d_instantiate (struct dentry *dentry, struct inode *inode) +{ + security_ops->d_instantiate (dentry, inode); +} /* prototypes */ extern int security_scaffolding_startup (void); @@ -2252,7 +2247,6 @@ extern int mod_reg_security (const char *name, struct security_operations *ops); extern int mod_unreg_security (const char *name, struct security_operations *ops); - #else /* CONFIG_SECURITY */ /* @@ -2602,10 +2596,6 @@ return 0; } -static inline void security_inode_post_lookup (struct inode *inode, - struct dentry *dentry) -{ } - static inline void security_inode_delete (struct inode *inode) { } @@ -3066,6 +3056,9 @@ { return 0; } + +static inline void security_d_instantiate (struct dentry *dentry, struct inode *inode) +{ } #endif /* CONFIG_SECURITY */ ===== security/dummy.c 1.23 vs edited ===== --- 1.23/security/dummy.c Fri Dec 13 14:19:28 2002 +++ edited/security/dummy.c Thu Jan 2 15:51:47 2003 @@ -376,11 +376,6 @@ return 0; } -static void dummy_inode_post_lookup (struct inode *ino, struct dentry *d) -{ - return; -} - static void dummy_inode_delete (struct inode *ino) { return; @@ -873,6 +868,12 @@ return -EINVAL; } +static void dummy_d_instantiate (struct dentry *dentry, struct inode *inode) +{ + return; +} + + struct security_operations dummy_security_ops; #define set_to_dummy_if_null(ops, function) \ @@ -934,7 +935,6 @@ set_to_dummy_if_null(ops, inode_permission_lite); set_to_dummy_if_null(ops, inode_setattr); set_to_dummy_if_null(ops, inode_getattr); - set_to_dummy_if_null(ops, inode_post_lookup); set_to_dummy_if_null(ops, inode_delete); set_to_dummy_if_null(ops, inode_setxattr); set_to_dummy_if_null(ops, inode_getxattr); @@ -1039,5 +1039,6 @@ set_to_dummy_if_null(ops, skb_set_owner_w); set_to_dummy_if_null(ops, skb_recv_datagram); set_to_dummy_if_null(ops, skb_free_security); + set_to_dummy_if_null(ops, d_instantiate); } ===== security/dte/dte.c 1.35 vs edited ===== --- 1.35/security/dte/dte.c Fri Oct 25 13:59:42 2002 +++ edited/security/dte/dte.c Thu Jan 2 15:57:48 2003 @@ -48,7 +48,6 @@ extern int dte_inode_permission_lite(struct inode *inode, int mask); extern int dte_task_alloc_security (struct task_struct *p); extern void dte_task_free_security (struct task_struct *p); -extern void dte_post_lookup (struct inode *ino, struct dentry *d); extern int dte_sb_alloc_security (struct super_block *sb); extern void dte_sb_free_security (struct super_block *sb); extern int dte_mount (char * dev_name, struct nameidata *nd, char * type, @@ -62,6 +61,7 @@ extern void dte_inode_post_mkdir (struct inode *inode, struct dentry *dentry, int mask); extern int dte_task_kill (struct task_struct *p, struct siginfo *info, int sig); +extern void dte_d_instantiate (struct dentry *dentry, struct inode *inode); /* flag to keep track of how we were registered */ /*static int secondary;*/ @@ -923,7 +923,6 @@ acct: dte_acct, sysctl: dte_sysctl, capable: dte_capable, - sys_security: dte_sys_security, swapon: dte_swapon, swapoff: dte_swapoff, quotactl: dte_quotactl, @@ -979,7 +978,6 @@ inode_permission_lite: dte_inode_permission_lite, inode_setattr: dte_inode_setattr, inode_getattr: dte_inode_getattr, - inode_post_lookup: dte_post_lookup, inode_delete: dte_delete, inode_setxattr: dte_inode_setxattr, inode_getxattr: dte_inode_getxattr, @@ -1081,6 +1079,8 @@ register_security: dte_register, unregister_security: dte_unregister, + + d_instantiate: dte_d_instantiate, }; extern int setup_dte_module(void); ===== security/dte/dte.h 1.4 vs edited ===== --- 1.4/security/dte/dte.h Thu Feb 14 18:39:49 2002 +++ edited/security/dte/dte.h Thu Jan 2 15:58:24 2003 @@ -18,6 +18,7 @@ #include <linux/slab.h> #include <linux/smp_lock.h> #include <linux/mount.h> +#include <linux/binfmts.h> /* type access */ #define DTE_READ 1 ===== security/dte/inode.c 1.3 vs edited ===== --- 1.3/security/dte/inode.c Sun Aug 4 23:22:35 2002 +++ edited/security/dte/inode.c Thu Jan 2 15:51:02 2003 @@ -151,6 +151,126 @@ dte_real_postlookup(ino, d, 0); } +void dte_d_instantiate (struct dentry *dentry, struct inode *inode) +{ + struct dentry *parent_dentry; + struct inode *parent_inode; + /* + * p is security field for parent inode + * c is security field for child inode + */ + struct dte_inode_sec *p, *c; + struct dte_sb_sec *sb_sec; /* superblock security field */ + long long offset; + unsigned char buf[2]; + int et, ret; + mm_segment_t old_fs; + +#ifdef CONFIG_DTE_DEBUG + printk(KERN_NOTICE "%s: called on %s.\n", __FUNCTION__, dentry->d_iname); +#endif + + if (!dte_initialized) return; + if (!inode) + return; + if (dentry == dentry->d_parent) + return; + + parent_dentry = dentry->d_parent; + if (!parent_dentry) { + printk(KERN_NOTICE "%s: no parent dentry for dentry %s.\n", + __FUNCTION__, dentry->d_iname); + return; + } + parent_inode = parent_dentry->d_inode; + if (!parent_inode) { + printk(KERN_NOTICE "%s: no inode for parent dentry %s.\n", + __FUNCTION__, parent_dentry->d_iname); + return; + } + p = (struct dte_inode_sec *) parent_inode->i_security; + if (!p || !p->initialized) { + /* Unallocated or uninitialized security object on parent. + This can happen legitimately for pipe or socket inodes, + since DTE does not appear to label them. Ignore for now. */ + return; + } + + c = (struct dte_inode_sec *) inode->i_security; + if (!c) { + printk(KERN_NOTICE "%s: no security object on child inode %s!\n", + __FUNCTION__, dentry->d_iname); + dte_inode_alloc_security(inode); + c = inode->i_security; + } + down(&c->s_sem); + if (c->initialized) { + up(&c->s_sem); + return; + } + + /* assign types using the hierarchical scheme */ + +#ifdef CONFIG_DTE_DEBUG + printk(KERN_NOTICE "%s: looking up %s.\n", __FUNCTION__, dentry->d_iname); +#endif + + c->map = NULL; + c->utype = c->etype = p->utype; + c->initialized = 1; + + if (p->map && p->map->num_kids) { + c->map = mapnode_getkid(p->map, dentry->d_name.name); + if (c->map) { + if (c->map->etype) + c->etype = c->map->etype; + if (c->map->utype) + c->utype = c->map->utype; + } + } + + sb_sec = (struct dte_sb_sec *)inode->i_sb->s_security; + if (!sb_sec || !sb_sec->fp_ready) { + up(&c->s_sem); + return; + } + + /* + * Read types from ea file + * We leave the mapnodes as are, but, if a valid type is found, we use + * that for both etype and utype + * + * An alternative would be to use it only for etype. Not sure which is + * best. + */ + c->map = NULL; + if (sb_sec->ntypes<128) { + offset = sb_sec->offset+inode->i_ino; + old_fs = get_fs(); + set_fs(KERNEL_DS); + ret = sb_sec->fp->f_op->read(sb_sec->fp, buf, 1, &offset); + set_fs(old_fs); + if (ret<0) + printk(KERN_NOTICE "%s: read(1) returned %d.\n", __FUNCTION__, ret); + et = (int)(*((unsigned char *)buf)); + } else { + offset = sb_sec->offset+2*inode->i_ino; + old_fs = get_fs(); + set_fs(KERNEL_DS); + ret = sb_sec->fp->f_op->read(sb_sec->fp, buf, 2, &offset); + set_fs(old_fs); + if (ret<0) + printk(KERN_NOTICE "%s: read(2) returned %d.\n", __FUNCTION__, ret); + et = (int)(*((unsigned short *)buf)); + } + + if (et!=sb_sec->ntypes) { + c->utype = c->etype = sb_sec->type_conv[et]; + c->initialized = 1; + } + up(&c->s_sem); +} + int dte_inode_alloc_security (struct inode *inode) { struct dte_inode_sec *s; ===== security/dte/module.c 1.3 vs edited ===== --- 1.3/security/dte/module.c Tue Sep 17 14:35:19 2002 +++ edited/security/dte/module.c Thu Jan 2 15:51:03 2003 @@ -170,6 +170,7 @@ root_ino_sec->map = dte_root_mapnode; root_ino_sec->etype = dte_root_mapnode->etype; root_ino_sec->utype = dte_root_mapnode->utype; + root_ino_sec->initialized = 1; dte_initialized = 1; dte_walk_dcache_tree_full(root_mnt, root_sb->s_root); ===== security/dte/mount.c 1.8 vs edited ===== --- 1.8/security/dte/mount.c Tue Sep 17 14:35:54 2002 +++ edited/security/dte/mount.c Thu Jan 2 15:51:03 2003 @@ -337,6 +337,7 @@ s->map = dte_root_mapnode; s->etype = dte_root_mapnode->etype; s->utype = dte_root_mapnode->utype; + s->initialized = 1; if (dte_c_maptohash(dte_root_mapnode)!=1) { printk(KERN_EMERG "Uh-oh : Trouble hashing mapnodes.\n"); ===== security/lids/lids_lsm.c 1.35 vs edited ===== --- 1.35/security/lids/lids_lsm.c Tue Dec 3 19:02:40 2002 +++ edited/security/lids/lids_lsm.c Thu Jan 2 15:52:20 2003 @@ -455,11 +455,6 @@ return 0; } -static void lids_post_lookup (struct inode *ino, struct dentry *d) -{ - return; -} - static void lids_delete (struct inode *ino) { return; @@ -774,7 +769,6 @@ .inode_permission_lite = lids_inode_permission_lite, .inode_setattr = lids_inode_setattr, .inode_getattr = lids_inode_getattr, - .inode_post_lookup = lids_post_lookup, .inode_delete = lids_delete, .inode_setxattr = lids_inode_setxattr, .inode_getxattr = lids_inode_getxattr, ===== security/selinux/hooks.c 1.71 vs edited ===== --- 1.71/security/selinux/hooks.c Wed Dec 4 10:11:35 2002 +++ edited/security/selinux/hooks.c Thu Jan 2 15:52:02 2003 @@ -461,7 +461,12 @@ "not configured for labeling" }; -static int inode_doinit(struct inode *inode); +static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry); + +static inline int inode_doinit(struct inode *inode) +{ + return inode_doinit_with_dentry(inode, NULL); +} static int superblock_doinit(struct super_block *sb) { @@ -551,7 +556,7 @@ labeling_behaviors[behavior-1]); /* Initialize the root inode. */ - rc = inode_doinit(sb->s_root->d_inode); + rc = inode_doinit_with_dentry(sb->s_root->d_inode, sb->s_root); if (rc) return rc; @@ -563,7 +568,7 @@ * The /proc/PID entries are labeled with the SID of the owning process. * Most entries simply inherit their SID from the parent directory SID. */ -static void procfs_set_sid(struct dentry *dentry) +static void procfs_set_sid(struct inode *inode, struct dentry *dentry) { struct task_security_struct *tsec; struct inode_security_struct *isec, *pisec; @@ -573,10 +578,7 @@ const char *name; int len; - if (!dentry->d_inode) - return; - - isec = dentry->d_inode->i_security; + isec = inode->i_security; #ifndef _SELINUX_KERNEL_PATCH_ if (!isec) return; @@ -644,7 +646,7 @@ char *buffer, int buflen); /* The inode's security attributes must be initialized before first use. */ -static int inode_doinit(struct inode *inode) +static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry) { struct superblock_security_struct *sbsec = NULL; struct inode_security_struct *isec = inode->i_security; @@ -719,7 +721,10 @@ isec->sid = sbsec->sid; /* Obtain a SID based on the fstype, path, and class. */ - dentry = d_find_alias(inode); + if (opt_dentry) + dentry = dget(opt_dentry); + else + dentry = d_find_alias(inode); if (dentry) { buffer = (char*)__get_free_page(GFP_KERNEL); if (buffer) { @@ -750,7 +755,7 @@ if (sbsec->proc) { /* Handle /proc/PID. */ - procfs_set_sid(dentry); + procfs_set_sid(inode, dentry); } dput(dentry); @@ -2071,15 +2076,6 @@ return inode_has_perm(current, inode, FILE__GETATTR, NULL, NULL); } -static void selinux_inode_post_lookup(struct inode *dir, struct dentry *dentry) -{ - struct inode *inode = dentry->d_inode; - - if (inode) - inode_doinit(inode); - return; -} - static void selinux_inode_delete(struct inode *inode) { struct super_block *sb = inode->i_sb; @@ -3993,6 +3989,12 @@ return 0; } +static void selinux_d_instantiate (struct dentry *dentry, struct inode *inode) +{ + if (inode) + inode_doinit_with_dentry(inode, dentry); +} + struct security_operations selinux_ops = { sethostname: selinux_sethostname, setdomainname: selinux_setdomainname, @@ -4061,7 +4063,6 @@ inode_permission_lite: selinux_inode_permission_lite, inode_setattr: selinux_inode_setattr, inode_getattr: selinux_inode_getattr, - inode_post_lookup: selinux_inode_post_lookup, inode_delete: selinux_inode_delete, inode_setxattr: selinux_inode_setxattr, inode_getxattr: selinux_inode_getxattr, @@ -4163,6 +4164,8 @@ register_security: &selinux_register_security, unregister_security: &selinux_unregister_security, + + d_instantiate: selinux_d_instantiate, }; extern long sys_security_selinux(struct pt_regs regs); _______________________________________________ linux-security-module mailing list linux-security-moduleat_private http://mail.wirex.com/mailman/listinfo/linux-security-module
This archive was generated by hypermail 2b30 : Fri Jan 03 2003 - 09:11:17 PST