--- linux-2.6.18.2/fs/devpts/inode.c 2006-09-20 16:58:34 +0200 +++ linux-2.6.18.2-vs2.1.1/fs/devpts/inode.c 2006-09-25 15:40:02 +0200 @@ -20,7 +20,20 @@ #include #include -#define DEVPTS_SUPER_MAGIC 0x1cd1 + +static int devpts_permission(struct inode *inode, int mask, struct nameidata *nd) +{ + int ret = -EACCES; + + /* devpts is xid tagged */ + if (vx_check((xid_t)inode->i_tag, VX_WATCH_P|VX_IDENT)) + ret = generic_permission(inode, mask, NULL); + return ret; +} + +static struct inode_operations devpts_file_inode_operations = { + .permission = devpts_permission, +}; static struct vfsmount *devpts_mnt; static struct dentry *devpts_root; --- linux-2.6.18.2/fs/devpts/inode.c 2006-09-20 16:58:34 +0200 +++ linux-2.6.18.2-vs2.1.1/fs/devpts/inode.c 2006-09-25 15:40:02 +0200 @@ -91,6 +104,25 @@ static int devpts_remount(struct super_b return 0; } +static int devpts_filter(struct dentry *de) +{ + /* devpts is xid tagged */ + return vx_check((xid_t)de->d_inode->i_tag, VX_WATCH_P|VX_IDENT); +} + +static int devpts_readdir(struct file * filp, void * dirent, filldir_t filldir) +{ + return dcache_readdir_filter(filp, dirent, filldir, devpts_filter); +} + +static struct file_operations devpts_dir_operations = { + .open = dcache_dir_open, + .release = dcache_dir_close, + .llseek = dcache_dir_lseek, + .read = generic_read_dir, + .readdir = devpts_readdir, +}; + static struct super_operations devpts_sops = { .statfs = simple_statfs, .remount_fs = devpts_remount, --- linux-2.6.18.2/fs/devpts/inode.c 2006-09-20 16:58:34 +0200 +++ linux-2.6.18.2-vs2.1.1/fs/devpts/inode.c 2006-09-25 15:40:02 +0200 @@ -117,8 +149,10 @@ devpts_fill_super(struct super_block *s, inode->i_uid = inode->i_gid = 0; inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR; inode->i_op = &simple_dir_inode_operations; - inode->i_fop = &simple_dir_operations; + inode->i_fop = &devpts_dir_operations; inode->i_nlink = 2; + /* devpts is xid tagged */ + inode->i_tag = (tag_t)vx_current_xid(); devpts_root = s->s_root = d_alloc_root(inode); if (s->s_root) --- linux-2.6.18.2/fs/devpts/inode.c 2006-09-20 16:58:34 +0200 +++ linux-2.6.18.2-vs2.1.1/fs/devpts/inode.c 2006-09-25 15:40:02 +0200 @@ -177,6 +211,9 @@ int devpts_pty_new(struct tty_struct *tt inode->i_gid = config.setgid ? config.gid : current->fsgid; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; init_special_inode(inode, S_IFCHR|config.mode, device); + /* devpts is xid tagged */ + inode->i_tag = (tag_t)vx_current_xid(); + inode->i_op = &devpts_file_inode_operations; inode->u.generic_ip = tty; dentry = get_node(number); --- linux-2.6.18.2/fs/libfs.c 2006-09-20 16:58:35 +0200 +++ linux-2.6.18.2-vs2.1.1/fs/libfs.c 2006-09-20 17:01:44 +0200 @@ -124,7 +124,8 @@ static inline unsigned char dt_type(stru * both impossible due to the lock on directory. */ -int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir) +static inline int do_dcache_readdir_filter(struct file * filp, + void * dirent, filldir_t filldir, int (*filter)(struct dentry *dentry)) { struct dentry *dentry = filp->f_dentry; struct dentry *cursor = filp->private_data; --- linux-2.6.18.2/fs/libfs.c 2006-09-20 16:58:35 +0200 +++ linux-2.6.18.2-vs2.1.1/fs/libfs.c 2006-09-20 17:01:44 +0200 @@ -157,6 +158,8 @@ int dcache_readdir(struct file * filp, v next = list_entry(p, struct dentry, d_u.d_child); if (d_unhashed(next) || !next->d_inode) continue; + if (filter && !filter(next)) + continue; spin_unlock(&dcache_lock); if (filldir(dirent, next->d_name.name, next->d_name.len, filp->f_pos, next->d_inode->i_ino, dt_type(next->d_inode)) < 0) --- linux-2.6.18.2/fs/libfs.c 2006-09-20 16:58:35 +0200 +++ linux-2.6.18.2-vs2.1.1/fs/libfs.c 2006-09-20 17:01:44 +0200 @@ -172,6 +175,18 @@ int dcache_readdir(struct file * filp, v return 0; } +int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir) +{ + return do_dcache_readdir_filter(filp, dirent, filldir, NULL); +} + +int dcache_readdir_filter(struct file * filp, void * dirent, filldir_t filldir, + int (*filter)(struct dentry *)) +{ + return do_dcache_readdir_filter(filp, dirent, filldir, filter); +} + + ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos) { return -EISDIR; --- linux-2.6.18.2/fs/libfs.c 2006-09-20 16:58:35 +0200 +++ linux-2.6.18.2-vs2.1.1/fs/libfs.c 2006-09-20 17:01:44 +0200 @@ -621,6 +636,7 @@ EXPORT_SYMBOL(dcache_dir_close); EXPORT_SYMBOL(dcache_dir_lseek); EXPORT_SYMBOL(dcache_dir_open); EXPORT_SYMBOL(dcache_readdir); +EXPORT_SYMBOL(dcache_readdir_filter); EXPORT_SYMBOL(generic_read_dir); EXPORT_SYMBOL(get_sb_pseudo); EXPORT_SYMBOL(simple_commit_write); --- linux-2.6.18.2/include/linux/fs.h 2006-09-20 16:58:43 +0200 +++ linux-2.6.18.2-vs2.1.1/include/linux/fs.h 2006-11-01 01:01:33 +0100 @@ -1790,6 +1820,7 @@ extern int dcache_dir_open(struct inode extern int dcache_dir_close(struct inode *, struct file *); extern loff_t dcache_dir_lseek(struct file *, loff_t, int); extern int dcache_readdir(struct file *, void *, filldir_t); +extern int dcache_readdir_filter(struct file *, void *, filldir_t, int (*)(struct dentry *)); extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *); extern int simple_statfs(struct dentry *, struct kstatfs *); extern int simple_link(struct dentry *, struct inode *, struct dentry *);