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. Any objections to this patch? -- Stephen Smalley, NSA sdsat_private diff -X /home/sds/dontdiff -ru lsm-2.4/fs/dcache.c lsm-2.4-bk/fs/dcache.c --- lsm-2.4/fs/dcache.c Tue Dec 31 11:08:05 2002 +++ lsm-2.4-bk/fs/dcache.c Thu Jan 2 14:17:19 2003 @@ -25,6 +25,7 @@ #include <linux/module.h> #include <asm/uaccess.h> +#include <linux/security.h> #define DCACHE_PARANOIA 1 /* #define DCACHE_DEBUG 1 */ @@ -651,6 +652,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); diff -X /home/sds/dontdiff -ru lsm-2.4/fs/namei.c lsm-2.4-bk/fs/namei.c --- lsm-2.4/fs/namei.c Thu Jan 2 08:52:21 2003 +++ lsm-2.4-bk/fs/namei.c Thu Jan 2 14:17:19 2003 @@ -314,10 +314,8 @@ unlock_kernel(); if (result) dput(dentry); - else { + else result = dentry; - security_inode_post_lookup(dir, result); - } } up(&dir->i_sem); return result; @@ -814,10 +812,9 @@ lock_kernel(); dentry = inode->i_op->lookup(inode, new); unlock_kernel(); - if (!dentry) { + if (!dentry) dentry = new; - security_inode_post_lookup(inode, dentry); - } else + else dput(new); } out: diff -X /home/sds/dontdiff -ru lsm-2.4/include/linux/security.h lsm-2.4-bk/include/linux/security.h --- lsm-2.4/include/linux/security.h Thu Jan 2 08:52:21 2003 +++ lsm-2.4-bk/include/linux/security.h Thu Jan 2 14:17:19 2003 @@ -342,10 +342,6 @@ * Check permission before obtaining file attributes. * @inode contains the inode 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 @@ -1305,7 +1301,6 @@ int (*inode_revalidate) (struct dentry *dentry); int (*inode_setattr) (struct dentry *dentry, struct iattr *attr); int (*inode_stat) (struct inode *inode); - 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); @@ -1443,6 +1438,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 */ @@ -1845,12 +1842,6 @@ return security_ops->inode_stat (inode); } -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); @@ -2355,6 +2346,10 @@ extern int mod_reg_security (const char *name, struct security_operations *ops); extern int mod_unreg_security (const char *name, struct security_operations *ops); +static inline void security_d_instantiate (struct dentry *dentry, struct inode *inode) +{ + security_ops->d_instantiate (dentry, inode); +} #else /* CONFIG_SECURITY */ @@ -2734,10 +2729,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) { } @@ -3206,6 +3197,9 @@ return 0; } +static inline void security_d_instantiate (struct dentry *dentry, struct inode *inode) +{ } + #endif /* CONFIG_SECURITY */ #endif /* ! __LINUX_SECURITY_H */ diff -X /home/sds/dontdiff -ru lsm-2.4/security/dte/dte.c lsm-2.4-bk/security/dte/dte.c --- lsm-2.4/security/dte/dte.c Thu Jan 2 08:52:21 2003 +++ lsm-2.4-bk/security/dte/dte.c Thu Jan 2 14:17:19 2003 @@ -47,7 +47,6 @@ extern int dte_inode_permission (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, @@ -61,6 +60,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;*/ @@ -894,7 +894,6 @@ inode_revalidate: dte_inode_revalidate, inode_setattr: dte_inode_setattr, inode_stat: dte_inode_stat, - inode_post_lookup: dte_post_lookup, inode_delete: dte_delete, file_permission: dte_file_permission, @@ -973,6 +972,8 @@ register_security: dte_register, unregister_security: dte_unregister, + + d_instantiate: dte_d_instantiate, }; extern int setup_dte_module(void); diff -X /home/sds/dontdiff -ru lsm-2.4/security/dte/inode.c lsm-2.4-bk/security/dte/inode.c --- lsm-2.4/security/dte/inode.c Thu Jan 3 15:38:27 2002 +++ lsm-2.4-bk/security/dte/inode.c Thu Jan 2 14:56:02 2003 @@ -153,6 +153,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; diff -X /home/sds/dontdiff -ru lsm-2.4/security/dte/module.c lsm-2.4-bk/security/dte/module.c --- lsm-2.4/security/dte/module.c Thu Feb 21 08:20:08 2002 +++ lsm-2.4-bk/security/dte/module.c Thu Jan 2 14:17:19 2003 @@ -168,6 +168,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); diff -X /home/sds/dontdiff -ru lsm-2.4/security/dte/mount.c lsm-2.4-bk/security/dte/mount.c --- lsm-2.4/security/dte/mount.c Thu Feb 21 08:20:09 2002 +++ lsm-2.4-bk/security/dte/mount.c Thu Jan 2 14:17:19 2003 @@ -312,6 +312,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"); diff -X /home/sds/dontdiff -ru lsm-2.4/security/dummy.c lsm-2.4-bk/security/dummy.c --- lsm-2.4/security/dummy.c Thu Jan 2 08:52:21 2003 +++ lsm-2.4-bk/security/dummy.c Thu Jan 2 14:17:19 2003 @@ -407,11 +407,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; @@ -910,6 +905,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) \ @@ -977,7 +978,6 @@ set_to_dummy_if_null(ops, inode_revalidate); set_to_dummy_if_null(ops, inode_setattr); set_to_dummy_if_null(ops, inode_stat); - 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); @@ -1083,5 +1083,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); } diff -X /home/sds/dontdiff -ru lsm-2.4/security/lids/lids_lsm.c lsm-2.4-bk/security/lids/lids_lsm.c --- lsm-2.4/security/lids/lids_lsm.c Thu Jan 2 08:52:21 2003 +++ lsm-2.4-bk/security/lids/lids_lsm.c Thu Jan 2 14:17:19 2003 @@ -512,11 +512,6 @@ return 0; } -static void lids_post_lookup (struct inode *ino, struct dentry *d) -{ - return; -} - static void lids_delete (struct inode *ino) { return; @@ -1066,7 +1061,6 @@ inode_revalidate: lids_inode_revalidate, inode_setattr: lids_inode_setattr, inode_stat: lids_inode_stat, - inode_post_lookup: lids_post_lookup, inode_delete: lids_delete, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2) inode_setxattr: lids_inode_setxattr, diff -X /home/sds/dontdiff -ru lsm-2.4/security/owlsm.c lsm-2.4-bk/security/owlsm.c --- lsm-2.4/security/owlsm.c Thu Jan 2 08:52:21 2003 +++ lsm-2.4-bk/security/owlsm.c Thu Jan 2 14:17:19 2003 @@ -394,11 +394,6 @@ return 0; } -static void owlsm_post_lookup (struct inode *ino, struct dentry *d) -{ - return; -} - static void owlsm_delete (struct inode *ino) { return; @@ -862,7 +857,6 @@ inode_revalidate: owlsm_inode_revalidate, inode_setattr: owlsm_inode_setattr, inode_stat: owlsm_inode_stat, - inode_post_lookup: owlsm_post_lookup, inode_delete: owlsm_delete, file_permission: owlsm_file_permission, diff -X /home/sds/dontdiff -ru lsm-2.4/security/selinux/hooks.c lsm-2.4-bk/security/selinux/hooks.c --- lsm-2.4/security/selinux/hooks.c Thu Jan 2 09:07:32 2003 +++ lsm-2.4-bk/security/selinux/hooks.c Thu Jan 2 14:17:19 2003 @@ -458,7 +458,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) { @@ -548,7 +553,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; @@ -560,7 +565,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; @@ -570,10 +575,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; @@ -641,7 +643,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; @@ -716,7 +718,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) { @@ -747,7 +752,7 @@ if (sbsec->proc) { /* Handle /proc/PID. */ - procfs_set_sid(dentry); + procfs_set_sid(inode, dentry); } dput(dentry); @@ -2064,15 +2069,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; @@ -3992,6 +3988,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, @@ -4063,7 +4065,6 @@ inode_revalidate: selinux_inode_revalidate, inode_setattr: selinux_inode_setattr, inode_stat: selinux_inode_stat, - inode_post_lookup: selinux_inode_post_lookup, inode_delete: selinux_inode_delete, file_permission: selinux_file_permission, @@ -4166,6 +4167,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); types root_t other_t etc_t domains init_d default_d init_d default_et root_t default_ut other_t spec_domain init_d (0) (3 rwxalcd->root_t rwxalcd->other_t rwxalcd->etc_t) (0) (1 0->0) assign -r etc_t /etc _______________________________________________ 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 : Thu Jan 02 2003 - 18:48:16 PST