cr: attempt at task userid restoration
Subsystems (2)
cover cr: attempt at task userid restoration
Here is a broken-out patchset representing a first stab at checkpoint and restoring task userids. As I note somewhere, I have more thinking to do about refcounting and I'm sure there are plenty of bugs. I'm sending this out to see if there are major objections to this general approach.
thanks,
-serge
A message that is not in the archive (sent off-list or not yet received): 20090511160424.GA12234-r/[email protected]
PATCH 1/5 cr: break out new_user_ns()
Break out the core function which checks privilege and (if allowed) creates a new user namespace, with the passed-in creating user_struct. Note that a user_namespace, unlike other namespace pointers, is not stored in the nsproxy. Rather it is purely a property of user_structs.
This will let us keep the task restore code simpler.
--- include/linux/user_namespace.h | 8 ++++++ kernel/user_namespace.c | 53 ++++++++++++++++++++++++++++------------ 2 files changed, 45 insertions(+), 16 deletions(-)
include/linux/user_namespace.h +8 -0
@@ -20,6 +20,8 @@ extern struct user_namespace init_user_ns;#ifdef CONFIG_USER_NS +struct user_namespace *new_user_ns (struct user_struct *creator, +struct user_struct **newroot);static inline struct user_namespace *get_user_ns (struct user_namespace *ns) {if (ns)
@@ -38,6 +40,12 @@ static inline void put_user_ns(struct user_namespace *ns)#else +static inline struct user_namespace *new_user_ns (struct user_struct *creator, +struct user_struct **newroot) +{ +return -EINVAL ; +} +static inline struct user_namespace *get_user_ns (struct user_namespace *ns) {return &init_user_ns;
kernel/user_namespace.c +37 -16
80 lines not on this page · raw message
Signature · 1 line
1.6.1
PATCH 2/5 cr: split core function out of some set*{u,g}id functions
In reply to a message not in the archiveWhen restarting tasks, we want to be able to change xuid and xgid in a struct cred, and do so with security checks. Break the core functionality of set{,fs,res}{u,g}id into cred_setX which performs the access checks based on current_cred(), but performs the requested change on a passed-in cred.
This will allow us to securely construct struct creds based on a checkpoint image, constrained by the caller's permissions, and apply them to the caller at the end of sys_restart().
--- include/linux/cred.h | 9 +++ kernel/cred.c | 143 +++++++++++++++++++++++++++++++++++++++++++ kernel/sys.c | 163 +++++++------------------------------------------ 3 files changed, 176 insertions(+), 139 deletions(-)
include/linux/cred.h +9 -0
@@ -20,6 +20,9 @@ struct user_struct;struct cred ;struct inode ; +/* defined in sys.c, used in cred_setresuid */ +extern int set_user (struct cred *new); +/* * COW Supplementary groups list */
@@ -343,4 +346,10 @@ do { \ *(_fsgid) = __cred->fsgid; \ } while(0) +int cred_setresuid(struct cred *new, uid_t ruid, uid_t euid, uid_t suid); +int cred_setresgid (struct cred *new,gid_t rgid,gid_t egid,gid_t sgid); +int cred_setfsuid (struct cred *new,uid_t uid,uid_t *old_fsuid); +int cred_setfsgid (struct cred *new,gid_t gid,gid_t *old_fsgid); +int cred_setuid (struct cred *new,uid_t uid); +#endif /* _LINUX_CRED_H */
kernel/cred.c +143 -0
146 lines not on this page · raw message
kernel/sys.c +24 -139
251 lines not on this page · raw message
Signature · 1 line
1.6.1
PATCH 3/5 cr: capabilities: define checkpoint and restore fns
In reply to a message not in the archiveAn application checkpoint image will store capability sets (and the bounding set) as __u64s. Define checkpoint and restart functions to translate between those and kernel_cap_t's.
Define a common function do_capset_tocred() which applies capability set changes to a passed-in struct cred.
The restore function uses do_capset_tocred() to apply the restored capabilities to the struct cred being crafted, subject to the current task's (task executing sys_restart()) permissions.
TODO: one day we'll want to c/r the securebits as well.
--- include/linux/capability.h | 5 ++ kernel/capability.c | 94 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 86 insertions(+), 13 deletions(-)
include/linux/capability.h +5 -0
@@ -536,6 +536,11 @@ extern const kernel_cap_t __cap_empty_set;extern const kernel_cap_t __cap_full_set;extern const kernel_cap_t __cap_init_eff_set; +extern void checkpoint_save_cap (__u64 *dest,kernel_cap_t src); +struct cred ; +extern int checkpoint_restore_cap (__u64 e,__u64 i,__u64 p,__u64 x, +struct cred *cred); +/** * has_capability - Determine if a task has a superior capability available * @t: The task in question
kernel/capability.c +81 -13
116 lines not on this page · raw message
Signature · 1 line
1.6.1
PATCH 4/5 cr: checkpoint and restore task credentials
In reply to a message not in the archiveThis patch adds the checkpointing and restart of credentials (uids, gids, and capabilities) to Oren's c/r patchset (on top of v14). It goes to great pains to re-use (and define when needed) common helpers, in order to make sure that as security code is modified, the cr code will be updated. Some of the helpers should still be moved (i.e. _creds() functions should be in kernel/cred.c).
When building the credentials for the restarted process, I
1. create a new struct cred as a copy of the running task's cred (using prepare_cred())
2. always authorize any changes to the new struct cred based on the permissions of current_cred() (not the current transient state of the new cred).
While this may mean that certain transient_cred1->transient_cred2 states are allowed which otherwise wouldn't be allowed, the fact remains that current_cred() is allowed to transition to transient_cred2.
The reconstructed creds are applied to the task at the very end of the sys_restart call. This ensures that any objects which need to be re-created (file, socket, etc) are re-created using the creds of the task calling sys_restart - preventing an unpriv user from creating a privileged object, and ensuring that a root task can restart a process which had started out privileged, created some privileged objects, then dropped its privilege.
With these patches, the root user can restart checkpoint images (created by either hallyn or root) of user hallyn's tasks, resulting in a program owned by hallyn.
Plenty of bugs to be found, no doubt.
TODO:
I'm pretty sure I've got some refcounting wrong. If a userns is created with refcount 1, then obj_new() incs the refcount, then ref is dropped at end of restart... that's good for an empty user_ns (creator of an active child user_ns). Does it mean that any non-empty user_ns will never drop to refcount 0? (restore_read_cred adds ref for the cred)
--- checkpoint/objhash.c | 119 ++++++++++- checkpoint/process.c | 459 +++++++++++++++++++++++++++++++++++++- include/linux/checkpoint.h | 11 + include/linux/checkpoint_hdr.h | 57 +++++ include/linux/checkpoint_types.h | 1 + 5 files changed, 644 insertions(+), 3 deletions(-)
checkpoint/objhash.c +118 -1
@@ -16,6 +16,7 @@#include <linux/file.h> #include <linux/sched.h> #include <linux/ipc_namespace.h> +#include <linux/user_namespace.h> #include <linux/checkpoint.h> #include <linux/checkpoint_hdr.h>
@@ -155,6 +156,71 @@ static int obj_ipc_ns_users(void *ptr)return atomic_read (&((struct ipc_namespace *) ptr)->count); } +static int obj_cred_grab (void *ptr) +{ +get_cred ((struct cred *) ptr); +return 0 ; +} + +static void obj_cred_drop (void *ptr) +{ +put_cred ((struct cred *) ptr); +} + +static int obj_cred_users (void *ptr) +{ +return atomic_read (&((struct cred *) ptr)->usage); +} + +static int obj_user_grab (void *ptr) +{ +struct user_struct *u = ptr; + (void )get_uid (u); +return 0 ; +} + +static void obj_user_drop (void *ptr) +{ +free_uid ((struct user_struct *) ptr); +} + +static int obj_user_users (void *ptr) +{ +return atomic_read (&((struct user_struct *) ptr)->__count); +} + +static int obj_userns_grab (void *ptr) +{ +get_user_ns ((struct user_namespace *) ptr); +return 0 ; +} + +static void obj_userns_drop (void *ptr) +{ +put_user_ns ((struct user_namespace *) ptr); +} + +static int obj_user_ns_users (void *ptr) +{ +return atomic_read (&((struct user_namespace *) ptr)->kref.refcount); +} + +static int obj_groupinfo_grab (void *ptr) +{ +get_group_info ((struct group_info *) ptr); +return 0 ; +} + +static void obj_groupinfo_drop (void *ptr) +{ +put_group_info ((struct group_info *) ptr); +} + +static int obj_groupinfo_users (void *ptr) +{ +return atomic_read (&((struct group_info *) ptr)->usage); +} +static struct ckpt_obj_ops ckpt_obj_ops[] = {/* ignored object */ {
@@ -221,6 +287,46 @@ static struct ckpt_obj_ops ckpt_obj_ops[] = { .checkpoint = checkpoint_bad, .restore = restore_bad, }, +/* user_ns object */ + { + .obj_name = "USER_NS", + .obj_type = CKPT_OBJ_USER_NS, + .ref_drop = obj_userns_drop, + .ref_grab = obj_userns_grab, + .ref_users = obj_user_ns_users, + .checkpoint = checkpoint_userns, + .restore = restore_userns, + }, + /* struct cred */ + { + .obj_name = "CRED", + .obj_type = CKPT_OBJ_CRED, + .ref_drop = obj_cred_drop, + .ref_grab = obj_cred_grab, + .ref_users = obj_cred_users, + .checkpoint = checkpoint_cred, + .restore = restore_cred, + }, + /* user object */ + { + .obj_name = "USER", + .obj_type = CKPT_OBJ_USER, + .ref_drop = obj_user_drop, + .ref_grab = obj_user_grab, + .ref_users = obj_user_users, + .checkpoint = checkpoint_user, + .restore = restore_user, + }, + /* struct groupinfo */ + { + .obj_name = "GROUPINFO", + .obj_type = CKPT_OBJ_GROUPINFO, + .ref_drop = obj_groupinfo_drop, + .ref_grab = obj_groupinfo_grab, + .ref_users = obj_groupinfo_users, + .checkpoint = checkpoint_groupinfo, + .restore = restore_groupinfo, + }, };
@@ -290,6 +396,18 @@ static struct ckpt_obj *obj_find_by_ptr(struct ckpt_ctx *ctx, void *ptr)return NULL ; } +/* +* look up an obj and return objref if in hash, else +* return 0. Used during checkpoint. +*/ +int obj_lookup_dontadd (struct ckpt_ctx *ctx,void *ptr) +{ +struct ckpt_obj *obj =obj_find_by_ptr (ctx, ptr); +if (obj) +return obj->objref; +return 0 ; +} +static struct ckpt_obj *obj_find_by_objref (struct ckpt_ctx *ctx,int objref) {struct hlist_head *h;
@@ -389,7 +507,6 @@ int ckpt_obj_lookup_add(struct ckpt_ctx *ctx, void *ptr, *first =0 ; } -ckpt_debug ("%s objref %d first %d\n" , ops->obj_name, objref, *first);return objref; }
checkpoint/process.c +457 -2
513 lines not on this page · raw message
include/linux/checkpoint.h +11 -0
@@ -53,6 +53,7 @@ extern void *ckpt_obj_fetch(struct ckpt_ctx *ctx, int objref, enum obj_type type);extern int ckpt_obj_lookup_add (struct ckpt_ctx *ctx,void *ptr,enum obj_type type,int *first); +extern int obj_lookup_dontadd (struct ckpt_ctx *ctx,void *ptr);extern void ckpt_obj_users_inc (struct ckpt_ctx *ctx,void *ptr,int increment);extern int ckpt_obj_insert (struct ckpt_ctx *ctx,void *ptr,int objref,enum obj_type type);
@@ -91,6 +92,16 @@ static inline int restore_ipc_ns(struct ckpt_ctx *ctx)extern int checkpoint_ipcns (struct ckpt_ctx *ctx,struct ipc_namespace *ipc_ns);extern int restore_ipcns (struct ckpt_ctx *ctx); +/* credentials */ +int checkpoint_groupinfo (struct ckpt_ctx *ctx,void *ptr); +int checkpoint_userns (struct ckpt_ctx *ctx,void *ptr); +int checkpoint_user (struct ckpt_ctx *ctx,void *ptr); +int checkpoint_cred (struct ckpt_ctx *ctx,void *ptr); +void *restore_groupinfo (struct ckpt_ctx *ctx); +void *restore_userns (struct ckpt_ctx *ctx); +void *restore_user (struct ckpt_ctx *ctx); +void *restore_cred (struct ckpt_ctx *ctx); +/* memory */ extern void ckpt_pgarr_free (struct ckpt_ctx *ctx);
include/linux/checkpoint_hdr.h +57 -0
79 lines not on this page · raw message
include/linux/checkpoint_types.h +1 -0
@@ -13,6 +13,7 @@#define CKPT_VERSION 1#define CHECKPOINT_SUBTREE 0x4 +#define RESTORE_CREATE_USERNS 0x8#ifdef __KERNEL__
Signature · 1 line
1.6.1
A message that is not in the archive (sent off-list or not yet received): 20090511160539.GD12286-r/[email protected]
PATCH 1/1 cr: child user namespace must grab ref to creator
This applies on top of yesterday's patchset.
thanks,
-serge
From f70a08dc6abdba372e1b3e1f25aadb919d07b171 Mon Sep 17 00:00:00 2001
From: Serge E. Hallyn <serue-r/[email protected]>
Date: Tue, 12 May 2009 08:17:34 -0400
Subject: [PATCH 1/1] cr: child user namespace must grab ref to creator
With this change plus Oren's proposed fix to obj_put() after obj_new() during restore_obj(), refcounting on user_ns and user_struct should be completely correct.
--- checkpoint/process.c | 24 +++--------------------- 1 files changed, 3 insertions(+), 21 deletions(-)
checkpoint/process.c +3 -21
@@ -569,27 +569,9 @@ static struct user_namespace *restore_read_userns(struct ckpt_ctx *ctx)if (IS_ERR (ns))return ns; -/* we need a way to keep track of the new_root just -* until we alloc the uid inthe userns which we -* actually want. Then we can do: -* if (uid == 0) -* new_user = new_root; -* else -* new_user = alloc_uid(ns, uid); -* free_uid(new_root); -* cred->user = new_user; -* This is because new_root is right now the only -* thing pinning the user_ns. -* BUT I don't think I can just add it to the -* objhash, bc then we use up an objref which we'll -* need for the next real objhash object, right? -* I suppose I could just add them to the top of -* the objref space :) (MAX_INT-1) -* -* For now, this code is just plain wrong bc it will -* leak the user_ns and its root_user when the task -* exits. But, a leak is better than an OOPS... -*/ +/* new_user_ns() doesn't bump creator's refcount */ +get_uid (creator); +return ns; }
Signature · 1 line
1.6.1
Re: [PATCH 4/5] cr: checkpoint and restore task credentials
In reply to a message not in the archiveQuoted 6 lines · Serge E. Hallyn
checkpoint/objhash.c +4
-0+#define CKPT_MAXGROUPS 15 +#define MAX_GROUPINFO_SIZE (sizeof(*h)+CKPT_MAXGROUPS*sizeof(gid_t)) +/* move this fn into kernel/sys.c next to group functions? */ +static int checkpoint_write_groupinfo(struct ckpt_ctx *ctx,
checkpoint/objhash.c
Quoted 10 lines
checkpoint/objhash.c +10
-0+ struct group_info *g) +{ +int ret, i, size; +struct ckpt_hdr_groupinfo *h; + +if (g->ngroups >CKPT_MAXGROUPS ) { +ckpt_debug ("Too many groups: %d (max is %d)\n" , + g->ngroups,CKPT_MAXGROUPS ); +return -E2BIG ; + }
Ooh, a hack :-)
Quoted 10 lines
checkpoint/objhash.c +10
-0+ size =sizeof (*h) + g->ngroups *sizeof (__u32); + h =ckpt_hdr_get_type (ctx, size,CKPT_HDR_GROUPINFO ); +if (!h) +return -ENOMEM ; + + h->ngroups = g->ngroups; +for (i =0 ; i < g->ngroups; i++) + h->groups[i] =GROUP_AT (g, i); + + ret =ckpt_write_obj (ctx, (struct ckpt_hdr *) h);
checkpoint/objhash.c
Quoted 10 lines
checkpoint/objhash.c +9
-0+ckpt_hdr_put (ctx, h); + +return ret; +} +/* +* write the user struct +* TODO keyring will need to be dumped +*/ +#define UNSAVED_NS_MAX 5
Another hack :-)
This is an invitation to discuss what to do with references to future, especially given that object image can be variable-size _and_ streamability on dump.
In case of user->user_ns->creator, we can avoid the issue and dump creator first.
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 4/5] cr: checkpoint and restore task credentials
Quoted 43 lines · Alexey Dobriyan
Quoted 6 lines · Serge E. Hallyn
checkpoint/objhash.c +4
-0+#define CKPT_MAXGROUPS 15 +#define MAX_GROUPINFO_SIZE (sizeof(*h)+CKPT_MAXGROUPS*sizeof(gid_t)) +/* move this fn into kernel/sys.c next to group functions? */ +static int checkpoint_write_groupinfo(struct ckpt_ctx *ctx,checkpoint/objhash.c
Quoted 10 lines
checkpoint/objhash.c +10
-0+ struct group_info *g) +{ +int ret, i, size; +struct ckpt_hdr_groupinfo *h; + +if (g->ngroups >CKPT_MAXGROUPS ) { +ckpt_debug ("Too many groups: %d (max is %d)\n" , + g->ngroups,CKPT_MAXGROUPS ); +return -E2BIG ; + }Ooh, a hack :-)
Quoted 10 lines
checkpoint/objhash.c +10
-0+ size =sizeof (*h) + g->ngroups *sizeof (__u32); + h =ckpt_hdr_get_type (ctx, size,CKPT_HDR_GROUPINFO ); +if (!h) +return -ENOMEM ; + + h->ngroups = g->ngroups; +for (i =0 ; i < g->ngroups; i++) + h->groups[i] =GROUP_AT (g, i); + + ret =ckpt_write_obj (ctx, (struct ckpt_hdr *) h);checkpoint/objhash.c
Quoted 10 lines
checkpoint/objhash.c +9
-0+ckpt_hdr_put (ctx, h); + +return ret; +} +/* +* write the user struct +* TODO keyring will need to be dumped +*/ +#define UNSAVED_NS_MAX 5Another hack :-)
Quoted 6 lines
This is an invitation to discuss what to do with references to future, especially given that object image can be variable-size _and_ streamability on dump.
In case of
user->user_ns->creator, we can avoid the issue and dump creator first.
Aieee, user_ns are also hierarchical and ->creator points to outside of hierarchy.
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 4/5] cr: checkpoint and restore task credentials
Quoted 48 lines · Alexey Dobriyan
Quoted 47 lines · Alexey Dobriyan
Quoted 6 lines · Serge E. Hallyn
checkpoint/objhash.c +4
-0+#define CKPT_MAXGROUPS 15 +#define MAX_GROUPINFO_SIZE (sizeof(*h)+CKPT_MAXGROUPS*sizeof(gid_t)) +/* move this fn into kernel/sys.c next to group functions? */ +static int checkpoint_write_groupinfo(struct ckpt_ctx *ctx,checkpoint/objhash.c
Quoted 10 lines
checkpoint/objhash.c +10
-0+ struct group_info *g) +{ +int ret, i, size; +struct ckpt_hdr_groupinfo *h; + +if (g->ngroups >CKPT_MAXGROUPS ) { +ckpt_debug ("Too many groups: %d (max is %d)\n" , + g->ngroups,CKPT_MAXGROUPS ); +return -E2BIG ; + }Ooh, a hack :-)
Quoted 10 lines
checkpoint/objhash.c +10
-0+ size =sizeof (*h) + g->ngroups *sizeof (__u32); + h =ckpt_hdr_get_type (ctx, size,CKPT_HDR_GROUPINFO ); +if (!h) +return -ENOMEM ; + + h->ngroups = g->ngroups; +for (i =0 ; i < g->ngroups; i++) + h->groups[i] =GROUP_AT (g, i); + + ret =ckpt_write_obj (ctx, (struct ckpt_hdr *) h);checkpoint/objhash.c
Quoted 10 lines
checkpoint/objhash.c +9
-0+ckpt_hdr_put (ctx, h); + +return ret; +} +/* +* write the user struct +* TODO keyring will need to be dumped +*/ +#define UNSAVED_NS_MAX 5Another hack :-)
This is an invitation to discuss what to do with references to future, especially given that object image can be variable-size _and_ streamability on dump.
Quoted 5 lines
Quoted 2 lines
In case of
user->user_ns->creator, we can avoid the issue and dump creator first.Aieee,
user_nsare also hierarchical and ->creator points to outside of hierarchy.
We don't checkpoint the final, top-most creator, the one which created the user namespace in which the top checkpointed task belongs. Instead we mark the user_ns as 'CKPT_USERNS_INIT'. So every user_struct and user_ns which we checkpoint will be in or under that namespace.
-serge
Re: [PATCH 4/5] cr: checkpoint and restore task credentials
In reply to a message not in the archiveQuoted 11 lines · Alexey Dobriyan
Quoted 10 lines · Serge E. Hallyn
checkpoint/objhash.c +8
-0+#define CKPT_MAXGROUPS 15 +#define MAX_GROUPINFO_SIZE (sizeof(*h)+CKPT_MAXGROUPS*sizeof(gid_t)) +/* move this fn into kernel/sys.c next to group functions? */ +static int checkpoint_write_groupinfo (struct ckpt_ctx *ctx, +struct group_info *g) +{ +int ret, i, size; +struct ckpt_hdr_groupinfo *h;
Quoted 8 lines
checkpoint/objhash.c
Quoted 6 lines
checkpoint/objhash.c +6
-0+ +if (g->ngroups >CKPT_MAXGROUPS ) { +ckpt_debug ("Too many groups: %d (max is %d)\n" , + g->ngroups,CKPT_MAXGROUPS ); +return -E2BIG ; + }Ooh, a hack :-)
Yup - actually I originally only had this at restart, and we must have it there to protect from malicious checkpoint images.
I copied it into the restart code during a cleanup phase, and I probably shouldn't have.
Quoted 23 lines
Quoted 10 lines
checkpoint/objhash.c +10
-0+ size =sizeof (*h) + g->ngroups *sizeof (__u32); + h =ckpt_hdr_get_type (ctx, size,CKPT_HDR_GROUPINFO ); +if (!h) +return -ENOMEM ; + + h->ngroups = g->ngroups; +for (i =0 ; i < g->ngroups; i++) + h->groups[i] =GROUP_AT (g, i); + + ret =ckpt_write_obj (ctx, (struct ckpt_hdr *) h);checkpoint/objhash.c
Quoted 10 lines
checkpoint/objhash.c +9
-0+ckpt_hdr_put (ctx, h); + +return ret; +} +/* +* write the user struct +* TODO keyring will need to be dumped +*/ +#define UNSAVED_NS_MAX 5Another hack :-)
Quoted 6 lines
This is an invitation to discuss what to do with references to future, especially given that object image can be variable-size _and_ streamability on dump.
In case of
user->user_ns->creator, we can avoid the issue and dump creator first.
In fact I do dump the creator first. Note first that this '5' is not just for 5 levels of (user->user_ns)->(creator->user_ns)->..., but for 5 such levels where there are no tasks in any of the intermediate user namespaces. So a task did a
1. T1: T2=clone(CLONE_NEWNS) 2. T1: exit T2: T3=clone(CLONE_NEWNS) 3. T2: exit T3: T4=clone(CLONE_NEWNS) 4. T3: exit T4: t5=clone(CLONE_NEWNS)
As with groups, I think I agree with you that we don't need such a limit at checkpoint time. But we need some kind of sanity check at restart time. How about 5000?
thanks,
-serge
PATCH 5/5 cr: restore file->f_cred
In reply to a message not in the archiveOny seems useful if you're using coda or hppfs, but go ahead and restore a file's f_cred. This is set to the cred of the task doing the open, so often it will be the same as that of the restarted task.
--- checkpoint/files.c | 16 ++++++++++++++-- include/linux/checkpoint_hdr.h | 1 + 2 files changed, 15 insertions(+), 2 deletions(-)
checkpoint/files.c +14 -2
@@ -151,7 +151,11 @@ int checkpoint_file_common(struct ckpt_ctx *ctx, struct file *file, h->f_pos = file->f_pos; h->f_version = file->f_version; -/* FIX: need also file->uid, file->gid, file->f_owner, etc */ + h->f_credref =checkpoint_obj (ctx, file->f_cred,CKPT_OBJ_CRED ); +if (h->f_credref <0 ) +return h->f_credref; + +/* FIX: need also file->f_owner, etc */ return 0 ; }
@@ -359,8 +363,16 @@ int restore_file_common(struct ckpt_ctx *ctx, struct file *file, struct ckpt_hdr_file *h) {int ret; +struct cred *cred; + +/* FIX: need to restore owner etc */ -/* FIX: need to restore uid, gid, owner etc */ +/* restore the cred */ + cred =ckpt_obj_fetch (ctx, h->f_credref,CKPT_OBJ_CRED ); +if (IS_ERR (cred)) +return PTR_ERR (cred); +put_cred (file->f_cred); + file->f_cred =get_cred (cred);/* safe to set 1st arg (fd) to 0, as command is F_SETFL */ ret =vfs_fcntl (0 ,F_SETFL , h->f_flags &CKPT_SETFL_MASK , file);
include/linux/checkpoint_hdr.h +1 -0
@@ -336,6 +336,7 @@ struct ckpt_hdr_file {__u32 _padding;__u64 f_pos;__u64 f_version; +__s32 f_credref; } __attribute__((aligned(8)));struct ckpt_hdr_file_generic {
Signature · 1 line
1.6.1
A message that is not in the archive (sent off-list or not yet received): 20090511160512.GB12286-r/[email protected]
Re: [PATCH 2/5] cr: split core function out of some set*{u, g}id functions
Is cred_setuid() necessary given that cred_setresgid() exists?
David
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 2/5] cr: split core function out of some set*{u,g}id functions
Quoted 4 lines · David Howells
Is
cred_setuid()necessary given thatcred_setresgid()exists?David
Uh... yikes. Not only *should* it be unnecessary, but in the set I sent out I don't actually use cred_setuid() anymore.
Will pull that out of the set, thanks.
-serge