diff -NurpP linux-2.6.36-vs2.3.0.36.38/include/linux/cred.h linux-2.6.36-vs2.3.0.36.38.1/include/linux/cred.h --- linux-2.6.36-vs2.3.0.36.38/include/linux/cred.h 2010-08-02 16:52:53.000000000 +0200 +++ linux-2.6.36-vs2.3.0.36.38.1/include/linux/cred.h 2010-12-01 17:26:52.000000000 +0100 @@ -208,6 +208,31 @@ static inline void validate_process_cred } #endif +static inline void set_cred_subscribers(struct cred *cred, int n) +{ +#ifdef CONFIG_DEBUG_CREDENTIALS + atomic_set(&cred->subscribers, n); +#endif +} + +static inline int read_cred_subscribers(const struct cred *cred) +{ +#ifdef CONFIG_DEBUG_CREDENTIALS + return atomic_read(&cred->subscribers); +#else + return 0; +#endif +} + +static inline void alter_cred_subscribers(const struct cred *_cred, int n) +{ +#ifdef CONFIG_DEBUG_CREDENTIALS + struct cred *cred = (struct cred *) _cred; + + atomic_add(n, &cred->subscribers); +#endif +} + /** * get_new_cred - Get a reference on a new set of credentials * @cred: The new credentials to reference diff -NurpP linux-2.6.36-vs2.3.0.36.38/include/linux/vserver/context.h linux-2.6.36-vs2.3.0.36.38.1/include/linux/vserver/context.h --- linux-2.6.36-vs2.3.0.36.38/include/linux/vserver/context.h 2010-10-21 13:09:36.000000000 +0200 +++ linux-2.6.36-vs2.3.0.36.38.1/include/linux/vserver/context.h 2010-12-01 17:36:51.000000000 +0100 @@ -110,6 +110,8 @@ struct vx_info { unsigned long vx_nsmask[VX_SPACES]; /* assignment mask */ struct nsproxy *vx_nsproxy[VX_SPACES]; /* private namespaces */ struct fs_struct *vx_fs[VX_SPACES]; /* private namespace fs */ + const struct cred *vx_real_cred; /* real task credentials */ + const struct cred *vx_cred; /* task credentials */ uint64_t vx_flags; /* context flags */ uint64_t vx_ccaps; /* context caps (vserver) */ diff -NurpP linux-2.6.36-vs2.3.0.36.38/kernel/cred.c linux-2.6.36-vs2.3.0.36.38.1/kernel/cred.c --- linux-2.6.36-vs2.3.0.36.38/kernel/cred.c 2010-10-21 13:07:56.000000000 +0200 +++ linux-2.6.36-vs2.3.0.36.38.1/kernel/cred.c 2010-12-01 17:25:55.000000000 +0100 @@ -60,31 +60,6 @@ struct cred init_cred = { #endif }; -static inline void set_cred_subscribers(struct cred *cred, int n) -{ -#ifdef CONFIG_DEBUG_CREDENTIALS - atomic_set(&cred->subscribers, n); -#endif -} - -static inline int read_cred_subscribers(const struct cred *cred) -{ -#ifdef CONFIG_DEBUG_CREDENTIALS - return atomic_read(&cred->subscribers); -#else - return 0; -#endif -} - -static inline void alter_cred_subscribers(const struct cred *_cred, int n) -{ -#ifdef CONFIG_DEBUG_CREDENTIALS - struct cred *cred = (struct cred *) _cred; - - atomic_add(n, &cred->subscribers); -#endif -} - /* * Dispose of the shared task group credentials */ diff -NurpP linux-2.6.36-vs2.3.0.36.38/kernel/vserver/context.c linux-2.6.36-vs2.3.0.36.38.1/kernel/vserver/context.c --- linux-2.6.36-vs2.3.0.36.38/kernel/vserver/context.c 2010-10-21 14:39:59.000000000 +0200 +++ linux-2.6.36-vs2.3.0.36.38.1/kernel/vserver/context.c 2010-12-01 17:38:02.000000000 +0100 @@ -3,7 +3,7 @@ * * Virtual Server: Context Support * - * Copyright (C) 2003-2007 Herbert Pötzl + * Copyright (C) 2003-2010 Herbert Pötzl * * V0.01 context helper * V0.02 vx_ctx_kill syscall command @@ -22,6 +22,7 @@ * V0.15 added context stat * V0.16 have __create claim() the vxi * V0.17 removed older and legacy stuff + * V0.18 added user credentials * */ @@ -38,6 +39,7 @@ #include #include #include +#include #include #include @@ -127,6 +129,10 @@ static struct vx_info *__alloc_vx_info(x new->vx_fs[index] = &init_fs; } + /* FIXME: we want defaults */ + new->vx_real_cred = 0; + new->vx_cred = 0; + vxdprintk(VXD_CBIT(xid, 0), "alloc_vx_info(%d) = %p", xid, new); vxh_alloc_vx_info(new); @@ -183,6 +189,7 @@ static void __shutdown_vx_info(struct vx { struct nsproxy *nsproxy; struct fs_struct *fs; + const struct cred *cred; int index, kill; might_sleep(); @@ -202,6 +209,14 @@ static void __shutdown_vx_info(struct vx if (kill) free_fs_struct(fs); } + + cred = xchg(&vxi->vx_real_cred, NULL); + alter_cred_subscribers(cred, -1); + put_cred(cred); + + cred = xchg(&vxi->vx_cred, NULL); + alter_cred_subscribers(cred, -1); + put_cred(cred); } /* exported stuff */ diff -NurpP linux-2.6.36-vs2.3.0.36.38/kernel/vserver/space.c linux-2.6.36-vs2.3.0.36.38.1/kernel/vserver/space.c --- linux-2.6.36-vs2.3.0.36.38/kernel/vserver/space.c 2010-10-21 14:41:06.000000000 +0200 +++ linux-2.6.36-vs2.3.0.36.38.1/kernel/vserver/space.c 2010-12-01 17:35:11.000000000 +0100 @@ -3,12 +3,13 @@ * * Virtual Server: Context Space Support * - * Copyright (C) 2003-2007 Herbert Pötzl + * Copyright (C) 2003-2010 Herbert Pötzl * * V0.01 broken out from context.c 0.07 * V0.02 added task locking for namespace * V0.03 broken out vx_enter_namespace * V0.04 added *space support and commands + * V0.05 added credential support * */ @@ -16,6 +17,7 @@ #include #include #include +#include #include #include @@ -238,6 +240,19 @@ int vx_enter_space(struct vx_info *vxi, } proxy_new = xchg(¤t->nsproxy, proxy_new); + + if (mask & CLONE_NEWUSER) { + vxdprintk(VXD_CBIT(space, 10), + "vx_enter_space(%p[#%u],%p,%p) cred (%p,%p)", + vxi, vxi->vx_id, vxi->vx_real_cred, vxi->vx_cred, + current->real_cred, current->cred); + exit_creds(current); + current->real_cred = get_cred(vxi->vx_real_cred); + alter_cred_subscribers(current->real_cred, 1); + current->cred = get_cred(vxi->vx_cred); + alter_cred_subscribers(current->cred, 1); + } + ret = 0; if (proxy_new) @@ -297,6 +312,28 @@ int vx_set_space(struct vx_info *vxi, un proxy_new = xchg(&vxi->vx_nsproxy[index], proxy_new); vxi->vx_nsmask[index] |= mask; + + if (mask & CLONE_NEWUSER) { + const struct cred *cred; + + vxdprintk(VXD_CBIT(space, 10), + "vx_set_space(%p[#%u],%p,%p) cred (%p,%p)", + vxi, vxi->vx_id, vxi->vx_real_cred, vxi->vx_cred, + current->real_cred, current->cred); + + cred = get_cred(current->real_cred); + alter_cred_subscribers(cred, 1); + cred = xchg(&vxi->vx_real_cred, cred); + alter_cred_subscribers(cred, -1); + put_cred(cred); + + cred = get_cred(current->cred); + alter_cred_subscribers(cred, 1); + cred = xchg(&vxi->vx_cred, cred); + alter_cred_subscribers(cred, -1); + put_cred(cred); + } + ret = 0; if (proxy_new)