diff -NurpP linux-2.6.17.4-vs2.1.1-rc25.0.1/include/linux/vserver/context_cmd.h linux-2.6.17.4-vs2.1.1-rc25.1/include/linux/vserver/context_cmd.h --- linux-2.6.17.4-vs2.1.1-rc25.0.1/include/linux/vserver/context_cmd.h 2006-07-09 17:07:13 +0200 +++ linux-2.6.17.4-vs2.1.1-rc25.1/include/linux/vserver/context_cmd.h 2006-07-09 19:28:39 +0200 @@ -20,7 +19,7 @@ struct vcmd_vx_info_v0 { }; #ifdef __KERNEL__ -extern int vc_vx_info(uint32_t, void __user *); +extern int vc_vx_info(struct vx_info *, void __user *); #endif /* __KERNEL__ */ @@ -43,7 +42,7 @@ struct vcmd_ctx_migrate { #ifdef __KERNEL__ extern int vc_ctx_create(uint32_t, void __user *); -extern int vc_ctx_migrate(uint32_t, void __user *); +extern int vc_ctx_migrate(struct vx_info *, void __user *); #endif /* __KERNEL__ */ @@ -59,8 +58,8 @@ struct vcmd_ctx_flags_v0 { }; #ifdef __KERNEL__ -extern int vc_get_cflags(uint32_t, void __user *); -extern int vc_set_cflags(uint32_t, void __user *); +extern int vc_get_cflags(struct vx_info *, void __user *); +extern int vc_set_cflags(struct vx_info *, void __user *); #endif /* __KERNEL__ */ @@ -85,10 +84,10 @@ struct vcmd_ctx_caps_v1 { }; #ifdef __KERNEL__ -extern int vc_get_ccaps_v0(uint32_t, void __user *); -extern int vc_set_ccaps_v0(uint32_t, void __user *); -extern int vc_get_ccaps(uint32_t, void __user *); -extern int vc_set_ccaps(uint32_t, void __user *); +extern int vc_get_ccaps_v0(struct vx_info *, void __user *); +extern int vc_set_ccaps_v0(struct vx_info *, void __user *); +extern int vc_get_ccaps(struct vx_info *, void __user *); +extern int vc_set_ccaps(struct vx_info *, void __user *); #endif /* __KERNEL__ */ @@ -104,8 +103,8 @@ struct vcmd_bcaps { }; #ifdef __KERNEL__ -extern int vc_get_bcaps(uint32_t, void __user *); -extern int vc_set_bcaps(uint32_t, void __user *); +extern int vc_get_bcaps(struct vx_info *, void __user *); +extern int vc_set_bcaps(struct vx_info *, void __user *); #endif /* __KERNEL__ */ #endif /* _VX_CONTEXT_CMD_H */ diff -NurpP linux-2.6.17.4-vs2.1.1-rc25.0.1/include/linux/vserver/cvirt_cmd.h linux-2.6.17.4-vs2.1.1-rc25.1/include/linux/vserver/cvirt_cmd.h --- linux-2.6.17.4-vs2.1.1-rc25.0.1/include/linux/vserver/cvirt_cmd.h 2006-07-09 17:07:13 +0200 +++ linux-2.6.17.4-vs2.1.1-rc25.1/include/linux/vserver/cvirt_cmd.h 2006-07-09 19:24:57 +0200 @@ -28,8 +28,8 @@ enum vhi_name_field { #include -extern int vc_set_vhi_name(uint32_t, void __user *); -extern int vc_get_vhi_name(uint32_t, void __user *); +extern int vc_set_vhi_name(struct vx_info *, void __user *); +extern int vc_get_vhi_name(struct vx_info *, void __user *); #endif /* __KERNEL__ */ #endif /* _VX_CVIRT_CMD_H */ diff -NurpP linux-2.6.17.4-vs2.1.1-rc25.0.1/include/linux/vserver/limit_cmd.h linux-2.6.17.4-vs2.1.1-rc25.1/include/linux/vserver/limit_cmd.h --- linux-2.6.17.4-vs2.1.1-rc25.0.1/include/linux/vserver/limit_cmd.h 2006-07-09 17:07:13 +0200 +++ linux-2.6.17.4-vs2.1.1-rc25.1/include/linux/vserver/limit_cmd.h 2006-07-09 19:26:04 +0200 @@ -41,15 +41,15 @@ struct vcmd_ctx_rlimit_v0_x32 { #include -extern int vc_get_rlimit(uint32_t, void __user *); -extern int vc_set_rlimit(uint32_t, void __user *); extern int vc_get_rlimit_mask(uint32_t, void __user *); -extern int vc_reset_minmax(uint32_t, void __user *); +extern int vc_get_rlimit(struct vx_info *, void __user *); +extern int vc_set_rlimit(struct vx_info *, void __user *); +extern int vc_reset_minmax(struct vx_info *, void __user *); #ifdef CONFIG_IA32_EMULATION -extern int vc_get_rlimit_x32(uint32_t, void __user *); -extern int vc_set_rlimit_x32(uint32_t, void __user *); +extern int vc_get_rlimit_x32(struct vx_info *, void __user *); +extern int vc_set_rlimit_x32(struct vx_info *, void __user *); #endif /* CONFIG_IA32_EMULATION */ diff -NurpP linux-2.6.17.4-vs2.1.1-rc25.0.1/include/linux/vserver/namespace_cmd.h linux-2.6.17.4-vs2.1.1-rc25.1/include/linux/vserver/namespace_cmd.h --- linux-2.6.17.4-vs2.1.1-rc25.0.1/include/linux/vserver/namespace_cmd.h 2006-07-09 17:07:13 +0200 +++ linux-2.6.17.4-vs2.1.1-rc25.1/include/linux/vserver/namespace_cmd.h 2006-07-09 19:26:16 +0200 @@ -11,9 +11,8 @@ #ifdef __KERNEL__ -extern int vc_enter_namespace(uint32_t, void __user *); -extern int vc_cleanup_namespace(uint32_t, void __user *); -extern int vc_set_namespace(uint32_t, void __user *); +extern int vc_enter_namespace(struct vx_info *, void __user *); +extern int vc_set_namespace(struct vx_info *, void __user *); #endif /* __KERNEL__ */ #endif /* _VX_NAMESPACE_CMD_H */ diff -NurpP linux-2.6.17.4-vs2.1.1-rc25.0.1/include/linux/vserver/network_cmd.h linux-2.6.17.4-vs2.1.1-rc25.1/include/linux/vserver/network_cmd.h --- linux-2.6.17.4-vs2.1.1-rc25.0.1/include/linux/vserver/network_cmd.h 2006-07-09 17:07:13 +0200 +++ linux-2.6.17.4-vs2.1.1-rc25.1/include/linux/vserver/network_cmd.h 2006-07-09 19:32:36 +0200 @@ -19,7 +19,7 @@ struct vcmd_nx_info_v0 { }; #ifdef __KERNEL__ -extern int vc_nx_info(uint32_t, void __user *); +extern int vc_nx_info(struct nx_info *, void __user *); #endif /* __KERNEL__ */ @@ -46,10 +46,10 @@ struct vcmd_net_addr_v0 { #ifdef __KERNEL__ extern int vc_net_create(uint32_t, void __user *); -extern int vc_net_migrate(uint32_t, void __user *); +extern int vc_net_migrate(struct nx_info *, void __user *); -extern int vc_net_add(uint32_t, void __user *); -extern int vc_net_remove(uint32_t, void __user *); +extern int vc_net_add(struct nx_info *, void __user *); +extern int vc_net_remove(struct nx_info *, void __user *); #endif /* __KERNEL__ */ @@ -65,8 +65,8 @@ struct vcmd_net_flags_v0 { }; #ifdef __KERNEL__ -extern int vc_get_nflags(uint32_t, void __user *); -extern int vc_set_nflags(uint32_t, void __user *); +extern int vc_get_nflags(struct nx_info *, void __user *); +extern int vc_set_nflags(struct nx_info *, void __user *); #endif /* __KERNEL__ */ @@ -82,8 +82,8 @@ struct vcmd_net_caps_v0 { }; #ifdef __KERNEL__ -extern int vc_get_ncaps(uint32_t, void __user *); -extern int vc_set_ncaps(uint32_t, void __user *); +extern int vc_get_ncaps(struct nx_info *, void __user *); +extern int vc_set_ncaps(struct nx_info *, void __user *); #endif /* __KERNEL__ */ #endif /* _VX_CONTEXT_CMD_H */ diff -NurpP linux-2.6.17.4-vs2.1.1-rc25.0.1/include/linux/vserver/sched_cmd.h linux-2.6.17.4-vs2.1.1-rc25.1/include/linux/vserver/sched_cmd.h --- linux-2.6.17.4-vs2.1.1-rc25.0.1/include/linux/vserver/sched_cmd.h 2006-07-09 17:07:13 +0200 +++ linux-2.6.17.4-vs2.1.1-rc25.1/include/linux/vserver/sched_cmd.h 2006-07-09 19:27:34 +0200 @@ -64,9 +64,9 @@ struct vcmd_set_sched_v4 { #include -extern int vc_set_sched_v2(uint32_t, void __user *); -extern int vc_set_sched_v3(uint32_t, void __user *); -extern int vc_set_sched(uint32_t, void __user *); +extern int vc_set_sched_v2(struct vx_info *, void __user *); +extern int vc_set_sched_v3(struct vx_info *, void __user *); +extern int vc_set_sched(struct vx_info *, void __user *); #endif /* __KERNEL__ */ #endif /* _VX_SCHED_CMD_H */ diff -NurpP linux-2.6.17.4-vs2.1.1-rc25.0.1/include/linux/vserver/signal_cmd.h linux-2.6.17.4-vs2.1.1-rc25.1/include/linux/vserver/signal_cmd.h --- linux-2.6.17.4-vs2.1.1-rc25.0.1/include/linux/vserver/signal_cmd.h 2006-07-09 17:07:13 +0200 +++ linux-2.6.17.4-vs2.1.1-rc25.1/include/linux/vserver/signal_cmd.h 2006-07-09 19:27:47 +0200 @@ -19,8 +19,8 @@ struct vcmd_wait_exit_v0 { #ifdef __KERNEL__ -extern int vc_ctx_kill(uint32_t, void __user *); -extern int vc_wait_exit(uint32_t, void __user *); +extern int vc_ctx_kill(struct vx_info *, void __user *); +extern int vc_wait_exit(struct vx_info *, void __user *); #endif /* __KERNEL__ */ #endif /* _VX_SIGNAL_CMD_H */ diff -NurpP linux-2.6.17.4-vs2.1.1-rc25.0.1/kernel/vserver/context.c linux-2.6.17.4-vs2.1.1-rc25.1/kernel/vserver/context.c --- linux-2.6.17.4-vs2.1.1-rc25.0.1/kernel/vserver/context.c 2006-07-09 17:07:14 +0200 +++ linux-2.6.17.4-vs2.1.1-rc25.1/kernel/vserver/context.c 2006-07-10 01:38:49 +0200 @@ -3,7 +3,7 @@ * * Virtual Server: Context Support * - * Copyright (C) 2003-2005 Herbert Pötzl + * Copyright (C) 2003-2006 Herbert Pötzl * * V0.01 context helper * V0.02 vx_ctx_kill syscall command @@ -18,6 +18,7 @@ * V0.11 and back to locking again * V0.12 referenced context store * V0.13 separate per cpu data + * V0.14 changed vcmds to vxi arg * */ @@ -794,21 +795,12 @@ int vc_task_xid(uint32_t id, void __user } -int vc_vx_info(uint32_t id, void __user *data) +int vc_vx_info(struct vx_info *vxi, void __user *data) { - struct vx_info *vxi; struct vcmd_vx_info_v0 vc_data; - if (!capable(CAP_SYS_RESOURCE)) - return -EPERM; - - vxi = lookup_vx_info(id); - if (!vxi) - return -ESRCH; - vc_data.xid = vxi->vx_id; vc_data.initpid = vxi->vx_initpid; - put_vx_info(vxi); if (copy_to_user (data, &vc_data, sizeof(vc_data))) return -EFAULT; @@ -852,67 +844,44 @@ int vc_ctx_create(uint32_t xid, void __u } -int vc_ctx_migrate(uint32_t id, void __user *data) +int vc_ctx_migrate(struct vx_info *vxi, void __user *data) { struct vcmd_ctx_migrate vc_data = { .flagword = 0 }; - struct vx_info *vxi; if (data && copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - /* dirty hack until Spectator becomes a cap */ - if (id == 1) { - current->xid = 1; - return 0; - } - - vxi = lookup_vx_info(id); - if (!vxi) - return -ESRCH; vx_migrate_task(current, vxi); if (vc_data.flagword & VXM_SET_INIT) vx_set_init(vxi, current); if (vc_data.flagword & VXM_SET_REAPER) vx_set_reaper(vxi, current); - put_vx_info(vxi); return 0; } -int vc_get_cflags(uint32_t id, void __user *data) +int vc_get_cflags(struct vx_info *vxi, void __user *data) { - struct vx_info *vxi; struct vcmd_ctx_flags_v0 vc_data; - vxi = lookup_vx_info(id); - if (!vxi) - return -ESRCH; - vc_data.flagword = vxi->vx_flags; /* special STATE flag handling */ vc_data.mask = vx_mask_flags(~0UL, vxi->vx_flags, VXF_ONE_TIME); - put_vx_info(vxi); - if (copy_to_user (data, &vc_data, sizeof(vc_data))) return -EFAULT; return 0; } -int vc_set_cflags(uint32_t id, void __user *data) +int vc_set_cflags(struct vx_info *vxi, void __user *data) { - struct vx_info *vxi; struct vcmd_ctx_flags_v0 vc_data; uint64_t mask, trigger; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - vxi = lookup_vx_info(id); - if (!vxi) - return -ESRCH; - /* special STATE flag handling */ mask = vx_mask_mask(vc_data.mask, vxi->vx_flags, VXF_ONE_TIME); trigger = (mask & vxi->vx_flags) ^ (mask & vc_data.flagword); @@ -931,33 +900,25 @@ int vc_set_cflags(uint32_t id, void __us if (trigger & VXF_PERSISTENT) vx_set_persistent(vxi); - put_vx_info(vxi); return 0; } -static int do_get_caps(xid_t xid, uint64_t *bcaps, uint64_t *ccaps) +static int do_get_caps(struct vx_info *vxi, uint64_t *bcaps, uint64_t *ccaps) { - struct vx_info *vxi; - - vxi = lookup_vx_info(xid); - if (!vxi) - return -ESRCH; - if (bcaps) *bcaps = vxi->vx_bcaps; if (ccaps) *ccaps = vxi->vx_ccaps; - put_vx_info(vxi); return 0; } -int vc_get_ccaps_v0(uint32_t id, void __user *data) +int vc_get_ccaps_v0(struct vx_info *vxi, void __user *data) { struct vcmd_ctx_caps_v0 vc_data; int ret; - ret = do_get_caps(id, &vc_data.bcaps, &vc_data.ccaps); + ret = do_get_caps(vxi, &vc_data.bcaps, &vc_data.ccaps); if (ret) return ret; vc_data.cmask = ~0UL; @@ -967,12 +928,12 @@ int vc_get_ccaps_v0(uint32_t id, void __ return 0; } -int vc_get_ccaps(uint32_t id, void __user *data) +int vc_get_ccaps(struct vx_info *vxi, void __user *data) { struct vcmd_ctx_caps_v1 vc_data; int ret; - ret = do_get_caps(id, NULL, &vc_data.ccaps); + ret = do_get_caps(vxi, NULL, &vc_data.ccaps); if (ret) return ret; vc_data.cmask = ~0UL; @@ -982,23 +943,16 @@ int vc_get_ccaps(uint32_t id, void __use return 0; } -static int do_set_caps(xid_t xid, uint64_t bcaps, uint64_t bmask, - uint64_t ccaps, uint64_t cmask) +static int do_set_caps(struct vx_info *vxi, + uint64_t bcaps, uint64_t bmask, uint64_t ccaps, uint64_t cmask) { - struct vx_info *vxi; - - vxi = lookup_vx_info(xid); - if (!vxi) - return -ESRCH; - vxi->vx_bcaps = vx_mask_flags(vxi->vx_bcaps, bcaps, bmask); vxi->vx_ccaps = vx_mask_flags(vxi->vx_ccaps, ccaps, cmask); - put_vx_info(vxi); return 0; } -int vc_set_ccaps_v0(uint32_t id, void __user *data) +int vc_set_ccaps_v0(struct vx_info *vxi, void __user *data) { struct vcmd_ctx_caps_v0 vc_data; @@ -1006,26 +960,26 @@ int vc_set_ccaps_v0(uint32_t id, void __ return -EFAULT; /* simulate old &= behaviour for bcaps */ - return do_set_caps(id, 0, ~vc_data.bcaps, + return do_set_caps(vxi, 0, ~vc_data.bcaps, vc_data.ccaps, vc_data.cmask); } -int vc_set_ccaps(uint32_t id, void __user *data) +int vc_set_ccaps(struct vx_info *vxi, void __user *data) { struct vcmd_ctx_caps_v1 vc_data; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - return do_set_caps(id, 0, 0, vc_data.ccaps, vc_data.cmask); + return do_set_caps(vxi, 0, 0, vc_data.ccaps, vc_data.cmask); } -int vc_get_bcaps(uint32_t id, void __user *data) +int vc_get_bcaps(struct vx_info *vxi, void __user *data) { struct vcmd_bcaps vc_data; int ret; - ret = do_get_caps(id, &vc_data.bcaps, NULL); + ret = do_get_caps(vxi, &vc_data.bcaps, NULL); if (ret) return ret; vc_data.bmask = ~0UL; @@ -1035,14 +989,14 @@ int vc_get_bcaps(uint32_t id, void __use return 0; } -int vc_set_bcaps(uint32_t id, void __user *data) +int vc_set_bcaps(struct vx_info *vxi, void __user *data) { struct vcmd_bcaps vc_data; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - return do_set_caps(id, vc_data.bcaps, vc_data.bmask, 0, 0); + return do_set_caps(vxi, vc_data.bcaps, vc_data.bmask, 0, 0); } #include diff -NurpP linux-2.6.17.4-vs2.1.1-rc25.0.1/kernel/vserver/cvirt.c linux-2.6.17.4-vs2.1.1-rc25.1/kernel/vserver/cvirt.c --- linux-2.6.17.4-vs2.1.1-rc25.0.1/kernel/vserver/cvirt.c 2006-07-09 17:07:14 +0200 +++ linux-2.6.17.4-vs2.1.1-rc25.1/kernel/vserver/cvirt.c 2006-07-09 19:22:26 +0200 @@ -3,10 +3,11 @@ * * Virtual Server: Context Virtualization * - * Copyright (C) 2004-2005 Herbert Pötzl + * Copyright (C) 2004-2006 Herbert Pötzl * * V0.01 broken out from limit.c * V0.02 added utsname stuff + * V0.03 changed vcmds to vxi arg * */ @@ -211,49 +212,38 @@ static char * vx_vhi_name(struct vx_info return NULL; } -int vc_set_vhi_name(uint32_t id, void __user *data) +int vc_set_vhi_name(struct vx_info *vxi, void __user *data) { - struct vx_info *vxi; struct vcmd_vhi_name_v0 vc_data; char *name; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - vxi = lookup_vx_info(id); - if (!vxi) - return -ESRCH; - name = vx_vhi_name(vxi, vc_data.field); - if (name) - memcpy(name, vc_data.name, 65); - put_vx_info(vxi); - return (name ? 0 : -EFAULT); + if (!name) + return -EFAULT; + + memcpy(name, vc_data.name, 65); + return 0; } -int vc_get_vhi_name(uint32_t id, void __user *data) +int vc_get_vhi_name(struct vx_info *vxi, void __user *data) { - struct vx_info *vxi; struct vcmd_vhi_name_v0 vc_data; char *name; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - vxi = lookup_vx_info(id); - if (!vxi) - return -ESRCH; - name = vx_vhi_name(vxi, vc_data.field); if (!name) - goto out_put; + return -EFAULT; memcpy(vc_data.name, name, 65); if (copy_to_user (data, &vc_data, sizeof(vc_data))) return -EFAULT; -out_put: - put_vx_info(vxi); - return (name ? 0 : -EFAULT); + return 0; } #ifdef CONFIG_VSERVER_VTIME diff -NurpP linux-2.6.17.4-vs2.1.1-rc25.0.1/kernel/vserver/limit.c linux-2.6.17.4-vs2.1.1-rc25.1/kernel/vserver/limit.c --- linux-2.6.17.4-vs2.1.1-rc25.0.1/kernel/vserver/limit.c 2006-07-09 17:07:14 +0200 +++ linux-2.6.17.4-vs2.1.1-rc25.1/kernel/vserver/limit.c 2006-07-09 19:22:06 +0200 @@ -3,9 +3,10 @@ * * Virtual Server: Context Limits * - * Copyright (C) 2004-2005 Herbert Pötzl + * Copyright (C) 2004-2006 Herbert Pötzl * * V0.01 broken out from vcontext V0.05 + * V0.02 changed vcmds to vxi arg * */ @@ -77,29 +78,22 @@ static inline uint64_t vc_get_hard(struc return VX_VLIM(limit); } -static int do_get_rlimit(xid_t xid, uint32_t id, +static int do_get_rlimit(struct vx_info *vxi, uint32_t id, uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum) { - struct vx_info *vxi; - if (!is_valid_rlimit(id)) return -EINVAL; - vxi = lookup_vx_info(xid); - if (!vxi) - return -ESRCH; - if (minimum) *minimum = CRLIM_UNSET; if (softlimit) *softlimit = vc_get_soft(vxi, id); if (maximum) *maximum = vc_get_hard(vxi, id); - put_vx_info(vxi); return 0; } -int vc_get_rlimit(uint32_t id, void __user *data) +int vc_get_rlimit(struct vx_info *vxi, void __user *data) { struct vcmd_ctx_rlimit_v0 vc_data; int ret; @@ -107,7 +101,7 @@ int vc_get_rlimit(uint32_t id, void __us if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - ret = do_get_rlimit(id, vc_data.id, + ret = do_get_rlimit(vxi, vc_data.id, &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum); if (ret) return ret; @@ -117,18 +111,12 @@ int vc_get_rlimit(uint32_t id, void __us return 0; } -static int do_set_rlimit(xid_t xid, uint32_t id, +static int do_set_rlimit(struct vx_info *vxi, uint32_t id, uint64_t minimum, uint64_t softlimit, uint64_t maximum) { - struct vx_info *vxi; - if (!is_valid_rlimit(id)) return -EINVAL; - vxi = lookup_vx_info(xid); - if (!vxi) - return -ESRCH; - if (maximum != CRLIM_KEEP) __rlim_hard(&vxi->limit, id) = VX_RLIM(maximum); if (softlimit != CRLIM_KEEP) @@ -138,39 +126,34 @@ static int do_set_rlimit(xid_t xid, uint if (__rlim_soft(&vxi->limit, id) > __rlim_hard(&vxi->limit, id)) __rlim_soft(&vxi->limit, id) = __rlim_hard(&vxi->limit, id); - put_vx_info(vxi); return 0; } -int vc_set_rlimit(uint32_t id, void __user *data) +int vc_set_rlimit(struct vx_info *vxi, void __user *data) { struct vcmd_ctx_rlimit_v0 vc_data; - if (!capable(CAP_SYS_RESOURCE)) - return -EPERM; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - return do_set_rlimit(id, vc_data.id, + return do_set_rlimit(vxi, vc_data.id, vc_data.minimum, vc_data.softlimit, vc_data.maximum); } #ifdef CONFIG_IA32_EMULATION -int vc_set_rlimit_x32(uint32_t id, void __user *data) +int vc_set_rlimit_x32(struct vx_info *vxi, void __user *data) { struct vcmd_ctx_rlimit_v0_x32 vc_data; - if (!capable(CAP_SYS_RESOURCE)) - return -EPERM; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - return do_set_rlimit(id, vc_data.id, + return do_set_rlimit(vxi, vc_data.id, vc_data.minimum, vc_data.softlimit, vc_data.maximum); } -int vc_get_rlimit_x32(uint32_t id, void __user *data) +int vc_get_rlimit_x32(struct vx_info *vxi, void __user *data) { struct vcmd_ctx_rlimit_v0_x32 vc_data; int ret; @@ -178,7 +161,7 @@ int vc_get_rlimit_x32(uint32_t id, void if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - ret = do_get_rlimit(id, vc_data.id, + ret = do_get_rlimit(vxi, vc_data.id, &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum); if (ret) return ret; @@ -212,8 +195,6 @@ int vc_get_rlimit_mask(uint32_t id, void 0 }; - if (!capable(CAP_SYS_RESOURCE)) - return -EPERM; if (copy_to_user(data, &mask, sizeof(mask))) return -EFAULT; return 0; @@ -233,19 +214,9 @@ static inline void vx_reset_minmax(struc } -int vc_reset_minmax(uint32_t id, void __user *data) +int vc_reset_minmax(struct vx_info *vxi, void __user *data) { - struct vx_info *vxi; - - if (!capable(CAP_SYS_RESOURCE)) - return -EPERM; - - vxi = lookup_vx_info(id); - if (!vxi) - return -ESRCH; - vx_reset_minmax(&vxi->limit); - put_vx_info(vxi); return 0; } diff -NurpP linux-2.6.17.4-vs2.1.1-rc25.0.1/kernel/vserver/namespace.c linux-2.6.17.4-vs2.1.1-rc25.1/kernel/vserver/namespace.c --- linux-2.6.17.4-vs2.1.1-rc25.0.1/kernel/vserver/namespace.c 2006-07-09 17:07:14 +0200 +++ linux-2.6.17.4-vs2.1.1-rc25.1/kernel/vserver/namespace.c 2006-07-09 17:58:08 +0200 @@ -46,27 +46,18 @@ int vx_set_namespace(struct vx_info *vxi return 0; } -int vc_enter_namespace(uint32_t id, void __user *data) +int vc_enter_namespace(struct vx_info *vxi, void __user *data) { - struct vx_info *vxi; struct fs_struct *old_fs, *fs; struct namespace *old_ns; - int ret = 0; - vxi = lookup_vx_info(id); - if (!vxi) - return -ESRCH; - - ret = -EINVAL; if (!vxi->vx_namespace) - goto out_put; + return -EINVAL; - ret = -ENOMEM; fs = copy_fs_struct(vxi->vx_fs); if (!fs) - goto out_put; + return -ENOMEM; - ret = 0; task_lock(current); old_ns = current->namespace; old_fs = current->fs; @@ -77,32 +68,15 @@ int vc_enter_namespace(uint32_t id, void put_namespace(old_ns); put_fs_struct(old_fs); -out_put: - put_vx_info(vxi); - return ret; -} - -int vc_cleanup_namespace(uint32_t id, void __user *data) -{ - // down_write(¤t->namespace->sem); - spin_lock(&vfsmount_lock); - umount_unused(current->namespace->root, current->fs); - spin_unlock(&vfsmount_lock); - // up_write(¤t->namespace->sem); return 0; } -int vc_set_namespace(uint32_t id, void __user *data) +int vc_set_namespace(struct vx_info *vxi, void __user *data) { struct fs_struct *fs; struct namespace *ns; - struct vx_info *vxi; int ret; - vxi = lookup_vx_info(id); - if (!vxi) - return -ESRCH; - task_lock(current); fs = current->fs; atomic_inc(&fs->count); @@ -114,7 +88,6 @@ int vc_set_namespace(uint32_t id, void _ put_namespace(ns); put_fs_struct(fs); - put_vx_info(vxi); return ret; } diff -NurpP linux-2.6.17.4-vs2.1.1-rc25.0.1/kernel/vserver/network.c linux-2.6.17.4-vs2.1.1-rc25.1/kernel/vserver/network.c --- linux-2.6.17.4-vs2.1.1-rc25.0.1/kernel/vserver/network.c 2006-07-09 17:07:14 +0200 +++ linux-2.6.17.4-vs2.1.1-rc25.1/kernel/vserver/network.c 2006-07-09 19:37:30 +0200 @@ -3,22 +3,23 @@ * * Virtual Server: Network Support * - * Copyright (C) 2003-2005 Herbert Pötzl + * Copyright (C) 2003-2006 Herbert Pötzl * * V0.01 broken out from vcontext V0.05 * V0.02 cleaned up implementation * V0.03 added equiv nx commands * V0.04 switch to RCU based hash * V0.05 and back to locking again + * V0.06 changed vcmds to nxi arg * */ #include -#include #include #include #include +#include /* __alloc_nx_info() @@ -544,20 +545,11 @@ int vc_task_nid(uint32_t id, void __user } -int vc_nx_info(uint32_t id, void __user *data) +int vc_nx_info(struct nx_info *nxi, void __user *data) { - struct nx_info *nxi; struct vcmd_nx_info_v0 vc_data; - if (!capable(CAP_SYS_RESOURCE)) - return -EPERM; - - nxi = lookup_nx_info(id); - if (!nxi) - return -ESRCH; - vc_data.nid = nxi->nx_id; - put_nx_info(nxi); if (copy_to_user (data, &vc_data, sizeof(vc_data))) return -EFAULT; @@ -601,22 +593,15 @@ int vc_net_create(uint32_t nid, void __u } -int vc_net_migrate(uint32_t id, void __user *data) +int vc_net_migrate(struct nx_info *nxi, void __user *data) { - struct nx_info *nxi; - - nxi = lookup_nx_info(id); - if (!nxi) - return -ESRCH; nx_migrate_task(current, nxi); - put_nx_info(nxi); return 0; } -int vc_net_add(uint32_t nid, void __user *data) +int vc_net_add(struct nx_info *nxi, void __user *data) { struct vcmd_net_addr_v0 vc_data; - struct nx_info *nxi; int index, pos, ret = 0; if (data && copy_from_user (&vc_data, data, sizeof(vc_data))) @@ -632,10 +617,6 @@ int vc_net_add(uint32_t nid, void __user break; } - nxi = lookup_nx_info(nid); - if (!nxi) - return -ESRCH; - switch (vc_data.type) { case NXA_TYPE_IPV4: index = 0; @@ -658,72 +639,49 @@ int vc_net_add(uint32_t nid, void __user ret = -EINVAL; break; } - - put_nx_info(nxi); return ret; } -int vc_net_remove(uint32_t nid, void __user *data) +int vc_net_remove(struct nx_info * nxi, void __user *data) { struct vcmd_net_addr_v0 vc_data; - struct nx_info *nxi; - int ret = 0; if (data && copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - nxi = lookup_nx_info(nid); - if (!nxi) - return -ESRCH; - switch ((unsigned)vc_data.type) { case NXA_TYPE_ANY: nxi->nbipv4 = 0; break; default: - ret = -EINVAL; - break; + return -EINVAL; } - - put_nx_info(nxi); - return ret; + return 0; } -int vc_get_nflags(uint32_t id, void __user *data) +int vc_get_nflags(struct nx_info *nxi, void __user *data) { - struct nx_info *nxi; struct vcmd_net_flags_v0 vc_data; - nxi = lookup_nx_info(id); - if (!nxi) - return -ESRCH; - vc_data.flagword = nxi->nx_flags; /* special STATE flag handling */ vc_data.mask = vx_mask_flags(~0UL, nxi->nx_flags, NXF_ONE_TIME); - put_nx_info(nxi); - if (copy_to_user (data, &vc_data, sizeof(vc_data))) return -EFAULT; return 0; } -int vc_set_nflags(uint32_t id, void __user *data) +int vc_set_nflags(struct nx_info *nxi, void __user *data) { - struct nx_info *nxi; struct vcmd_net_flags_v0 vc_data; uint64_t mask, trigger; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - nxi = lookup_nx_info(id); - if (!nxi) - return -ESRCH; - /* special STATE flag handling */ mask = vx_mask_mask(vc_data.mask, nxi->nx_flags, NXF_ONE_TIME); trigger = (mask & nxi->nx_flags) ^ (mask & vc_data.flagword); @@ -733,43 +691,30 @@ int vc_set_nflags(uint32_t id, void __us if (trigger & NXF_PERSISTENT) nx_set_persistent(nxi); - put_nx_info(nxi); return 0; } -int vc_get_ncaps(uint32_t id, void __user *data) +int vc_get_ncaps(struct nx_info *nxi, void __user *data) { - struct nx_info *nxi; struct vcmd_net_caps_v0 vc_data; - nxi = lookup_nx_info(id); - if (!nxi) - return -ESRCH; - vc_data.ncaps = nxi->nx_ncaps; vc_data.cmask = ~0UL; - put_nx_info(nxi); if (copy_to_user (data, &vc_data, sizeof(vc_data))) return -EFAULT; return 0; } -int vc_set_ncaps(uint32_t id, void __user *data) +int vc_set_ncaps(struct nx_info *nxi, void __user *data) { - struct nx_info *nxi; struct vcmd_net_caps_v0 vc_data; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - nxi = lookup_nx_info(id); - if (!nxi) - return -ESRCH; - nxi->nx_ncaps = vx_mask_flags(nxi->nx_ncaps, vc_data.ncaps, vc_data.cmask); - put_nx_info(nxi); return 0; } diff -NurpP linux-2.6.17.4-vs2.1.1-rc25.0.1/kernel/vserver/sched.c linux-2.6.17.4-vs2.1.1-rc25.1/kernel/vserver/sched.c --- linux-2.6.17.4-vs2.1.1-rc25.0.1/kernel/vserver/sched.c 2006-07-09 17:07:14 +0200 +++ linux-2.6.17.4-vs2.1.1-rc25.1/kernel/vserver/sched.c 2006-07-09 19:29:31 +0200 @@ -3,10 +3,11 @@ * * Virtual Server: Scheduler Support * - * Copyright (C) 2004-2005 Herbert Pötzl + * Copyright (C) 2004-2006 Herbert Pötzl * * V0.01 adapted Sam Vilains version to 2.6.3 * V0.02 removed legacy interface + * V0.03 changed vcmds to vxi arg * */ @@ -265,19 +266,14 @@ static int do_set_sched(struct vx_info * vc_data_v4.set_mask |= mask; \ } -int vc_set_sched_v2(uint32_t xid, void __user *data) +int vc_set_sched_v2(struct vx_info *vxi, void __user *data) { struct vcmd_set_sched_v2 vc_data; struct vcmd_set_sched_v4 vc_data_v4 = { .set_mask = 0 }; - struct vx_info *vxi; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - vxi = lookup_vx_info(xid); - if (!vxi) - return -ESRCH; - COPY_MASK_V2(fill_rate, VXSM_FILL_RATE); COPY_MASK_V2(interval, VXSM_INTERVAL); COPY_MASK_V2(tokens, VXSM_TOKENS); @@ -286,49 +282,33 @@ int vc_set_sched_v2(uint32_t xid, void _ vc_data_v4.bucket_id = 0; do_set_sched(vxi, &vc_data_v4); - put_vx_info(vxi); return 0; } #endif -int vc_set_sched_v3(uint32_t xid, void __user *data) +int vc_set_sched_v3(struct vx_info *vxi, void __user *data) { struct vcmd_set_sched_v3 vc_data; struct vcmd_set_sched_v4 vc_data_v4; - struct vx_info *vxi; - int ret; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - vxi = lookup_vx_info(xid); - if (!vxi) - return -ESRCH; - /* structures are binary compatible */ memcpy(&vc_data_v4, &vc_data, sizeof(vc_data)); vc_data_v4.set_mask &= VXSM_V3_MASK; vc_data_v4.bucket_id = 0; - ret = do_set_sched(vxi, &vc_data_v4); - put_vx_info(vxi); - return ret; + + return do_set_sched(vxi, &vc_data_v4); } -int vc_set_sched(uint32_t xid, void __user *data) +int vc_set_sched(struct vx_info *vxi, void __user *data) { struct vcmd_set_sched_v4 vc_data; - struct vx_info *vxi; - int ret; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - vxi = lookup_vx_info(xid); - if (!vxi) - return -ESRCH; - - ret = do_set_sched(vxi, &vc_data); - put_vx_info(vxi); - return ret; + return do_set_sched(vxi, &vc_data); } diff -NurpP linux-2.6.17.4-vs2.1.1-rc25.0.1/kernel/vserver/signal.c linux-2.6.17.4-vs2.1.1-rc25.1/kernel/vserver/signal.c --- linux-2.6.17.4-vs2.1.1-rc25.0.1/kernel/vserver/signal.c 2006-07-09 17:07:14 +0200 +++ linux-2.6.17.4-vs2.1.1-rc25.1/kernel/vserver/signal.c 2006-07-09 19:20:23 +0200 @@ -3,9 +3,10 @@ * * Virtual Server: Signal Support * - * Copyright (C) 2003-2005 Herbert Pötzl + * Copyright (C) 2003-2006 Herbert Pötzl * * V0.01 broken out from vcontext V0.05 + * V0.02 changed vcmds to vxi arg * */ @@ -69,22 +70,14 @@ int vx_info_kill(struct vx_info *vxi, in return retval; } -int vc_ctx_kill(uint32_t id, void __user *data) +int vc_ctx_kill(struct vx_info *vxi, void __user *data) { - int retval; struct vcmd_ctx_kill_v0 vc_data; - struct vx_info *vxi; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - vxi = lookup_vx_info(id); - if (!vxi) - return -ESRCH; - - retval = vx_info_kill(vxi, vc_data.pid, vc_data.sig); - put_vx_info(vxi); - return retval; + return vx_info_kill(vxi, vc_data.pid, vc_data.sig); } @@ -115,20 +108,14 @@ out: -int vc_wait_exit(uint32_t id, void __user *data) +int vc_wait_exit(struct vx_info *vxi, void __user *data) { - struct vx_info *vxi; struct vcmd_wait_exit_v0 vc_data; int ret; - vxi = lookup_vx_info(id); - if (!vxi) - return -ESRCH; - ret = __wait_exit(vxi); vc_data.reboot_cmd = vxi->reboot_cmd; vc_data.exit_code = vxi->exit_code; - put_vx_info(vxi); if (copy_to_user (data, &vc_data, sizeof(vc_data))) ret = -EFAULT; diff -NurpP linux-2.6.17.4-vs2.1.1-rc25.0.1/kernel/vserver/switch.c linux-2.6.17.4-vs2.1.1-rc25.1/kernel/vserver/switch.c --- linux-2.6.17.4-vs2.1.1-rc25.0.1/kernel/vserver/switch.c 2006-07-09 17:07:14 +0200 +++ linux-2.6.17.4-vs2.1.1-rc25.1/kernel/vserver/switch.c 2006-07-10 01:39:13 +0200 @@ -3,7 +3,7 @@ * * Virtual Server: Syscall Switch * - * Copyright (C) 2003-2005 Herbert Pötzl + * Copyright (C) 2003-2006 Herbert Pötzl * * V0.01 syscall switch * V0.02 added signal to context @@ -11,6 +11,7 @@ * V0.04 added iattr, task/xid functions * V0.05 added debug/history stuff * V0.06 added compat32 layer + * V0.07 vcmd args and perms * */ @@ -19,7 +20,8 @@ #include #include -#include +#include +#include #include #include @@ -67,142 +69,92 @@ int vc_get_vci(uint32_t id) static inline -long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat) +long do_vcmd(uint32_t cmd, uint32_t id, + struct vx_info *vxi, struct nx_info *nxi, + void __user *data, int compat) { - vxdprintk(VXD_CBIT(switch, 0), - "vc: VCMD_%02d_%d[%d], %d,%p,%d", - VC_CATEGORY(cmd), VC_COMMAND(cmd), - VC_VERSION(cmd), id, data, compat); - -#ifdef CONFIG_VSERVER_LEGACY - if (!capable(CAP_CONTEXT) && - /* dirty hack for capremove */ - !(cmd==VCMD_new_s_context && id==-2)) - return -EPERM; -#else - if (!capable(CAP_CONTEXT)) - return -EPERM; -#endif - /* moved here from the individual commands */ - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - switch (cmd) { + case VCMD_get_version: return vc_get_version(id); case VCMD_get_vci: return vc_get_vci(id); - case VCMD_dump_history: -#ifdef CONFIG_VSERVER_HISTORY - return vc_dump_history(id); -#else - return -ENOSYS; -#endif - -#ifdef CONFIG_VSERVER_LEGACY - case VCMD_new_s_context: - return vc_new_s_context(id, data); -#endif -#ifdef CONFIG_VSERVER_LEGACYNET - case VCMD_set_ipv4root: - return vc_set_ipv4root(id, data); -#endif - case VCMD_task_xid: return vc_task_xid(id, data); case VCMD_vx_info: - return vc_vx_info(id, data); + return vc_vx_info(vxi, data); case VCMD_task_nid: return vc_task_nid(id, data); case VCMD_nx_info: - return vc_nx_info(id, data); + return vc_nx_info(nxi, data); case VCMD_set_namespace_v0: - return vc_set_namespace(-1, data); /* this is version 1 */ case VCMD_set_namespace: - return vc_set_namespace(id, data); - case VCMD_cleanup_namespace: - return vc_cleanup_namespace(id, data); - } - - /* those are allowed while in setup too */ - if (!vx_check(0, VX_ADMIN|VX_WATCH) && - !vx_flags(VXF_STATE_SETUP,0)) - return -EPERM; - -#ifdef CONFIG_VSERVER_LEGACY - switch (cmd) { - case VCMD_set_cflags: - case VCMD_set_ccaps_v0: - if (vx_check(0, VX_WATCH)) - return 0; - } -#endif + return vc_set_namespace(vxi, data); - switch (cmd) { #ifdef CONFIG_IA32_EMULATION case VCMD_get_rlimit: - return __COMPAT(vc_get_rlimit, id, data, compat); + return __COMPAT(vc_get_rlimit, vxi, data, compat); case VCMD_set_rlimit: - return __COMPAT(vc_set_rlimit, id, data, compat); + return __COMPAT(vc_set_rlimit, vxi, data, compat); #else case VCMD_get_rlimit: - return vc_get_rlimit(id, data); + return vc_get_rlimit(vxi, data); case VCMD_set_rlimit: - return vc_set_rlimit(id, data); + return vc_set_rlimit(vxi, data); #endif case VCMD_get_rlimit_mask: return vc_get_rlimit_mask(id, data); case VCMD_reset_minmax: - return vc_reset_minmax(id, data); + return vc_reset_minmax(vxi, data); case VCMD_get_vhi_name: - return vc_get_vhi_name(id, data); + return vc_get_vhi_name(vxi, data); case VCMD_set_vhi_name: - return vc_set_vhi_name(id, data); + return vc_set_vhi_name(vxi, data); case VCMD_set_cflags: - return vc_set_cflags(id, data); + return vc_set_cflags(vxi, data); case VCMD_get_cflags: - return vc_get_cflags(id, data); + return vc_get_cflags(vxi, data); case VCMD_set_ccaps_v0: - return vc_set_ccaps_v0(id, data); + return vc_set_ccaps_v0(vxi, data); /* this is version 1 */ case VCMD_set_ccaps: - return vc_set_ccaps(id, data); + return vc_set_ccaps(vxi, data); case VCMD_get_ccaps_v0: - return vc_get_ccaps_v0(id, data); + return vc_get_ccaps_v0(vxi, data); /* this is version 1 */ case VCMD_get_ccaps: - return vc_get_ccaps(id, data); + return vc_get_ccaps(vxi, data); case VCMD_set_bcaps: - return vc_set_bcaps(id, data); + return vc_set_bcaps(vxi, data); case VCMD_get_bcaps: - return vc_get_bcaps(id, data); + return vc_get_bcaps(vxi, data); case VCMD_set_nflags: - return vc_set_nflags(id, data); + return vc_set_nflags(nxi, data); case VCMD_get_nflags: - return vc_get_nflags(id, data); + return vc_get_nflags(nxi, data); case VCMD_set_ncaps: - return vc_set_ncaps(id, data); + return vc_set_ncaps(nxi, data); case VCMD_get_ncaps: - return vc_get_ncaps(id, data); + return vc_get_ncaps(nxi, data); #ifdef CONFIG_VSERVER_LEGACY case VCMD_set_sched_v2: - return vc_set_sched_v2(id, data); + return vc_set_sched_v2(vxi, data); #endif case VCMD_set_sched_v3: - return vc_set_sched_v3(id, data); + return vc_set_sched_v3(vxi, data); /* this is version 4 */ case VCMD_set_sched: - return vc_set_sched(id, data); + return vc_set_sched(vxi, data); case VCMD_add_dlimit: return __COMPAT(vc_add_dlimit, id, data, compat); @@ -212,24 +164,16 @@ long do_vserver(uint32_t cmd, uint32_t i return __COMPAT(vc_set_dlimit, id, data, compat); case VCMD_get_dlimit: return __COMPAT(vc_get_dlimit, id, data, compat); - } - - /* below here only with VX_ADMIN */ - if (!vx_check(0, VX_ADMIN|VX_WATCH)) - return -EPERM; - switch (cmd) { case VCMD_ctx_kill: - return vc_ctx_kill(id, data); + return vc_ctx_kill(vxi, data); case VCMD_wait_exit: - return vc_wait_exit(id, data); + return vc_wait_exit(vxi, data); - case VCMD_create_context: #ifdef CONFIG_VSERVER_LEGACY + case VCMD_create_context: return vc_ctx_create(id, NULL); -#else - return -ENOSYS; #endif case VCMD_get_iattr: @@ -238,62 +182,273 @@ long do_vserver(uint32_t cmd, uint32_t i return __COMPAT(vc_set_iattr, id, data, compat); case VCMD_enter_namespace: - return vc_enter_namespace(id, data); + return vc_enter_namespace(vxi, data); case VCMD_ctx_create_v0: -#ifdef CONFIG_VSERVER_LEGACY - if (id == 1) { - current->xid = 1; - return 1; - } -#endif return vc_ctx_create(id, NULL); case VCMD_ctx_create: return vc_ctx_create(id, data); case VCMD_ctx_migrate_v0: - return vc_ctx_migrate(id, NULL); + return vc_ctx_migrate(vxi, NULL); case VCMD_ctx_migrate: - return vc_ctx_migrate(id, data); + return vc_ctx_migrate(vxi, data); case VCMD_net_create_v0: return vc_net_create(id, NULL); case VCMD_net_create: return vc_net_create(id, data); case VCMD_net_migrate: - return vc_net_migrate(id, data); + return vc_net_migrate(nxi, data); case VCMD_net_add: - return vc_net_add(id, data); + return vc_net_add(nxi, data); case VCMD_net_remove: - return vc_net_remove(id, data); + return vc_net_remove(nxi, data); +#ifdef CONFIG_VSERVER_HISTORY + case VCMD_dump_history: + return vc_dump_history(id); +#endif +#ifdef CONFIG_VSERVER_LEGACY + case VCMD_new_s_context: + return vc_new_s_context(id, data); +#endif +#ifdef CONFIG_VSERVER_LEGACYNET + case VCMD_set_ipv4root: + return vc_set_ipv4root(id, data); +#endif + default: + vxwprintk(1, "unimplemented VCMD_%02d_%d[%d]", + VC_CATEGORY(cmd), VC_COMMAND(cmd), VC_VERSION(cmd)); } return -ENOSYS; } -extern asmlinkage long -sys_vserver(uint32_t cmd, uint32_t id, void __user *data) + +#define __VCMD(vcmd, _perm, _args, _flags) \ + case VCMD_ ## vcmd: perm = _perm; \ + args = _args; flags = _flags; break + + +#define VCA_NONE 0x00 +#define VCA_VXI 0x01 +#define VCA_NXI 0x02 + +#define VCF_NONE 0x00 +#define VCF_INFO 0x01 +#define VCF_ADMIN 0x02 +#define VCF_ARES 0x06 /* includes admin */ +#define VCF_SETUP 0x08 + + +static inline +long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat) { - long ret = do_vserver(cmd, id, data, 0); + long ret; + int permit = -1, state = 0; + int perm = -1, args = 0, flags = 0; + struct vx_info *vxi = NULL; + struct nx_info *nxi = NULL; + + switch (cmd) { + /* unpriviledged commands */ + __VCMD(get_version, 0, VCA_NONE, 0); + __VCMD(get_vci, 0, VCA_NONE, 0); + __VCMD(get_rlimit_mask, 0, VCA_NONE, 0); + + /* info commands */ + __VCMD(task_xid, 2, VCA_NONE, 0); + __VCMD(reset_minmax, 2, VCA_VXI, 0); + __VCMD(vx_info, 3, VCA_VXI, VCF_INFO); + __VCMD(get_bcaps, 3, VCA_VXI, VCF_INFO); + __VCMD(get_ccaps_v0, 3, VCA_VXI, VCF_INFO); + __VCMD(get_ccaps, 3, VCA_VXI, VCF_INFO); + __VCMD(get_cflags, 3, VCA_VXI, VCF_INFO); + __VCMD(get_vhi_name, 3, VCA_VXI, VCF_INFO); + __VCMD(get_rlimit, 3, VCA_VXI, VCF_INFO); + + __VCMD(task_nid, 2, VCA_NONE, 0); + __VCMD(nx_info, 3, VCA_NXI, VCF_INFO); + __VCMD(get_ncaps, 3, VCA_NXI, VCF_INFO); + __VCMD(get_nflags, 3, VCA_NXI, VCF_INFO); + + __VCMD(get_iattr, 2, VCA_NONE, 0); + __VCMD(get_dlimit, 3, VCA_NONE, VCF_INFO); + + /* lower admin commands */ + __VCMD(wait_exit, 4, VCA_VXI, VCF_ADMIN); + __VCMD(ctx_create_v0, 5, VCA_NONE, 0); + __VCMD(ctx_create, 5, VCA_NONE, 0); + __VCMD(ctx_migrate_v0, 5, VCA_VXI, VCF_ADMIN); + __VCMD(ctx_migrate, 5, VCA_VXI, VCF_ADMIN); + __VCMD(enter_namespace, 5, VCA_VXI, VCF_ADMIN); + + __VCMD(net_create_v0, 5, VCA_NONE, 0); + __VCMD(net_create, 5, VCA_NONE, 0); + __VCMD(net_migrate, 5, VCA_NXI, VCF_ADMIN); + + /* higher admin commands */ + __VCMD(ctx_kill, 6, VCA_VXI, VCF_ARES); + __VCMD(set_namespace_v0, 7, VCA_VXI, VCF_ARES|VCF_SETUP); + __VCMD(set_namespace, 7, VCA_VXI, VCF_ARES|VCF_SETUP); + + __VCMD(set_ccaps_v0, 7, VCA_VXI, VCF_ARES|VCF_SETUP); + __VCMD(set_ccaps, 7, VCA_VXI, VCF_ARES|VCF_SETUP); + __VCMD(set_bcaps, 7, VCA_VXI, VCF_ARES|VCF_SETUP); + __VCMD(set_cflags, 7, VCA_VXI, VCF_ARES|VCF_SETUP); + + __VCMD(set_vhi_name, 7, VCA_VXI, VCF_ARES|VCF_SETUP); + __VCMD(set_rlimit, 7, VCA_VXI, VCF_ARES|VCF_SETUP); + __VCMD(set_sched, 7, VCA_VXI, VCF_ARES|VCF_SETUP); + __VCMD(set_sched_v2, 7, VCA_VXI, VCF_ARES|VCF_SETUP); + __VCMD(set_sched_v3, 7, VCA_VXI, VCF_ARES|VCF_SETUP); + + __VCMD(set_ncaps, 7, VCA_NXI, VCF_ARES|VCF_SETUP); + __VCMD(set_nflags, 7, VCA_NXI, VCF_ARES|VCF_SETUP); + __VCMD(net_add, 8, VCA_NXI, VCF_ARES|VCF_SETUP); + __VCMD(net_remove, 8, VCA_NXI, VCF_ARES|VCF_SETUP); + + __VCMD(set_iattr, 7, VCA_NONE, 0); + __VCMD(set_dlimit, 7, VCA_NONE, VCF_ARES); + __VCMD(add_dlimit, 8, VCA_NONE, VCF_ARES); + __VCMD(rem_dlimit, 8, VCA_NONE, VCF_ARES); + + /* debug level admin commands */ +#ifdef CONFIG_VSERVER_HISTORY + __VCMD(dump_history, 9, VCA_NONE, 0); +#endif + + /* legacy commands */ +#ifdef CONFIG_VSERVER_LEGACY + __VCMD(create_context, 5, VCA_NONE, 0); + __VCMD(new_s_context, 5, VCA_NONE, 0); +#endif +#ifdef CONFIG_VSERVER_LEGACYNET + __VCMD(set_ipv4root, 5, VCA_NONE, 0); +#endif + default: + perm = -1; + } + + vxdprintk(VXD_CBIT(switch, 0), + "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]", + VC_CATEGORY(cmd), VC_COMMAND(cmd), + VC_VERSION(cmd), id, data, compat, + perm, args, flags); + + ret = -EPERM; + if (perm < 0) + goto out; + + state = 1; +#ifdef CONFIG_VSERVER_LEGACY + if (!capable(CAP_CONTEXT) && + /* dirty hack for capremove */ + !(cmd==VCMD_new_s_context && id==-2)) + goto out; +#else + if (!capable(CAP_CONTEXT)) + goto out; +#endif + + state = 2; + /* moved here from the individual commands */ + ret = -EPERM; + if ((perm > 1) && !capable(CAP_SYS_ADMIN)) + goto out; + + state = 3; + /* vcmd involves resource management */ + ret = -EPERM; + if ((flags & VCF_ARES) && !capable(CAP_SYS_RESOURCE)) + goto out; + + state = 4; + /* various legacy exceptions */ + switch (cmd) { +#ifdef CONFIG_VSERVER_LEGACY + case VCMD_set_cflags: + case VCMD_set_ccaps_v0: + ret = 0; + if (vx_check(0, VX_WATCH)) + goto out; + break; + + case VCMD_ctx_create_v0: +#endif + /* will go away when admin is a cap */ + case VCMD_ctx_migrate_v0: + case VCMD_ctx_migrate: + if (id == 1) { + current->xid = 1; + ret = 1; + goto out; + } + break; + + /* legacy special casing */ + case VCMD_set_namespace_v0: + id = -1; + break; + } + + /* vcmds are fine by default */ + permit = 1; + + /* admin type vcmds require admin ... */ + if (flags & VCF_ADMIN) + permit = vx_check(0, VX_ADMIN) ? 1 : 0; + + /* ... but setup type vcmds override that */ + if (!permit && (flags & VCF_SETUP)) + permit = vx_flags(VXF_STATE_SETUP, 0) ? 2 : 0; + + state = 5; + ret = -EPERM; + if (!permit) + goto out; + + state = 6; + ret = -ESRCH; + if (args & VCA_VXI) { + vxi = lookup_vx_info(id); + if (!vxi) + goto out; + } + state = 7; + if (args & VCA_NXI) { + nxi = lookup_nx_info(id); + if (!nxi) + goto out_vxi; + } + state = 8; + ret = do_vcmd(cmd, id, vxi, nxi, data, compat); + + if (args & VCA_NXI) + put_nx_info(nxi); +out_vxi: + if (args & VCA_VXI) + put_vx_info(vxi); +out: vxdprintk(VXD_CBIT(switch, 1), - "vc: VCMD_%02d_%d[%d] = %08lx(%ld)", + "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]", VC_CATEGORY(cmd), VC_COMMAND(cmd), - VC_VERSION(cmd), ret, ret); + VC_VERSION(cmd), ret, ret, state, permit); return ret; } +extern asmlinkage long +sys_vserver(uint32_t cmd, uint32_t id, void __user *data) +{ + return do_vserver(cmd, id, data, 0); +} + #ifdef CONFIG_COMPAT extern asmlinkage long sys32_vserver(uint32_t cmd, uint32_t id, void __user *data) { - long ret = do_vserver(cmd, id, data, 1); - - vxdprintk(VXD_CBIT(switch, 1), - "vc: VCMD_%02d_%d[%d] = %08lx(%ld)", - VC_CATEGORY(cmd), VC_COMMAND(cmd), - VC_VERSION(cmd), ret, ret); - return ret; + return do_vserver(cmd, id, data, 1); } #endif /* CONFIG_COMPAT */