--- linux-2.6.12.2/include/linux/ipc.h 2004-08-14 12:54:46 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/ipc.h 2005-07-02 22:38:30 +0200 @@ -66,6 +66,7 @@ struct kern_ipc_perm mode_t mode; unsigned long seq; void *security; + xid_t xid; }; #endif /* __KERNEL__ */ --- linux-2.6.12.2/include/linux/sched.h 2005-06-22 02:38:49 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/sched.h 2005-07-02 22:38:30 +0200 @@ -416,9 +420,10 @@ struct user_struct { /* Hash table maintenance information */ struct list_head uidhash_list; uid_t uid; + xid_t xid; }; -extern struct user_struct *find_user(uid_t); +extern struct user_struct *find_user(xid_t, uid_t); extern struct user_struct root_user; #define INIT_USER (&root_user) --- linux-2.6.12.2/ipc/msg.c 2005-06-22 02:38:52 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/ipc/msg.c 2005-07-02 22:38:30 +0200 @@ -98,6 +98,7 @@ static int newque (key_t key, int msgflg msq->q_perm.mode = (msgflg & S_IRWXUGO); msq->q_perm.key = key; + msq->q_perm.xid = vx_current_xid(); msq->q_perm.security = NULL; retval = security_msg_queue_alloc(msq); --- linux-2.6.12.2/ipc/msg.c 2005-06-22 02:38:52 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/ipc/msg.c 2005-07-02 22:38:30 +0200 @@ -820,7 +821,11 @@ static int sysvipc_msg_read_proc(char *b for(i = 0; i <= msg_ids.max_id; i++) { struct msg_queue * msq; msq = msg_lock(i); - if(msq != NULL) { + if (msq) { + if (!vx_check(msq->q_perm.xid, VX_IDENT)) { + msg_unlock(msq); + continue; + } len += sprintf(buffer + len, "%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n", msq->q_perm.key, msg_buildid(i,msq->q_perm.seq), --- linux-2.6.12.2/ipc/sem.c 2005-06-22 02:38:52 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/ipc/sem.c 2005-07-02 22:38:30 +0200 @@ -177,6 +177,7 @@ static int newary (key_t key, int nsems, sma->sem_perm.mode = (semflg & S_IRWXUGO); sma->sem_perm.key = key; + sma->sem_perm.xid = vx_current_xid(); sma->sem_perm.security = NULL; retval = security_sem_alloc(sma); --- linux-2.6.12.2/ipc/sem.c 2005-06-22 02:38:52 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/ipc/sem.c 2005-07-02 22:38:30 +0200 @@ -1347,7 +1348,11 @@ static int sysvipc_sem_read_proc(char *b for(i = 0; i <= sem_ids.max_id; i++) { struct sem_array *sma; sma = sem_lock(i); - if(sma) { + if (sma) { + if (!vx_check(sma->sem_perm.xid, VX_IDENT)) { + sem_unlock(sma); + continue; + } len += sprintf(buffer + len, "%10d %10d %4o %10lu %5u %5u %5u %5u %10lu %10lu\n", sma->sem_perm.key, sem_buildid(i,sma->sem_perm.seq), --- linux-2.6.12.2/ipc/shm.c 2005-06-22 02:38:52 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/ipc/shm.c 2005-07-02 22:38:30 +0200 @@ -882,11 +893,15 @@ static int sysvipc_shm_read_proc(char *b struct shmid_kernel* shp; shp = shm_lock(i); - if(shp!=NULL) { + if (shp) { #define SMALL_STRING "%10d %10d %4o %10u %5u %5u %5d %5u %5u %5u %5u %10lu %10lu %10lu\n" #define BIG_STRING "%10d %10d %4o %21u %5u %5u %5d %5u %5u %5u %5u %10lu %10lu %10lu\n" char *format; + if (!vx_check(shp->shm_perm.xid, VX_IDENT)) { + shm_unlock(shp); + continue; + } if (sizeof(size_t) <= sizeof(int)) format = SMALL_STRING; else --- linux-2.6.12.2/ipc/util.c 2004-12-25 01:55:30 +0100 +++ linux-2.6.12.2-vs2.0-rc6.1/ipc/util.c 2005-07-02 22:38:30 +0200 @@ -107,7 +107,9 @@ int ipc_findkey(struct ipc_ids* ids, key */ for (id = 0; id <= max_id; id++) { p = ids->entries->p[id]; - if(p==NULL) + if (p==NULL) + continue; + if (!vx_check(p->xid, VX_IDENT)) continue; if (key == p->key) return id; --- linux-2.6.12.2/ipc/util.c 2004-12-25 01:55:30 +0100 +++ linux-2.6.12.2-vs2.0-rc6.1/ipc/util.c 2005-07-02 22:38:30 +0200 @@ -420,6 +422,8 @@ int ipcperms (struct kern_ipc_perm *ipcp { /* flag will most probably be 0 or S_...UGO from */ int requested_mode, granted_mode; + if (!vx_check(ipcp->xid, VX_ADMIN|VX_IDENT)) /* maybe just VX_IDENT? */ + return -1; requested_mode = (flag >> 6) | (flag >> 3) | flag; granted_mode = ipcp->mode; if (current->euid == ipcp->cuid || current->euid == ipcp->uid) --- linux-2.6.12.2/kernel/printk.c 2005-06-22 02:38:53 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/kernel/printk.c 2005-07-02 22:38:30 +0200 @@ -222,18 +223,13 @@ int do_syslog(int type, char __user * bu unsigned long i, j, limit, count; int do_clear = 0; char c; - int error = 0; + int error; error = security_syslog(type); if (error) return error; - switch (type) { - case 0: /* Close log */ - break; - case 1: /* Open log */ - break; - case 2: /* Read from log */ + if ((type >= 2) && (type <= 4)) { error = -EINVAL; if (!buf || len < 0) goto out; --- linux-2.6.12.2/kernel/printk.c 2005-06-22 02:38:53 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/kernel/printk.c 2005-07-02 22:38:30 +0200 @@ -244,6 +240,16 @@ int do_syslog(int type, char __user * bu error = -EFAULT; goto out; } + } + if (!vx_check(0, VX_ADMIN|VX_WATCH)) + return vx_do_syslog(type, buf, len); + + switch (type) { + case 0: /* Close log */ + break; + case 1: /* Open log */ + break; + case 2: /* Read from log */ error = wait_event_interruptible(log_wait, (log_start - log_end)); if (error) goto out; --- linux-2.6.12.2/kernel/printk.c 2005-06-22 02:38:53 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/kernel/printk.c 2005-07-02 22:38:30 +0200 @@ -267,16 +273,6 @@ int do_syslog(int type, char __user * bu do_clear = 1; /* FALL THRU */ case 3: /* Read last kernel messages */ - error = -EINVAL; - if (!buf || len < 0) - goto out; - error = 0; - if (!len) - goto out; - if (!access_ok(VERIFY_WRITE, buf, len)) { - error = -EFAULT; - goto out; - } count = len; if (count > log_buf_len) count = log_buf_len; --- linux-2.6.12.2/kernel/sys.c 2005-06-22 02:38:53 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/kernel/sys.c 2005-07-02 22:38:30 +0200 @@ -281,7 +286,8 @@ asmlinkage long sys_setpriority(int whic if (!who) who = current->uid; else - if ((who != current->uid) && !(user = find_user(who))) + if ((who != current->uid) && + !(user = find_user(vx_current_xid(), who))) goto out_unlock; /* No processes for this user */ do_each_thread(g, p) --- linux-2.6.12.2/kernel/sys.c 2005-06-22 02:38:53 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/kernel/sys.c 2005-07-02 22:38:30 +0200 @@ -339,7 +345,8 @@ asmlinkage long sys_getpriority(int whic if (!who) who = current->uid; else - if ((who != current->uid) && !(user = find_user(who))) + if ((who != current->uid) && + !(user = find_user(vx_current_xid(), who))) goto out_unlock; /* No processes for this user */ do_each_thread(g, p) --- linux-2.6.12.2/kernel/sys.c 2005-06-22 02:38:53 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/kernel/sys.c 2005-07-02 22:38:30 +0200 @@ -581,7 +592,7 @@ static int set_user(uid_t new_ruid, int { struct user_struct *new_user; - new_user = alloc_uid(new_ruid); + new_user = alloc_uid(vx_current_xid(), new_ruid); if (!new_user) return -EAGAIN; --- linux-2.6.12.2/kernel/user.c 2005-06-22 02:38:53 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/kernel/user.c 2005-07-02 22:38:30 +0200 @@ -22,8 +22,8 @@ #define UIDHASH_BITS (CONFIG_BASE_SMALL ? 3 : 8) #define UIDHASH_SZ (1 << UIDHASH_BITS) #define UIDHASH_MASK (UIDHASH_SZ - 1) -#define __uidhashfn(uid) (((uid >> UIDHASH_BITS) + uid) & UIDHASH_MASK) -#define uidhashentry(uid) (uidhash_table + __uidhashfn((uid))) +#define __uidhashfn(xid,uid) ((((uid) >> UIDHASH_BITS) + ((uid)^(xid))) & UIDHASH_MASK) +#define uidhashentry(xid,uid) (uidhash_table + __uidhashfn((xid),(uid))) static kmem_cache_t *uid_cachep; static struct list_head uidhash_table[UIDHASH_SZ]; --- linux-2.6.12.2/kernel/user.c 2005-06-22 02:38:53 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/kernel/user.c 2005-07-02 22:38:30 +0200 @@ -55,7 +55,7 @@ static inline void uid_hash_remove(struc list_del(&up->uidhash_list); } -static inline struct user_struct *uid_hash_find(uid_t uid, struct list_head *hashent) +static inline struct user_struct *uid_hash_find(xid_t xid, uid_t uid, struct list_head *hashent) { struct list_head *up; --- linux-2.6.12.2/kernel/user.c 2005-06-22 02:38:53 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/kernel/user.c 2005-07-02 22:38:30 +0200 @@ -64,7 +64,7 @@ static inline struct user_struct *uid_ha user = list_entry(up, struct user_struct, uidhash_list); - if(user->uid == uid) { + if(user->uid == uid && user->xid == xid) { atomic_inc(&user->__count); return user; } --- linux-2.6.12.2/kernel/user.c 2005-06-22 02:38:53 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/kernel/user.c 2005-07-02 22:38:30 +0200 @@ -79,12 +79,12 @@ static inline struct user_struct *uid_ha * * If the user_struct could not be found, return NULL. */ -struct user_struct *find_user(uid_t uid) +struct user_struct *find_user(xid_t xid, uid_t uid) { struct user_struct *ret; spin_lock(&uidhash_lock); - ret = uid_hash_find(uid, uidhashentry(uid)); + ret = uid_hash_find(xid, uid, uidhashentry(xid, uid)); spin_unlock(&uidhash_lock); return ret; } --- linux-2.6.12.2/kernel/user.c 2005-06-22 02:38:53 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/kernel/user.c 2005-07-02 22:38:30 +0200 @@ -100,13 +100,13 @@ void free_uid(struct user_struct *up) } } -struct user_struct * alloc_uid(uid_t uid) +struct user_struct * alloc_uid(xid_t xid, uid_t uid) { - struct list_head *hashent = uidhashentry(uid); + struct list_head *hashent = uidhashentry(xid, uid); struct user_struct *up; spin_lock(&uidhash_lock); - up = uid_hash_find(uid, hashent); + up = uid_hash_find(xid, uid, hashent); spin_unlock(&uidhash_lock); if (!up) { --- linux-2.6.12.2/kernel/user.c 2005-06-22 02:38:53 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/kernel/user.c 2005-07-02 22:38:30 +0200 @@ -116,6 +116,7 @@ struct user_struct * alloc_uid(uid_t uid if (!new) return NULL; new->uid = uid; + new->xid = xid; atomic_set(&new->__count, 1); atomic_set(&new->processes, 0); atomic_set(&new->files, 0); --- linux-2.6.12.2/kernel/user.c 2005-06-22 02:38:53 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/kernel/user.c 2005-07-02 22:38:30 +0200 @@ -134,7 +135,7 @@ struct user_struct * alloc_uid(uid_t uid * on adding the same user already.. */ spin_lock(&uidhash_lock); - up = uid_hash_find(uid, hashent); + up = uid_hash_find(xid, uid, hashent); if (up) { key_put(new->uid_keyring); key_put(new->session_keyring); --- linux-2.6.12.2/kernel/user.c 2005-06-22 02:38:53 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/kernel/user.c 2005-07-02 22:38:30 +0200 @@ -180,7 +181,7 @@ static int __init uid_cache_init(void) /* Insert the root user immediately (init already runs as root) */ spin_lock(&uidhash_lock); - uid_hash_insert(&root_user, uidhashentry(0)); + uid_hash_insert(&root_user, uidhashentry(0,0)); spin_unlock(&uidhash_lock); return 0; --- linux-2.6.12.2/fs/libfs.c 2005-03-02 12:38:44 +0100 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/libfs.c 2005-07-09 03:54:30 +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.12.2/fs/devpts/inode.c 2005-03-02 12:38:44 +0100 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/devpts/inode.c 2005-07-09 03:54:30 +0200 @@ -115,8 +141,9 @@ 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; + inode->i_xid = vx_current_xid(); devpts_root = s->s_root = d_alloc_root(inode); if (s->s_root) --- linux-2.6.12.2/fs/devpts/inode.c 2005-03-02 12:38:44 +0100 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/devpts/inode.c 2005-07-09 03:54:30 +0200 @@ -175,6 +202,7 @@ 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); + inode->i_xid = vx_current_xid(); inode->i_op = &devpts_file_inode_operations; inode->u.generic_ip = tty; --- linux-2.6.12.2/include/linux/fs.h 2005-06-22 02:38:48 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/include/linux/fs.h 2005-07-09 03:54:30 +0200 @@ -1580,6 +1595,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 super_block *, struct kstatfs *); extern int simple_link(struct dentry *, struct inode *, struct dentry *); --- linux-2.6.12.2/fs/namei.c 2005-06-22 02:38:37 +0200 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/namei.c 2005-07-09 04:35:26 +0200 @@ -674,16 +699,34 @@ static int do_lookup(struct nameidata *n { struct vfsmount *mnt = nd->mnt; struct dentry *dentry = __d_lookup(nd->dentry, name); + struct inode *inode; if (!dentry) goto need_lookup; if (dentry->d_op && dentry->d_op->d_revalidate) goto need_revalidate; + inode = dentry->d_inode; + if (!inode) + goto done; + if (!vx_check(inode->i_xid, VX_WATCH|VX_ADMIN|VX_HOSTID|VX_IDENT)) + goto hidden; + if (inode->i_sb->s_magic == PROC_SUPER_MAGIC) { + struct proc_dir_entry *de = PDE(inode); + + if (de && !vx_hide_check(0, de->vx_flags)) + goto hidden; + } done: path->mnt = mnt; path->dentry = dentry; __follow_mount(path); return 0; +hidden: + vxwprintk(1, "xid=%d did lookup hidden %p[#%d,%lu] »%s«.", + vx_current_xid(), inode, inode->i_xid, inode->i_ino, + vxd_path(dentry, mnt)); + dput(dentry); + return -ENOENT; need_lookup: dentry = real_lookup(nd->dentry, name, nd); --- linux-2.6.12.2/fs/libfs.c 2005-03-02 12:38:44 +0100 +++ linux-2.6.12.2-vs2.0-rc6.1/fs/libfs.c 2005-07-09 03:54:30 +0200 @@ -523,6 +538,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);