--- linux-2.6.16-rc1/fs/namespace.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/namespace.c 2006-01-25 05:34:51 +0100 @@ -608,7 +676,7 @@ asmlinkage long sys_umount(char __user * goto dput_and_out; retval = -EPERM; - if (!capable(CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SECURE_MOUNT)) goto dput_and_out; retval = do_umount(nd.mnt, flags); --- linux-2.6.16-rc1/fs/namespace.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/namespace.c 2006-01-25 05:34:51 +0100 @@ -634,6 +702,8 @@ static int mount_is_safe(struct nameidat { if (capable(CAP_SYS_ADMIN)) return 0; + if (vx_ccaps(VXC_SECURE_MOUNT)) + return 0; return -EPERM; #ifdef notyet if (S_ISLNK(nd->dentry->d_inode->i_mode)) --- linux-2.6.16-rc1/fs/namespace.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/namespace.c 2006-01-25 05:34:51 +0100 @@ -917,7 +996,7 @@ ***** int err; struct super_block *sb = nd->mnt->mnt_sb; - if (!capable(CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SECURE_REMOUNT)) return -EPERM; if (!check_mnt(nd->mnt)) --- linux-2.6.16-rc1/fs/namespace.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/namespace.c 2006-01-25 05:34:51 +0100 @@ -1341,7 +1433,7 @@ int copy_namespace(int flags, struct tas if (!(flags & CLONE_NEWNS)) return 0; - if (!capable(CAP_SYS_ADMIN)) { + if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SECURE_MOUNT)) { put_namespace(namespace); return -EPERM; } --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -81,7 +84,7 @@ static int generic_quotactl_valid(struct if (cmd == Q_GETQUOTA) { if (((type == USRQUOTA && current->euid != id) || (type == GRPQUOTA && !in_egroup_p(id))) && - !capable(CAP_SYS_ADMIN)) + !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) return -EPERM; } else if (cmd != Q_GETFMT && cmd != Q_SYNC && cmd != Q_GETINFO) --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -85,7 +88,7 @@ ***** return -EPERM; } else if (cmd != Q_GETFMT && cmd != Q_SYNC && cmd != Q_GETINFO) - if (!capable(CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) return -EPERM; return 0; --- linux-2.6.16-rc1/fs/quota.c 2006-01-26 22:35:12 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/quota.c 2006-01-21 18:28:18 +0100 @@ -132,10 +135,10 @@ static int xqm_quotactl_valid(struct sup if (cmd == Q_XGETQUOTA) { if (((type == XQM_USRQUOTA && current->euid != id) || (type == XQM_GRPQUOTA && !in_egroup_p(id))) && - !capable(CAP_SYS_ADMIN)) + !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) return -EPERM; } else if (cmd != Q_XGETQSTAT && cmd != Q_XQUOTASYNC) { - if (!capable(CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) return -EPERM; } --- linux-2.6.16-rc1/fs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/super.c 2006-01-21 18:28:18 +0100 @@ -789,7 +791,7 @@ struct vfsmount * do_kern_mount(const char *fstype, int flags, const char *name, void *data) { struct file_system_type *type = get_fs_type(fstype); - struct super_block *sb = ERR_PTR(-ENOMEM); + struct super_block *sb; struct vfsmount *mnt; int error; char *secdata = NULL; --- linux-2.6.16-rc1/fs/super.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/super.c 2006-01-21 18:28:18 +0100 @@ -797,6 +799,12 @@ do_kern_mount(const char *fstype, int fl if (!type) return ERR_PTR(-ENODEV); + sb = ERR_PTR(-EPERM); + if ((type->fs_flags & FS_BINARY_MOUNTDATA) && + !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_BINARY_MOUNT)) + goto out; + + sb = ERR_PTR(-ENOMEM); mnt = alloc_vfsmnt(name); if (!mnt) goto out; --- linux-2.6.16-rc1/fs/xfs/quota/xfs_qm_syscalls.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/xfs/quota/xfs_qm_syscalls.c 2006-01-21 18:28:18 +0100 @@ -384,7 +384,7 @@ xfs_qm_scall_trunc_qfiles( int error; xfs_inode_t *qip; - if (!capable(CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) return XFS_ERROR(EPERM); error = 0; if (!XFS_SB_VERSION_HASQUOTA(&mp->m_sb) || flags == 0) { --- linux-2.6.16-rc1/fs/xfs/quota/xfs_qm_syscalls.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/xfs/quota/xfs_qm_syscalls.c 2006-01-21 18:28:18 +0100 @@ -429,7 +429,7 @@ xfs_qm_scall_quotaon( uint accflags; __int64_t sbflags; - if (!capable(CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) return XFS_ERROR(EPERM); flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD); --- linux-2.6.16-rc1/fs/xfs/quota/xfs_qm_syscalls.c 2006-01-26 22:35:13 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/fs/xfs/quota/xfs_qm_syscalls.c 2006-01-21 18:28:18 +0100 @@ -600,7 +600,7 @@ xfs_qm_scall_setqlim( int error; xfs_qcnt_t hard, soft; - if (!capable(CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) return XFS_ERROR(EPERM); if ((newlim->d_fieldmask & --- linux-2.6.16-rc1/kernel/sched.c 2006-01-26 22:35:32 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/kernel/sched.c 2006-01-21 18:28:15 +0100 @@ -3642,7 +3709,7 @@ asmlinkage long sys_nice(int increment) nice = 19; if (increment < 0 && !can_nice(current, nice)) - return -EPERM; + return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM; retval = security_task_setnice(current, nice); if (retval) --- linux-2.6.16-rc1/kernel/sys.c 2006-01-26 22:35:32 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/kernel/sys.c 2006-01-21 18:51:02 +0100 @@ -227,6 +229,8 @@ EXPORT_SYMBOL(unregister_reboot_notifier #ifndef CONFIG_SECURITY int capable(int cap) { + if (vx_check_bit(VXC_CAP_MASK, cap) && !vx_mcaps(1L << cap)) + return 0; if (cap_raised(current->cap_effective, cap)) { current->flags |= PF_SUPERPRIV; return 1; --- linux-2.6.16-rc1/kernel/sys.c 2006-01-26 22:35:32 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/kernel/sys.c 2006-01-21 18:51:02 +0100 @@ -246,7 +250,10 @@ static int set_one_prio(struct task_stru goto out; } if (niceval < task_nice(p) && !can_nice(p, niceval)) { - error = -EACCES; + if (vx_flags(VXF_IGNEG_NICE, 0)) + error = 0; + else + error = -EACCES; goto out; } no_nice = security_task_setnice(p, niceval); --- linux-2.6.16-rc1/kernel/sys.c 2006-01-26 22:35:32 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/kernel/sys.c 2006-01-21 18:51:02 +0100 @@ -1534,7 +1551,7 @@ asmlinkage long sys_sethostname(char __u int errno; char tmp[__NEW_UTS_LEN]; - if (!capable(CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SET_UTSNAME)) return -EPERM; if (len < 0 || len > __NEW_UTS_LEN) return -EINVAL; --- linux-2.6.16-rc1/kernel/sys.c 2006-01-26 22:35:32 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/kernel/sys.c 2006-01-21 18:51:02 +0100 @@ -1579,7 +1600,7 @@ asmlinkage long sys_setdomainname(char _ int errno; char tmp[__NEW_UTS_LEN]; - if (!capable(CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SET_UTSNAME)) return -EPERM; if (len < 0 || len > __NEW_UTS_LEN) return -EINVAL; --- linux-2.6.16-rc1/kernel/sys.c 2006-01-26 22:35:32 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/kernel/sys.c 2006-01-21 18:51:02 +0100 @@ -1645,7 +1668,7 @@ asmlinkage long sys_setrlimit(unsigned i return -EINVAL; old_rlim = current->signal->rlim + resource; if ((new_rlim.rlim_max > old_rlim->rlim_max) && - !capable(CAP_SYS_RESOURCE)) + !capable(CAP_SYS_RESOURCE) && !vx_ccaps(VXC_SET_RLIMIT)) return -EPERM; if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > NR_OPEN) return -EPERM; --- linux-2.6.16-rc1/net/ipv4/af_inet.c 2006-01-26 22:35:34 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/net/ipv4/af_inet.c 2006-01-21 18:28:15 +0100 @@ -282,9 +283,11 @@ lookup_protocol: } err = -EPERM; + if ((protocol == IPPROTO_ICMP) && vx_ccaps(VXC_RAW_ICMP)) + goto override; if (answer->capability > 0 && !capable(answer->capability)) goto out_rcu_unlock; - +override: sock->ops = answer->ops; answer_prot = answer->prot; answer_no_check = answer->no_check; --- linux-2.6.16-rc1/security/commoncap.c 2006-01-26 22:35:40 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/security/commoncap.c 2006-01-21 18:28:15 +0100 @@ -143,7 +143,7 @@ void cap_bprm_apply_creds (struct linux_ /* Derived from fs/exec.c:compute_creds. */ kernel_cap_t new_permitted, working; - new_permitted = cap_intersect (bprm->cap_permitted, cap_bset); + new_permitted = cap_intersect (bprm->cap_permitted, vx_current_bcaps()); working = cap_intersect (bprm->cap_inheritable, current->cap_inheritable); new_permitted = cap_combine (new_permitted, working); --- linux-2.6.16-rc1/security/commoncap.c 2006-01-26 22:35:40 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/security/commoncap.c 2006-01-21 18:28:15 +0100 @@ -312,7 +312,8 @@ void cap_task_reparent_to_init (struct t int cap_syslog (int type) { - if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN)) + if ((type != 3 && type != 10) && + !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SYSLOG)) return -EPERM; return 0; } --- linux-2.6.16-rc1/security/security.c 2006-01-26 22:35:40 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/security/security.c 2006-01-21 18:28:15 +0100 @@ -186,6 +186,8 @@ int mod_unreg_security(const char *name, */ int capable(int cap) { + if (vx_check_bit(VXC_CAP_MASK, cap) && !vx_mcaps(1L << cap)) + return 0; if (security_ops->capable(current, cap)) { /* capability denied */ return 0; --- linux-2.6.16-rc1/security/security.c 2006-01-26 22:35:40 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/security/security.c 2006-01-21 18:28:15 +0100 @@ -196,6 +198,20 @@ int capable(int cap) return 1; } +int vx_capable(int cap, int ccap) +{ + if (security_ops->capable(current, cap)) { + /* capability denied */ + return 0; + } + if (!vx_ccaps(ccap)) + return 0; + + /* capability granted */ + current->flags |= PF_SUPERPRIV; + return 1; +} + EXPORT_SYMBOL_GPL(register_security); EXPORT_SYMBOL_GPL(unregister_security); EXPORT_SYMBOL_GPL(mod_reg_security); --- linux-2.6.16-rc1/security/security.c 2006-01-26 22:35:40 +0100 +++ linux-2.6.16-rc1-vs2.1.0.9.4/security/security.c 2006-01-21 18:28:15 +0100 @@ -201,4 +217,5 @@ ***** EXPORT_SYMBOL_GPL(mod_reg_security); EXPORT_SYMBOL_GPL(mod_unreg_security); EXPORT_SYMBOL(capable); +EXPORT_SYMBOL(vx_capable); EXPORT_SYMBOL(security_ops);