diff -NurpP --minimal linux-2.6.38-rc2-vs2.3.0.37-rc2/include/linux/cred.h linux-2.6.38-rc2-vs2.3.0.37-rc2.1/include/linux/cred.h --- linux-2.6.38-rc2-vs2.3.0.37-rc2/include/linux/cred.h 2011-01-29 02:01:07.000000000 +0100 +++ linux-2.6.38-rc2-vs2.3.0.37-rc2.1/include/linux/cred.h 2011-01-31 12:03:07.000000000 +0100 @@ -155,6 +155,7 @@ extern void exit_creds(struct task_struc extern int copy_creds(struct task_struct *, unsigned long); extern const struct cred *get_task_cred(struct task_struct *); extern struct cred *cred_alloc_blank(void); +extern struct cred *__prepare_creds(const struct cred *); extern struct cred *prepare_creds(void); extern struct cred *prepare_exec_creds(void); extern int commit_creds(struct cred *); diff -NurpP --minimal linux-2.6.38-rc2-vs2.3.0.37-rc2/include/linux/vserver/context.h linux-2.6.38-rc2-vs2.3.0.37-rc2.1/include/linux/vserver/context.h --- linux-2.6.38-rc2-vs2.3.0.37-rc2/include/linux/vserver/context.h 2011-01-29 02:01:07.000000000 +0100 +++ linux-2.6.38-rc2-vs2.3.0.37-rc2.1/include/linux/vserver/context.h 2011-01-31 11:53:26.000000000 +0100 @@ -104,7 +104,7 @@ struct _vx_space { struct nsproxy *vx_nsproxy; /* private namespaces */ struct fs_struct *vx_fs; /* private namespace fs */ // const struct cred *vx_real_cred; /* real task credentials */ -// const struct cred *vx_cred; /* task credentials */ + const struct cred *vx_cred; /* task credentials */ }; struct vx_info { diff -NurpP --minimal linux-2.6.38-rc2-vs2.3.0.37-rc2/kernel/cred.c linux-2.6.38-rc2-vs2.3.0.37-rc2.1/kernel/cred.c --- linux-2.6.38-rc2-vs2.3.0.37-rc2/kernel/cred.c 2011-01-29 02:01:07.000000000 +0100 +++ linux-2.6.38-rc2-vs2.3.0.37-rc2.1/kernel/cred.c 2011-01-31 11:55:25.000000000 +0100 @@ -255,21 +255,16 @@ error: * * Call commit_creds() or abort_creds() to clean up. */ -struct cred *prepare_creds(void) +struct cred *__prepare_creds(const struct cred *old) { - struct task_struct *task = current; - const struct cred *old; struct cred *new; - validate_process_creds(); - new = kmem_cache_alloc(cred_jar, GFP_KERNEL); if (!new) return NULL; kdebug("prepare_creds() alloc %p", new); - old = task->cred; memcpy(new, old, sizeof(struct cred)); atomic_set(&new->usage, 1); @@ -296,6 +291,13 @@ error: abort_creds(new); return NULL; } + +struct cred *prepare_creds(void) +{ + validate_process_creds(); + + return __prepare_creds(current->cred); +} EXPORT_SYMBOL(prepare_creds); /* diff -NurpP --minimal linux-2.6.38-rc2-vs2.3.0.37-rc2/kernel/vserver/context.c linux-2.6.38-rc2-vs2.3.0.37-rc2.1/kernel/vserver/context.c --- linux-2.6.38-rc2-vs2.3.0.37-rc2/kernel/vserver/context.c 2011-01-29 02:01:07.000000000 +0100 +++ linux-2.6.38-rc2-vs2.3.0.37-rc2.1/kernel/vserver/context.c 2011-01-31 11:58:13.000000000 +0100 @@ -193,7 +193,7 @@ static void __shutdown_vx_info(struct vx { struct nsproxy *nsproxy; struct fs_struct *fs; - const struct cred *cred; + struct cred *cred; int index, kill; might_sleep(); @@ -221,12 +221,10 @@ static void __shutdown_vx_info(struct vx put_cred(cred); } - cred = xchg(&space->vx_cred, NULL); - if (cred) { - alter_cred_subscribers(cred, -1); - put_cred(cred); - } #endif + cred = (struct cred *)xchg(&space->vx_cred, NULL); + if (cred) + abort_creds(cred); } } diff -NurpP --minimal linux-2.6.38-rc2-vs2.3.0.37-rc2/kernel/vserver/space.c linux-2.6.38-rc2-vs2.3.0.37-rc2.1/kernel/vserver/space.c --- linux-2.6.38-rc2-vs2.3.0.37-rc2/kernel/vserver/space.c 2011-01-29 02:01:07.000000000 +0100 +++ linux-2.6.38-rc2-vs2.3.0.37-rc2.1/kernel/vserver/space.c 2011-01-31 11:59:17.000000000 +0100 @@ -248,6 +248,8 @@ int vx_enter_space(struct vx_info *vxi, proxy_new = xchg(¤t->nsproxy, proxy_new); if (mask & CLONE_NEWUSER) { + struct cred *cred; + vxdprintk(VXD_CBIT(space, 10), #if 1 "vx_enter_space(%p[#%u])", vxi, vxi->vx_id); @@ -259,9 +261,10 @@ int vx_enter_space(struct vx_info *vxi, exit_creds(current); current->real_cred = get_cred(space->vx_real_cred); alter_cred_subscribers(current->real_cred, 1); - current->cred = get_cred(space->vx_cred); - alter_cred_subscribers(current->cred, 1); #endif + cred = __prepare_creds(space->vx_cred); + if (cred) + commit_creds(cred); } ret = 0; @@ -328,7 +331,7 @@ int vx_set_space(struct vx_info *vxi, un space->vx_nsmask |= mask; if (mask & CLONE_NEWUSER) { - // const struct cred *cred; + struct cred *cred; vxdprintk(VXD_CBIT(space, 10), #if 1 @@ -350,17 +353,11 @@ int vx_set_space(struct vx_info *vxi, un put_cred(cred); } - if (current->cred) { - cred = get_cred(current->cred); - alter_cred_subscribers(cred, 1); - } else - cred = NULL; - cred = xchg(&space->vx_cred, cred); - if (cred) { - alter_cred_subscribers(cred, -1); - put_cred(cred); - } #endif + cred = prepare_creds(); + cred = (struct cred *)xchg(&space->vx_cred, cred); + if (cred) + abort_creds(cred); } ret = 0;