credentials c/r: Introduction
Subsystems (3)
cover credentials c/r: Introduction
This is the next, hopefully final, version of the patchset to start supporting credentials in Oren's c/r set. It addresses feedback by Alexey, is ported on top of v16, supports c/r of securebits, and adds support for credentials on ipc objects.
Next I intend to support the LSM ->security field on tasks, files, and ipc objects.
thanks,
-serge
PATCH 1/9 cred: #include init.h in cred.h
cred.h can't be included as first header because it uses __init and doesn't include init.h which is enough to break compilation on at least ia64.
--- include/linux/cred.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
include/linux/cred.h +1 -0
@@ -13,6 +13,7 @@#define _LINUX_CRED_H#include <linux/capability.h> +#include <linux/init.h> #include <linux/key.h> #include <asm/atomic.h>
Signature · 1 line
1.6.1
PATCH 2/9 groups: move code to kernel/groups.c
In reply to Serge E. HallynMove supplementary groups implementation to kernel/groups.c . kernel/sys.c already accumulated quite a few random stuff.
Do strictly copy/paste + add required headers to compile. Compile-tested on many configs and archs.
--- kernel/Makefile | 1 + kernel/groups.c | 288 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/sys.c | 283 ------------------------------------------------------ 3 files changed, 289 insertions(+), 283 deletions(-) create mode 100644 kernel/groups.c
kernel/Makefile +1 -0
@@ -11,6 +11,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o \ hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \ async.o +obj-y += groups.o ifdef CONFIG_FUNCTION_TRACER # Do not trace debug files and internal ftrace files
kernel/groups.c new file +288 -0
288 lines not on this page · raw message
kernel/sys.c +0 -283
289 lines not on this page · raw message
Signature · 1 line
1.6.1
PATCH 3/9 cr: break out new_user_ns()
In reply to Serge E. HallynBreak 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 4/9 cr: split core function out of some set*{u,g}id functions
In reply to Serge E. HallynWhen 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 | 8 +++ kernel/cred.c | 114 ++++++++++++++++++++++++++++++++++++++++++ kernel/sys.c | 134 ++++++++------------------------------------------ 3 files changed, 143 insertions(+), 113 deletions(-)
include/linux/cred.h +8 -0
@@ -21,6 +21,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 */
@@ -344,4 +347,9 @@ 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); +#endif /* _LINUX_CRED_H */
kernel/cred.c +114 -0
117 lines not on this page · raw message
kernel/sys.c +21 -113
210 lines not on this page · raw message
Signature · 1 line
1.6.1
PATCH 5/9 cr: capabilities: define checkpoint and restore fns
In reply to Serge E. HallynAn 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.
Changelog:
May 28: add helpers to c/r securebits
--- include/linux/capability.h | 7 +++ kernel/capability.c | 94 +++++++++++++++++++++++++++++++++++++------ security/commoncap.c | 51 ++++++++++++++++-------- 3 files changed, 122 insertions(+), 30 deletions(-)
include/linux/capability.h +7 -0
@@ -536,6 +536,13 @@ 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); +extern void checkpoint_save_securebits (unsigned *,unsigned ); +extern int checkpoint_restore_securebits (unsigned ,struct 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
security/commoncap.c +34 -17
70 lines not on this page · raw message
Signature · 1 line
1.6.1
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
Serge,
I'm not sure I'm too happy with hard coding the 64-bitness of capability sets. It may well be a very long time before we increase their size, but couldn't you prepare for that with some reference to the prevailing magic numbers for the current ABI representation?
Also, the use of 'error' as both a variable and a goto destination looks a little confusing.
Cheers
Andrew
Quoted 242 lines · Serge E. Hallyn
An 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 executingsys_restart()) permissions.Changelog:
May 28: add helpers to c/r securebitsSigned-off-by Serge E. Hallyn <[email protected]>---
include/linux/capability.h | 7 +++
kernel/capability.c | 94 +++++++++++++++++++++++++++++++++++++------security/commoncap.c| 51 ++++++++++++++++--------3 files changed, 122 insertions(+), 30 deletions(-)include/linux/capability.h +7
-0@@ -536,6 +536,13 @@ 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); +extern void checkpoint_save_securebits (unsigned *,unsigned ); +extern int checkpoint_restore_securebits (unsigned ,struct cred *); + /*** has_capability - Determine if a task has a superior capability available * @t: The task in question kernel/capability.c +81
-13@@ -217,6 +217,45 @@ SYSCALL_DEFINE2(capget, cap_user_header_t, header, cap_user_data_t, dataptr) return ret; } +static int do_capset_tocred (kernel_cap_t *effective,kernel_cap_t *inheritable, + kernel_cap_t *permitted, struct cred *new) +{ + int ret; + + ret = security_capset(new, current_cred(), + effective, inheritable, permitted); + if (ret < 0) + return ret; + + /* + * for checkpoint-restart, do we want to wait until end of restart? + * not sure we care */ + audit_log_capset(current->pid, new, current_cred()); + + return 0; +} + +static int do_capset (kernel_cap_t *effective,kernel_cap_t *inheritable, + kernel_cap_t *permitted) +{ + struct cred *new; + int ret; + + new = prepare_creds(); + if (!new) + return -ENOMEM; + + ret = do_capset_tocred(effective, inheritable, permitted, new); + if (ret < 0) + goto error; + + return commit_creds(new); + +error: + abort_creds(new); + return ret; +} + /*** sys_capset - set capabilities for a process or (*) a group of processes * @header: pointer to struct that contains capability version and @@ -240,7 +279,6 @@ SYSCALL_DEFINE2(capset, cap_user_header_t, header, const cap_user_data_t, data) struct __user_cap_data_struct kdata[_KERNEL_CAPABILITY_U32S]; unsigned i, tocopy; kernel_cap_t inheritable, permitted, effective; - struct cred *new; int ret; pid_t pid;@@ -271,22 +309,52 @@ SYSCALL_DEFINE2(capset, cap_user_header_t, header, const cap_user_data_t, data) i++; } - new = prepare_creds(); - if (!new) - return -ENOMEM; + return do_capset(&effective, &inheritable, &permitted); - ret = security_capset(new, current_cred(), - &effective, &inheritable, &permitted); - if (ret < 0) - goto error; +} - audit_log_capset(pid, new, current_cred()); - return commit_creds(new); +void checkpoint_save_cap (__u64 *dest,kernel_cap_t src) +{ + *dest = src.cap[0] | (src.cap[1] << sizeof(__u32)); +} -error: - abort_creds(new); - return ret; +static void do_capbset_drop (struct cred *cred,int cap) +{ + cap_lower(cred->cap_bset, cap); +} + +int checkpoint_restore_cap (__u64 newe,__u64 newi,__u64 newp,__u64 newx, + struct cred *cred) +{ + kernel_cap_t effective, inheritable, permitted, bset; + int may_dropbcap = capable(CAP_SETPCAP); + int ret, i; + + effective.cap[0] = newe; + effective.cap[1] = (newe >> sizeof(__u32)); + inheritable.cap[0] = newi; + inheritable.cap[1] = (newi >> sizeof(__u32)); + permitted.cap[0] = newp; + permitted.cap[1] = (newp >> sizeof(__u32)); + bset.cap[0] = newx; + bset.cap[1] = (newx >> sizeof(__u32)); + + ret = do_capset_tocred(&effective, &inheritable, &permitted, cred); + if (ret < 0) + return ret; + + for (i = 0; i < CAP_LAST_CAP; i++) { + if (cap_raised(bset, i)) + continue; + if (!cap_raised(current_cred()->cap_bset, i)) + continue; + if (!may_dropbcap) + return -EPERM; + do_capbset_drop(cred, i); + } + + return 0; } /**security/commoncap.c +22
-0@@ -804,6 +804,28 @@ int cap_task_setnice (struct task_struct *p, int nice) } #endif +int cap_set_securebits (struct cred *new,unsigned securebits) +{ + if ((((new->securebits & SECURE_ALL_LOCKS) >> 1) + & (new->securebits ^ securebits)) /*[1]*/ + || ((new->securebits & SECURE_ALL_LOCKS & ~securebits)) /*[2]*/ + || (securebits & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ + || (cap_capable(current, current_cred(), CAP_SETPCAP, + SECURITY_CAP_AUDIT) != 0) /*[4]*/ + /* + * [1] no changing of bits that are locked + * [2] no unlocking of locks + * [3] no setting of unsupported bits + * [4] doing anything requires privilege (go read about + * the "sendmail capabilities bug") + */ + ) + /* cannot change a locked bit */ + return -EPERM; + new->securebits = securebits; + return 0; +} + /*** cap_task_prctl - Implement process control functions for this security module * @option: The process control function requested @@ -861,24 +883,9 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,* capability-based-privilege environment. */ case
PR_SET_SECUREBITS:
- error =-EPERM;
- if ((((new->securebits&SECURE_ALL_LOCKS) >> 1)
- & (new->securebits^ arg2)) /*[1]*/- || ((new->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/ - || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ - || (cap_capable(current, current_cred(), CAP_SETPCAP,-
SECURITY_CAP_AUDIT) != 0) /*[4]*/
- /*
- * [1] no changing of bits that are locked
- * [2] no unlocking of locks
- * [3] no setting of unsupported bits
- * [4] doing anything requires privilege (go read about
- * the "sendmail capabilities bug")
- */
- )
- /* cannot change a locked bit */
+ error =cap_set_securebits(new, arg2);
+ if (error)
goto error;
-new->securebits= arg2;
goto changed;case
PR_GET_SECUREBITS:security/commoncap.c +10
-1@@ -921,6 +928,16 @@ error: return error; } +void checkpoint_save_securebits (unsigned *b,unsigned cred_securebits) +{ + *b = cred_securebits; +} + +int checkpoint_restore_securebits (unsigned b,struct cred *cred) +{ + return cap_set_securebits(cred, b); +} + /*** cap_syslog - Determine whether syslog function is permitted * @type: Function requested -- 1.6.1
Quoted 5 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
Quoted 4 lines · Andrew G. Morgan
I'm not sure I'm too happy with hard coding the 64-bitness of capability sets. It may well be a very long time before we increase their size, but couldn't you prepare for that with some reference to the prevailing magic numbers for the current ABI representation?
Yes, please, use BUILD_BUG_ON or something
Serge E. Hallyn
maintainerRe: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
In reply to Andrew G. MorganQuoted 6 lines · Andrew G. Morgan
Serge,
I'm not sure I'm too happy with hard coding the 64-bitness of capability sets. It may well be a very long time before we increase their size, but couldn't you prepare for that with some reference to the prevailing magic numbers for the current ABI representation?
Hmm, ok. I figured since the c/r code was in capability.h it would be obvious that going past 64-bit would mean a new checkpoint image format. I can see where that's silly...
I'll put in a commented BUILD_BUG_ON like Alexey suggests - does that suffice?
Quoted 2 lines
Also, the use of 'error' as both a variable and a goto destination looks a little confusing.
Ok will change.
Did you see any problems with the way I authorize a task's resetting of capabilities at sys_restart()?
thanks,
-serge
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
Quoted 9 lines · Serge E. Hallyn
Quoted 6 lines · Andrew G. Morgan
Serge,
I'm not sure I'm too happy with hard coding the 64-bitness of capability sets. It may well be a very long time before we increase their size, but couldn't you prepare for that with some reference to the prevailing magic numbers for the current ABI representation?
Quoted 6 lines
Hmm, ok. I figured since the c/r code was in
capability.hit would be obvious that going past 64-bit would mean a new checkpoint image format. I can see where that's silly...I'll put in a commented
BUILD_BUG_ONlike Alexey suggests - does that suffice?
I guess I'm not really well up on what the plans are for checkpoint images. Is there some sort of version control/signature/checksum to protect a kernel from loading an image that has been hacked to modify the privilege it was running with when the checkpoint was created?
Quoted 7 lines
Quoted 2 lines
Also, the use of 'error' as both a variable and a goto destination looks a little confusing.
Ok will change.
Did you see any problems with the way I authorize a task's resetting of capabilities at
sys_restart()?
[See above.] Is there a mailing list or something I can lurk on to get up to speed on what is being intended?
Thanks
Andrew
Quoted 7 lines
thanks,
-serge
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
Quoted 14 lines · Andrew G. Morgan
Quoted 13 lines · Serge E. Hallyn
Quoted 6 lines · Andrew G. Morgan
Serge,
I'm not sure I'm too happy with hard coding the 64-bitness of capability sets. It may well be a very long time before we increase their size, but couldn't you prepare for that with some reference to the prevailing magic numbers for the current ABI representation?
Hmm, ok. I figured since the c/r code was in
capability.hit would be obvious that going past 64-bit would mean a new checkpoint image format. I can see where that's silly...
Quoted 7 lines
Quoted 2 lines
I'll put in a commented
BUILD_BUG_ONlike Alexey suggests - does that suffice?I guess I'm not really well up on what the plans are for checkpoint images. Is there some sort of version control/signature/checksum to protect a kernel from loading an image that has been hacked to modify the privilege it was running with when the checkpoint was created?
No. One day we expect there will be TPM-signing of checkpoint images, but that will be up to userspace to properly exploit. So if userspace wants to enforce a certain flow control to prevent an unprivileged user from modifying a checkpoint image (which of course it does), then it should set up DAC and/or MAC to enforce that.
Quoted 10 lines
Quoted 7 lines
Quoted 2 lines
Also, the use of 'error' as both a variable and a goto destination looks a little confusing.
Ok will change.
Did you see any problems with the way I authorize a task's resetting of capabilities at
sys_restart()?[See above.] Is there a mailing list or something I can lurk on to get up to speed on what is being intended?
It mainly gets discussed on the containers list
(https://lists.linux-foundation.org/mailman/listinfo/containers) and on freenode/#lxcontainers.
thanks,
-serge
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
Quoted 2 lines · Serge E. Hallyn
Quoted 2 lines
Quoted 2 lines
I'll put in a commented
BUILD_BUG_ONlike Alexey suggests - does that suffice?
I can't speak for other subsystems, but it seems to me as if for the capabilities, I'd want to create something like this in include/linux/capabilities.h
typedef struct checkpoint_caps_s {
/* what goes in here is the capability code's business */
} checkpoint_caps_t;
and then have a kernel-internal callable:
caps_checkpoint_save(&caps_storage); caps_checkpoint_restore(&caps_storage);
kind if API. That way, the maintainer of the subsystem state gets to make sure that the right things are saved/restored/sanity checked. Breaking things out explicitly in "struct ckpt_hdr_cred" looks like it will complicate the distribution of knowledge about what's going on throughout the kernel.
Cheers
Andrew
Quoted 11 lines
Quoted 5 lines
I guess I'm not really well up on what the plans are for checkpoint images. Is there some sort of version control/signature/checksum to protect a kernel from loading an image that has been hacked to modify the privilege it was running with when the checkpoint was created?
No. One day we expect there will be TPM-signing of checkpoint images, but that will be up to userspace to properly exploit. So if userspace wants to enforce a certain flow control to prevent an unprivileged user from modifying a checkpoint image (which of course it does), then it should set up DAC and/or MAC to enforce that.
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
Quoted 11 lines · Andrew G. Morgan
Quoted 2 lines · Serge E. Hallyn
Quoted 2 lines
Quoted 2 lines
I'll put in a commented
BUILD_BUG_ONlike Alexey suggests - does that suffice?I can't speak for other subsystems, but it seems to me as if for the capabilities, I'd want to create something like this in
include/linux/capabilities.htypedef struct checkpoint_caps_s { /* what goes in here is the capability code's business */ } checkpoint_caps_t;
Sigh - Did a patch this way, but the problem is userspace needs to be able to parse the checkpoint image, so it needs to know what this struct looks like. So if I put it the struct definition include/linux/capability.h, I run into a whole new set of problems trying to compile a userspace program to do a sys_restart().
So I went part-way to what you suggested in the patchset I'm about to send out (please see patch 6/8). I think the caps code does look nicer in this new version.
thanks,
-serge
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
Quoted 13 lines · Serge E. Hallyn
Quoted 11 lines · Andrew G. Morgan
Quoted 2 lines · Serge E. Hallyn
Quoted 2 lines
Quoted 2 lines
I'll put in a commented
BUILD_BUG_ONlike Alexey suggests - does that suffice?I can't speak for other subsystems, but it seems to me as if for the capabilities, I'd want to create something like this in
include/linux/capabilities.htypedef struct
checkpoint_caps_s{
/* what goes in here is the capability code's business */ }checkpoint_caps_t;
Quoted 5 lines
Sigh - Did a patch this way, but the problem is userspace needs to be able to parse the checkpoint image, so it needs to know what this struct looks like. So if I put it the struct definition
include/linux/capability.h, I run into a whole new set of problems trying to compile a userspace program to do asys_restart().
Does the user space app need to be able to modify the data in some way? It seems like embedding a length with the structure or something might simplify such a user space dependency.
Quoted 3 lines
So I went part-way to what you suggested in the patchset I'm about to send out (please see patch 6/8). I think the caps code does look nicer in this new version.
Better, but I remain concerned that the code looks hard to maintain when structured this way.
Cheers
Andrew
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
Quoted 20 lines · Andrew G. Morgan
Quoted 13 lines · Serge E. Hallyn
Quoted 11 lines · Andrew G. Morgan
Quoted 2 lines · Serge E. Hallyn
Quoted 2 lines
Quoted 2 lines
I'll put in a commented
BUILD_BUG_ONlike Alexey suggests - does that suffice?I can't speak for other subsystems, but it seems to me as if for the capabilities, I'd want to create something like this in
include/linux/capabilities.htypedef struct
checkpoint_caps_s{
/* what goes in here is the capability code's business */ }checkpoint_caps_t;Quoted 5 lines
Sigh - Did a patch this way, but the problem is userspace needs to be able to parse the checkpoint image, so it needs to know what this struct looks like. So if I put it the struct definition
include/linux/capability.h, I run into a whole new set of problems trying to compile a userspace program to do asys_restart().
Quoted 3 lines
Does the user space app need to be able to modify the data in some way? It seems like embedding a length with the structure or something might simplify such a user space dependency.
Hmm, I suppose I could do something like define struct ckpt_capabilities in capabilities.h, then in checkpoint_hdr.h do
struct ckpt_capabilities;
struct ckpt_cap_dummy {
__u64 dummies[9];
};struct ckpt_hdr_cred {
...
union {
struct ckpt_capabilities r;
struct ckpt_cap_dummy d;
} caps;
};with a BUILD_BUG_ON to ensure that sizeof(r)==sizeof(d). Ugly, but should suit everyone?
Quoted 6 lines
Quoted 3 lines
So I went part-way to what you suggested in the patchset I'm about to send out (please see patch 6/8). I think the caps code does look nicer in this new version.
Better, but I remain concerned that the code looks hard to maintain when structured this way.
Why exactly? Just having the struct defined in checkpoint_hdr.h? Or is there something else I'm unwittingly doing?
thanks,
-serge
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
Quoted 13 lines · Serge E. Hallyn
Quoted 12 lines · Andrew G. Morgan
Quoted 11 lines · Serge E. Hallyn
Quoted 10 lines · Andrew G. Morgan
Quoted 2 lines · Serge E. Hallyn
Quoted 2 lines
Quoted 2 lines
I'll put in a commented
BUILD_BUG_ONlike Alexey suggests - does that suffice?I can't speak for other subsystems, but it seems to me as if for the capabilities, I'd want to create something like this in
include/linux/capabilities.htypedef struct checkpoint_caps_s { /* what goes in here is the capability code's business */ } checkpoint_caps_t;
Quoted 8 lines
Quoted 8 lines
Quoted 5 lines
Sigh - Did a patch this way, but the problem is userspace needs to be able to parse the checkpoint image, so it needs to know what this struct looks like. So if I put it the struct definition
include/linux/capability.h, I run into a whole new set of problems trying to compile a userspace program to do asys_restart().Does the user space app need to be able to modify the data in some way? It seems like embedding a length with the structure or something might simplify such a user space dependency.
Userspace needs to be able not only to parse the checkpoint image but also to understand the contents:
1) For analysis and debugging tool(s) that will give information about a checkpoint image
2) For conversion tool(s) that will convert a checkpoint image from an older to a newer kernel. The idea is to avoid accumulating endless compatibility code in the kernel.
So yes, these userspace apps need to be able to look and perhaps modify the data in some way.
However, this raises an interesting question of _how_ to do this even in userspace. Suppose we want to convert from version X to version Y, where struct ckpt_blah changed between the version.
What would be an effective way to allow userspace to include both the old and the new ckpt_blah and have them named differently ?
Oren.
Quoted 32 lines
Hmm, I suppose I could do something like define struct
ckpt_capabilitiesincapabilities.h, then incheckpoint_hdr.hdostruct
ckpt_capabilities;struct ckpt_cap_dummy { __u64 dummies[9]; };struct ckpt_hdr_cred { ... union { struct ckpt_capabilities r; struct ckpt_cap_dummy d; } caps; };with a
BUILD_BUG_ONto ensure that sizeof(r)==sizeof(d). Ugly, but should suit everyone?Quoted 5 lines
Quoted 3 lines
So I went part-way to what you suggested in the patchset I'm about to send out (please see patch 6/8). I think the caps code does look nicer in this new version.
Better, but I remain concerned that the code looks hard to maintain when structured this way.
Why exactly? Just having the struct defined in
checkpoint_hdr.h? Or is there something else I'm unwittingly doing?thanks,
-serge
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
In reply to Serge E. Hallyn[I'm sorry if I'm flogging a dead horse. I'm actually really excited by this functionality! :-) ]
Comments inline...
Quoted 33 lines · Serge E. Hallyn
Quoted 20 lines · Andrew G. Morgan
Quoted 13 lines · Serge E. Hallyn
Quoted 11 lines · Andrew G. Morgan
Quoted 2 lines · Serge E. Hallyn
Quoted 2 lines
Quoted 2 lines
I'll put in a commented
BUILD_BUG_ONlike Alexey suggests - does that suffice?I can't speak for other subsystems, but it seems to me as if for the capabilities, I'd want to create something like this in
include/linux/capabilities.htypedef struct
checkpoint_caps_s{
/* what goes in here is the capability code's business */ }checkpoint_caps_t;Quoted 5 lines
Sigh - Did a patch this way, but the problem is userspace needs to be able to parse the checkpoint image, so it needs to know what this struct looks like. So if I put it the struct definition
include/linux/capability.h, I run into a whole new set of problems trying to compile a userspace program to do asys_restart().Quoted 3 lines
Does the user space app need to be able to modify the data in some way? It seems like embedding a length with the structure or something might simplify such a user space dependency.
Hmm, I suppose I could do something like define struct
ckpt_capabilitiesincapabilities.h, then incheckpoint_hdr.hdostruct
ckpt_capabilities;
structckpt_cap_dummy{
__u64 dummies[9];
};
Quoted 7 lines
struct
ckpt_hdr_cred{
...
union {
structckpt_capabilitiesr;
structckpt_cap_dummyd;
} caps;
};
Yes, something like this, but perhaps:
struct ckpt_caps_part_s {
int length; /* = sizeof(struct ckpt_capabilities) */
cap_ckpt_t data;
} caps;and then the generic checkpoint code would do:
#include <linux/capabilities.h> caps.ckpt_capabilities_length = cap_checkpoint_save(&caps.data); [...] cap_checkpoint_restore(caps.length, &caps.caps.data);
and the capability code could opaquely deal with the details.
The reason I think this is more maintainable is that its clear (to the capability code) what is being check-pointed and, conversely, for the checkpoint code it is abstracted with the responsibility for detailed state decisions elsewhere in the kernel.
I suspect I don't understand the user space code issue sufficiently. But if, for some reason, the user space source code is unable to include the definition of cap_ckpt_t, it should be clear that parsing this type of data structure, given that offsets are embedded in it, should be straightforward.
Quoted 2 lines
with a
BUILD_BUG_ONto ensure that sizeof(r)==sizeof(d). Ugly, but should suit everyone?
could the checkpointing code check the return value for cap_checkpoint_restore() and fail the restore if it returned an error?
Cheers
Andrew
Quoted 11 lines
Quoted 7 lines
Quoted 4 lines
So I went part-way to what you suggested in the patchset I'm about to send out (please see patch 6/8). I think the caps code does look nicer in this new version.
Better, but I remain concerned that the code looks hard to maintain when structured this way.
Why exactly? Just having the struct defined in
checkpoint_hdr.h? Or is there something else I'm unwittingly doing?
Quoted 7 lines
thanks,
-serge
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
Quoted 5 lines · Andrew G. Morgan
Quoted 2 lines
with a
BUILD_BUG_ONto ensure that sizeof(r)==sizeof(d). Ugly, but should suit everyone?could the checkpointing code check the return value for
cap_checkpoint_restore()and fail the restore if it returned an error?
Sorry things seem mixed up here. Let's stick to the naming Oren suggested (and i used in the latest set):
checkpoint_capabilities() saves the credential's caps to the
checkpoint image
restore_capabilities() takes state from checkpoint file and
sets a credential's caps accordingly if allowed.
restore_capabilities() returns an error now on failure (-EPERM or -ENOMEM). We might talk about it returning -EINVAL if capability sets aren't valid, but then the kernel currently allows invalid capabilities to be set anyway (hence CapPrm for root tasks is generally 0xffffffffffffffff, not just filled with valid bits).
checkpoint_capabilities() doesn't need to return an error - if it is called at all, it is called with enough space for the struct it expects to write out.
So I don't understand what it is you're asking for above?
thanks,
-serge
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
In reply to Andrew G. MorganQuoted 64 lines · Andrew G. Morgan
[I'm sorry if I'm flogging a dead horse. I'm actually really excited by this functionality! :-) ]
Comments inline...
Quoted 29 lines · Serge E. Hallyn
Quoted 12 lines · Andrew G. Morgan
Quoted 11 lines · Serge E. Hallyn
Quoted 10 lines · Andrew G. Morgan
Quoted 2 lines · Serge E. Hallyn
Quoted 2 lines
Quoted 2 lines
I'll put in a commented
BUILD_BUG_ONlike Alexey suggests - does that suffice?I can't speak for other subsystems, but it seems to me as if for the capabilities, I'd want to create something like this in
include/linux/capabilities.htypedef struct checkpoint_caps_s { /* what goes in here is the capability code's business */ } checkpoint_caps_t;Quoted 8 lines
Quoted 5 lines
Sigh - Did a patch this way, but the problem is userspace needs to be able to parse the checkpoint image, so it needs to know what this struct looks like. So if I put it the struct definition
include/linux/capability.h, I run into a whole new set of problems trying to compile a userspace program to do asys_restart().Does the user space app need to be able to modify the data in some way? It seems like embedding a length with the structure or something might simplify such a user space dependency.
Hmm, I suppose I could do something like define struct
ckpt_capabilitiesincapabilities.h, then incheckpoint_hdr.hdostruct
ckpt_capabilities;struct ckpt_cap_dummy { __u64 dummies[9]; };Quoted 7 lines
struct ckpt_hdr_cred { ... union { struct ckpt_capabilities r; struct ckpt_cap_dummy d; } caps; };Yes, something like this, but perhaps:
struct ckpt_caps_part_s { int length; /* = sizeof(struct ckpt_capabilities) */ cap_ckpt_t data; } caps;and then the generic checkpoint code would do:
#include <linux/capabilities.h> caps.ckpt_capabilities_length = cap_checkpoint_save(&caps.data); [...] cap_checkpoint_restore(caps.length, &caps.caps.data);and the capability code could opaquely deal with the details.
The reason I think this is more maintainable is that its clear (to the capability code) what is being check-pointed and, conversely, for the checkpoint code it is abstracted with the responsibility for detailed state decisions elsewhere in the kernel.
Quoted 6 lines
I suspect I don't understand the user space code issue sufficiently. But if, for some reason, the user space source code is unable to include the definition of
cap_ckpt_t, it should be clear that parsing this type of data structure, given that offsets are embedded in it, should be straightforward.
As I said here:
https://lists.linux-foundation.org/pipermail/containers/2009-June/018288.html
Userspace needs to understand what's in the image to be able to provide debug/info about the image, and to be able to convert images from older kernel version to newer (or even vice versa if one insists).
Oren.
Quoted 26 lines
Quoted 2 lines
with a
BUILD_BUG_ONto ensure that sizeof(r)==sizeof(d). Ugly, but should suit everyone?could the checkpointing code check the return value for
cap_checkpoint_restore()and fail the restore if it returned an error?Cheers
Andrew
Quoted 15 lines
Quoted 5 lines
Quoted 3 lines
So I went part-way to what you suggested in the patchset I'm about to send out (please see patch 6/8). I think the caps code does look nicer in this new version.
Better, but I remain concerned that the code looks hard to maintain when structured this way.
Why exactly? Just having the struct defined in
checkpoint_hdr.h? Or is there something else I'm unwittingly doing?thanks,
-serge
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
You guys are well on the road to having something functional. I do not want to get in the way of that.
What I'm trying to question is the way the code is abstracted. My sense is that its not very friendly to the subsystems being checkpointed. I could offer an alternative patch for the capabilities code, but if it breaks some invisible constraint I'd rather you tell me about it first.
There are three sets of code in these changes:
1. the capabilities code (but I think I'm arguing about that because
it is an example I'm familiar with and this probably applies to other subsystems in the kernel)
2. the glue code in the kernel that implements sys_restore() etc.
3. the user space code
What seems to have happened with these patches is that the glue code and the user space code have knowledge of each other and things are written to make an API/ABI that they can agree on. (Part of this is evidenced by the u64 reference to capabilities and non-use of the more natural kernel_cap_t data that the kernel itself uses.)
It seems to me that a more natural abstraction is that 1 and 3 know about each other (actually 3 knows about how 1 chooses to define things), and 2 is a generic data packager interface.
This should be functionally equivalent, but my belief is an implementation based on the current abstraction will be broken more often because some subsystem (eg. 1) evolves its critical state and the corresponding (2+3)'s relationship is too confusing/constraining for the kernel subsystem developer to keep in sync (someone else's problem). And subtle problems of ignored state in checkpoints can be really hard to debug!
Bottom line. Don't wait for me to Ack this change. I intend to lurk and if I see a way to "clean it up", I'll offer a patch, which you can of course reject... But don't wait on me.
Cheers
Andrew
Quoted 111 lines · Oren Laadan
Quoted 64 lines · Andrew G. Morgan
[I'm sorry if I'm flogging a dead horse. I'm actually really excited by this functionality! :-) ]
Comments inline...
Quoted 29 lines · Serge E. Hallyn
Quoted 12 lines · Andrew G. Morgan
Quoted 11 lines · Serge E. Hallyn
Quoted 10 lines · Andrew G. Morgan
Quoted 2 lines · Serge E. Hallyn
Quoted 2 lines
Quoted 2 lines
I'll put in a commented
BUILD_BUG_ONlike Alexey suggests - does that suffice?I can't speak for other subsystems, but it seems to me as if for the capabilities, I'd want to create something like this in
include/linux/capabilities.htypedef struct
checkpoint_caps_s{
/* what goes in here is the capability code's business */ }checkpoint_caps_t;Quoted 8 lines
Quoted 5 lines
Sigh - Did a patch this way, but the problem is userspace needs to be able to parse the checkpoint image, so it needs to know what this struct looks like. So if I put it the struct definition
include/linux/capability.h, I run into a whole new set of problems trying to compile a userspace program to do asys_restart().Does the user space app need to be able to modify the data in some way? It seems like embedding a length with the structure or something might simplify such a user space dependency.
Hmm, I suppose I could do something like define struct
ckpt_capabilitiesincapabilities.h, then incheckpoint_hdr.hdostruct
ckpt_capabilities;
structckpt_cap_dummy{
__u64 dummies[9];
};Quoted 7 lines
struct
ckpt_hdr_cred{
...
union {
structckpt_capabilitiesr;
structckpt_cap_dummyd;
} caps;
};Yes, something like this, but perhaps:
struct
ckpt_caps_part_s{
int length; /* =sizeof(struct ckpt_capabilities)*/cap_ckpt_tdata;
} caps;and then the generic checkpoint code would do:
#include <
linux/capabilities.h> caps.ckpt_capabilities_length =cap_checkpoint_save(&caps.data); [...]
cap_checkpoint_restore(caps.length, &caps.caps.data);and the capability code could opaquely deal with the details.
The reason I think this is more maintainable is that its clear (to the capability code) what is being check-pointed and, conversely, for the checkpoint code it is abstracted with the responsibility for detailed state decisions elsewhere in the kernel.
Quoted 6 lines
I suspect I don't understand the user space code issue sufficiently. But if, for some reason, the user space source code is unable to include the definition of
cap_ckpt_t, it should be clear that parsing this type of data structure, given that offsets are embedded in it, should be straightforward.As I said here:
https://lists.linux-foundation.org/pipermail/containers/2009-June/018288.htmlUserspace needs to understand what's in the image to be able to provide debug/info about the image, and to be able to convert images from older kernel version to newer (or even vice versa if one insists).
Oren.
Quoted 26 lines
Quoted 2 lines
with a
BUILD_BUG_ONto ensure that sizeof(r)==sizeof(d). Ugly, but should suit everyone?could the checkpointing code check the return value for
cap_checkpoint_restore()and fail the restore if it returned an error?Cheers
Andrew
Quoted 15 lines
Quoted 5 lines
Quoted 3 lines
So I went part-way to what you suggested in the patchset I'm about to send out (please see patch 6/8). I think the caps code does look nicer in this new version.
Better, but I remain concerned that the code looks hard to maintain when structured this way.
Why exactly? Just having the struct defined in
checkpoint_hdr.h? Or is there something else I'm unwittingly doing?thanks,
-serge
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
Quoted 23 lines · Andrew G. Morgan
You guys are well on the road to having something functional. I do not want to get in the way of that.
What I'm trying to question is the way the code is abstracted. My sense is that its not very friendly to the subsystems being checkpointed. I could offer an alternative patch for the capabilities code, but if it breaks some invisible constraint I'd rather you tell me about it first.
There are three sets of code in these changes:
1. the capabilities code (but I think I'm arguing about that because
it is an example I'm familiar with and this probably applies to other subsystems in the kernel)
2. the glue code in the kernel that implementssys_restore()etc.
3. the user space codeWhat seems to have happened with these patches is that the glue code and the user space code have knowledge of each other and things are written to make an API/ABI that they can agree on. (Part of this is evidenced by the u64 reference to capabilities and non-use of the more natural
kernel_cap_tdata that the kernel itself uses.)
Quoted 3 lines
It seems to me that a more natural abstraction is that 1 and 3 know about each other (actually 3 knows about how 1 chooses to define things), and 2 is a generic data packager interface.
One reason (3) and (2) need to know about each is other is bc userspace needs to read the checkpoint image enough to read the task states, clone off suitable children, and then each child calls sys_restart(). So to this end, there are certainly details which userspace doesn't need to be able to parse.
The other reason is that userspace will expect to be able to make changes to the checkpoint file. For instance, if restarting a process from one kernel version with 34 capabilities defined, on a kernel version with 35 defined, then userspace may want to fill in an extra cap.
But I strongly agree with your concern that subsystems will get out of sync with the checkpoint code.
If we just move the struct ckpt_capabilities definition into include/linux/capabilities.h, does that suffice? The c/r userspace could then do something like
cat > ckpthdr.sed << EOF
/^[^ \t]*struct ckpt[^\n]*{/,/}/p
EOF
cat /usr/include/linux/*.h /usr/include/asm/*.h | sed -n -f ckpthdr.sed \
> checkpoint_headers.h
Now you mention using kernel_cap_t's... we can go partway down that road, but the inherent problem is serializing the relevant data so it can be streamed to some file. So I think it's better if the subsystems are required to specify a useful format (like struct ckpt_capabilities) and define the checkpoint/restart helpers to serialize data into the struct. We can try and get cute with dual mirrored struct defs, one which is defined in terms the caps code can understand, and one defined in more arch-independent terms (which is why we need __u64s and packed, for instance). But that seems more fragile than having clear and simple requirements for the $SUBYSTEM_checkpoint() and $SUBSYSTEM_restart() helpers.
(I'll wait to hear whether you think I'm on the right track before reworking my patch)
Quoted 11 lines
This should be functionally equivalent, but my belief is an implementation based on the current abstraction will be broken more often because some subsystem (eg. 1) evolves its critical state and the corresponding (2+3)'s relationship is too confusing/constraining for the kernel subsystem developer to keep in sync (someone else's problem). And subtle problems of ignored state in checkpoints can be really hard to debug!
Bottom line. Don't wait for me to Ack this change. I intend to lurk and if I see a way to "clean it up", I'll offer a patch, which you can of course reject... But don't wait on me.
Thanks, it's much appreciated. But please don't hold back, as your points are imo valid, and we need to work out how to address them.
-serge
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
Quoted 53 lines · Serge E. Hallyn
Quoted 23 lines · Andrew G. Morgan
You guys are well on the road to having something functional. I do not want to get in the way of that.
What I'm trying to question is the way the code is abstracted. My sense is that its not very friendly to the subsystems being checkpointed. I could offer an alternative patch for the capabilities code, but if it breaks some invisible constraint I'd rather you tell me about it first.
There are three sets of code in these changes:
1. the capabilities code (but I think I'm arguing about that because it is an example I'm familiar with and this probably applies to other subsystems in the kernel)
2. the glue code in the kernel that implementssys_restore()etc.
3. the user space codeWhat seems to have happened with these patches is that the glue code and the user space code have knowledge of each other and things are written to make an API/ABI that they can agree on. (Part of this is evidenced by the u64 reference to capabilities and non-use of the more natural
kernel_cap_tdata that the kernel itself uses.)Quoted 3 lines
It seems to me that a more natural abstraction is that 1 and 3 know about each other (actually 3 knows about how 1 chooses to define things), and 2 is a generic data packager interface.
One reason (3) and (2) need to know about each is other is bc userspace needs to read the checkpoint image enough to read the task states, clone off suitable children, and then each child calls
sys_restart(). So to this end, there are certainly details which userspace doesn't need to be able to parse.The other reason is that userspace will expect to be able to make changes to the checkpoint file. For instance, if restarting a process from one kernel version with 34 capabilities defined, on a kernel version with 35 defined, then userspace may want to fill in an extra cap.
But I strongly agree with your concern that subsystems will get out of sync with the checkpoint code.
If we just move the struct
ckpt_capabilitiesdefinition intoinclude/linux/capabilities.h, does that suffice? The c/r userspace could then do something likecat > ckpthdr.sed << EOF
/^[^ \t]*struct ckpt[^\n]*{/,/}/p
EOF
cat/usr/include/linux/*.h/usr/include/asm/*.h| sed -n -f ckpthdr.sed \
>checkpoint_headers.h
Quoted 13 lines
Now you mention using kernel_cap_t's... we can go partway down that road, but the inherent problem is serializing the relevant data so it can be streamed to some file. So I think it's better if the subsystems are required to specify a useful format (like struct
ckpt_capabilities) and define the checkpoint/restart helpers to serialize data into the struct. We can try and get cute with dual mirrored struct defs, one which is defined in terms the caps code can understand, and one defined in more arch-independent terms (which is why we need__u64sand packed, for instance). But that seems more fragile than having clear and simple requirements for the $SUBYSTEM_checkpoint() and $SUBSYSTEM_restart() helpers.
I like this $SUBSYSTEM_checkpoint() etc. thing.
I like the ckpthdr.sed thing. I think a similar rule could be used to generate the calls to the list of $SUBSYSTEM_checkpoint() functions.
For serialization, could a kernel "gcc -E checkpoint-headers.h > this-kernel-checkpoint-file.h" build rule be enough?
Cheers
Andrew
Quoted 20 lines
(I'll wait to hear whether you think I'm on the right track before reworking my patch)
Quoted 11 lines
This should be functionally equivalent, but my belief is an implementation based on the current abstraction will be broken more often because some subsystem (eg. 1) evolves its critical state and the corresponding (2+3)'s relationship is too confusing/constraining for the kernel subsystem developer to keep in sync (someone else's problem). And subtle problems of ignored state in checkpoints can be really hard to debug!
Bottom line. Don't wait for me to Ack this change. I intend to lurk and if I see a way to "clean it up", I'll offer a patch, which you can of course reject... But don't wait on me.
Thanks, it's much appreciated. But please don't hold back, as your points are imo valid, and we need to work out how to address them.
Quoted 6 lines
-serge
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
Quoting Andrew G. Morgan ([email protected]):
...
Quoted 14 lines
Quoted 5 lines
Now you mention using kernel_cap_t's... we can go partway down that road, but the inherent problem is serializing the relevant data so it can be streamed to some file. So I think it's better if the subsystems are required to specify a useful format (like struct
ckpt_capabilities) and defineQuoted 8 lines
the checkpoint/restart helpers to serialize data into the struct. We can try and get cute with dual mirrored struct defs, one which is defined in terms the caps code can understand, and one defined in more arch-independent terms (which is why we need
__u64sand packed, for instance). But that seems more fragile than having clear and simple requirements for the $SUBYSTEM_checkpoint() and $SUBSYSTEM_restart() helpers.
Quoted 4 lines
I like this $SUBSYSTEM_checkpoint() etc. thing.
I like the ckpthdr.sed thing. I think a similar rule could be used to generate the calls to the list of $SUBSYSTEM_checkpoint() functions.
Sorry, I don't follow. Could you say a bit more about this?
Quoted 2 lines
For serialization, could a kernel "gcc -E
checkpoint-headers.h>this-kernel-checkpoint-file.h" build rule be enough?
Again, I don't follow. Do you mean to turn something like kernel_cap_t into something like struct ckpt_capabilities?
thanks,
-serge
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
Quoted 16 lines · Serge E. Hallyn
Quoting Andrew G. Morgan ([email protected]):
...Quoted 14 lines
Quoted 13 lines
Now you mention using kernel_cap_t's... we can go partway down that road, but the inherent problem is serializing the relevant data so it can be streamed to some file. So I think it's better if the subsystems are required to specify a useful format (like struct
ckpt_capabilities) and define the checkpoint/restart helpers to serialize data into the struct. We can try and get cute with dual mirrored struct defs, one which is defined in terms the caps code can understand, and one defined in more arch-independent terms (which is why we need__u64sand packed, for instance). But that seems more fragile than having clear and simple requirements for the $SUBYSTEM_checkpoint() and $SUBSYSTEM_restart() helpers.
Quoted 6 lines
Quoted 4 lines
I like this $SUBSYSTEM_checkpoint() etc. thing.
I like the ckpthdr.sed thing. I think a similar rule could be used to generate the calls to the list of $SUBSYSTEM_checkpoint() functions.
Sorry, I don't follow. Could you say a bit more about this?
See sketch below.
Quoted 6 lines
Quoted 3 lines
For serialization, could a kernel "gcc -E
checkpoint-headers.h>this-kernel-checkpoint-file.h" build rule be enough?Again, I don't follow. Do you mean to turn something like
kernel_cap_tinto something like structckpt_capabilities?
Yes, but without manual effort.
To return the the 1,2,3 breakdown. I think it should be possible for 1 to provide code like this:
$SUBSYSTEM_header.h:
struct ckpt_$SUBSYSTEM_s {
kernel_foo_t a, b, c;};
$SUBSYSTEM_code.c:
void $SUBSYSTEM_checkpoint(struct *storage_ptr)
{
}
int $SUBSYSTEM_restore(struct *storage_ptr)
{
}2 would be 'sed'(perl) generated:
temp_header.h:
foreach $x (sort @SUBSYSTEMS) {
print "#include <$SUBSYSTEM_header.h>\n";
}
print "extern full_checkpoint();\n";
print "struct uber_ckpt_struct {\n";
foreach $x (sort @SUBSYSTEMS) {
print " struct ckpt_$x_s $x;\n"; }
print <<EOT;
};
#ifdef __kernel_source__full_checkpoint()
{
EOT
foreach $x (sort @SUBSYSTEMS) {
print " $x_checkpoint();\n"; }
print <<EOT;
}
#endif
EOT
"ditto for restore, but pay attention to return codes".
Then, for '3', gcc -E temp_header.h | sed 'cut from line after 'extern full_checkpoint'.
That means:
1. gets to define its checkpoint state with its own conventions
2. gets generated with some perl/sed/whatever - low maintenance
3. gets a plain C serialization of the checkpointed state.
The kernel code subsystem code is king here. It defines its checkpoints in whatever manner it feels is natural for the specific subsystem. The glue code is autogenerated. User space has full access to the data in a plain C format. The user space code is where things are fragile, if the user space code wants to manipulate the checkpointed data in some way, but I think there will always be at least one place in the system for fragility and user space is the best place for it.
Cheers
Andrew
Quoted 8 lines
thanks,
-serge
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
Quoted 43 lines · Andrew G. Morgan
Quoted 16 lines · Serge E. Hallyn
Quoting Andrew G. Morgan ([email protected]):
...Quoted 14 lines
Quoted 13 lines
Now you mention using kernel_cap_t's... we can go partway down that road, but the inherent problem is serializing the relevant data so it can be streamed to some file. So I think it's better if the subsystems are required to specify a useful format (like struct
ckpt_capabilities) and define the checkpoint/restart helpers to serialize data into the struct. We can try and get cute with dual mirrored struct defs, one which is defined in terms the caps code can understand, and one defined in more arch-independent terms (which is why we need__u64sand packed, for instance). But that seems more fragile than having clear and simple requirements for the $SUBYSTEM_checkpoint() and $SUBSYSTEM_restart() helpers.Quoted 6 lines
Quoted 4 lines
I like this $SUBSYSTEM_checkpoint() etc. thing.
I like the ckpthdr.sed thing. I think a similar rule could be used to generate the calls to the list of $SUBSYSTEM_checkpoint() functions.
Sorry, I don't follow. Could you say a bit more about this?
See sketch below.
Quoted 6 lines
Quoted 3 lines
For serialization, could a kernel "gcc -E
checkpoint-headers.h>this-kernel-checkpoint-file.h" build rule be enough?Again, I don't follow. Do you mean to turn something like
kernel_cap_tinto something like structckpt_capabilities?Yes, but without manual effort.
To return the the 1,2,3 breakdown. I think it should be possible for 1 to provide code like this:
$SUBSYSTEM_header.h:
struct ckpt_$SUBSYSTEM_s { kernel_foo_t a, b, c;};
Quoted 8 lines
$SUBSYSTEM_code.c:
void $SUBSYSTEM_checkpoint(struct*storage_ptr)
{
}int $SUBSYSTEM_restore(struct *storage_ptr) { }
This doesn't work. Kernel internals don't have clearly defined subsystem boundaries, capabilities or not.
As for capabilities, I think code below is everything what's needed:
typedef __u64 kstate_cap_t;
struct kstate_image_cred {
...
kstate_cap_t cap_inheritable;
kstate_cap_t cap_permitted;
kstate_cap_t cap_effective;
kstate_cap_t cap_bset;
...
};
static void dump_capabilities(kstate_cap_t *i, kernel_cap_t *cap)
{
BUILD_BUG_ON(sizeof(kstate_cap_t) != sizeof(kernel_cap_t));
memcpy(i, cap, sizeof(kstate_cap_t));
}Kernel and userspace can do anything they want with such image easily. --
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
In reply to Andrew G. MorganQuoted 6 lines · Andrew G. Morgan
Serge,
I'm not sure I'm too happy with hard coding the 64-bitness of capability sets. It may well be a very long time before we increase their size, but couldn't you prepare for that with some reference to the prevailing magic numbers for the current ABI representation?
Is the appended, updated version of the patch ok?
Quoted 2 lines
Also, the use of 'error' as both a variable and a goto destination looks a little confusing.
Ok, but that was in the original code. I can send a separate patch for mainline to change that, but it's not hurting anything at the moment so not sure it's worth it?
-serge
From aa72f022fb5788ab46658e6eb94eaf18e8c6568a Mon Sep 17 00:00:00 2001
From: Serge E. Hallyn <[email protected]>
Date: Mon, 11 May 2009 09:44:42 -0400
Subject: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
An 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.
Changelog:
Jun 01: Add commented BUILD_BUG_ON() to point out that the
current implementation depends on 64-bit capabilities. (Andrew Morgan and Alexey Dobriyan).
May 28: add helpers to c/r securebits
--- include/linux/capability.h | 7 +++ kernel/capability.c | 102 ++++++++++++++++++++++++++++++++++++++------ security/commoncap.c | 51 +++++++++++++++------- 3 files changed, 130 insertions(+), 30 deletions(-)
include/linux/capability.h +7 -0
@@ -536,6 +536,13 @@ 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); +extern void checkpoint_save_securebits (unsigned *,unsigned ); +extern int checkpoint_restore_securebits (unsigned ,struct cred *); +/** * has_capability - Determine if a task has a superior capability available * @t: The task in question
kernel/capability.c +89 -13
124 lines not on this page · raw message
security/commoncap.c +34 -17
70 lines not on this page · raw message
Signature · 1 line
1.6.1
Re: [PATCH 5/9] cr: capabilities: define checkpoint and restore fns
Quoted 53 lines · Serge E. Hallyn
Quoted 6 lines · Andrew G. Morgan
Serge,
I'm not sure I'm too happy with hard coding the 64-bitness of capability sets. It may well be a very long time before we increase their size, but couldn't you prepare for that with some reference to the prevailing magic numbers for the current ABI representation?
Is the appended, updated version of the patch ok?
Quoted 2 lines
Also, the use of 'error' as both a variable and a goto destination looks a little confusing.
Ok, but that was in the original code. I can send a separate patch for mainline to change that, but it's not hurting anything at the moment so not sure it's worth it?
-serge
From
aa72f022fb5788ab46658e6eb94eaf18e8c6568aMon Sep 17 00:00:00 2001
From: Serge E. Hallyn <[email protected]>
Date: Mon, 11 May 2009 09:44:42 -0400
Subject: [PATCH 5/9] cr: capabilities: define checkpoint and restore fnsAn 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 executingsys_restart()) permissions.Changelog:
Jun 01: Add commentedBUILD_BUG_ON()to point out that the
current implementation depends on 64-bit capabilities. (Andrew Morgan and Alexey Dobriyan).
May 28: add helpers to c/r securebitsSigned-off-by Serge E. Hallyn <[email protected]>--- include/linux/capability.h | 7 +++ kernel/capability.c | 102 ++++++++++++++++++++++++++++++++++++++------ security/commoncap.c | 51 +++++++++++++++------- 3 files changed, 130 insertions(+), 30 deletions(-)include/linux/capability.h +0
-0
include/linux/capability.h extern const kernel_cap_t __cap_empty_set; · line 544
Quoted 9 lines
include/linux/capability.h +6
-0@@ -536,6 +536,13 @@ 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); +extern void checkpoint_save_securebits (unsigned *,unsigned ); +extern int checkpoint_restore_securebits (unsigned ,struct cred *);
(nit) How about:
checkpoint_capabilities() or checkpoint_cap_t() restore_capabilities() or restore_cap_t()
? (also consistent with rest of the c/r code)
Oren.
PATCH 6/9 cr: checkpoint and restore task credentials
In reply to Serge E. HallynThis 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.
Changelog:
May 28: 1. Restore securebits
2. Address Alexey's comments: move prototypes out of sched.h, validate ngroups < NGROUPS_MAX, validate groups are sorted, and get rid of ckpt_hdr_cred->version.
3. remove bogus unused flag RESTORE_CREATE_USERNS
May 26: Move group, user, userns, creds c/r functions out
of checkpoint/process.c and into the appropriate files.
May 26: Define struct ckpt_hdr_task_creds and move task cred
objref c/r into {checkpoint_restore}_task_shared().
May 26: Take cred refs around checkpoint_write_creds() May 20: Remove the limit on number of groups in groupinfo
at checkpoint time
May 20: Remove the depth limit on empty user namespaces May 20: Better document checkpoint_user
May 18: fix more refcounting: if (userns 5, uid 0) had
no active tasks or child user_namespaces, then it shouldn't exist at restart or it, its namespace, and its whole chain of creators will be leaked.
May 14: fix some refcounting:
1. a new user_ns needs a ref to remain pinned
by its root user
2. current_user_ns needs an extra ref bc objhash drops two on restart
3. cred needs a ref for the real credentials bc commit_creds eats one ref.
May 13: folded in fix to userns refcounting.
--- checkpoint/objhash.c | 118 +++++++++++++++++++++++++++++ checkpoint/process.c | 152 +++++++++++++++++++++++++++++++++++++- include/linux/checkpoint.h | 11 +++ include/linux/checkpoint_hdr.h | 61 +++++++++++++++ include/linux/checkpoint_types.h | 2 +- include/linux/cred.h | 13 +++ include/linux/user_namespace.h | 6 ++ kernel/cred.c | 117 +++++++++++++++++++++++++++++ kernel/groups.c | 59 +++++++++++++++ kernel/user.c | 147 ++++++++++++++++++++++++++++++++++++ kernel/user_namespace.c | 86 +++++++++++++++++++++ 11 files changed, 769 insertions(+), 3 deletions(-)
checkpoint/objhash.c +118 -0
@@ -17,6 +17,7 @@#include <linux/fdtable.h> #include <linux/sched.h> #include <linux/ipc_namespace.h> +#include <linux/user_namespace.h> #include <linux/checkpoint.h> #include <linux/checkpoint_hdr.h>
@@ -177,6 +178,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 */ {
@@ -254,6 +320,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, + }, };
@@ -323,6 +429,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 (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;
checkpoint/process.c +150 -2
214 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 (struct ckpt_ctx *ctx,void *ptr);extern int ckpt_obj_insert (struct ckpt_ctx *ctx,void *ptr,int objref,enum obj_type type);
@@ -117,6 +118,16 @@ extern int checkpoint_file_common(struct ckpt_ctx *ctx, struct file *file,extern int restore_file_common (struct ckpt_ctx *ctx,struct file *file,struct ckpt_hdr_file *h); +/* 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 +61 -0
82 lines not on this page · raw message
include/linux/checkpoint_types.h +1 -1
@@ -15,7 +15,6 @@#define CHECKPOINT_SUBTREE 0x1 -#ifdef __KERNEL__struct ckpt_ctx ;struct ckpt_hdr_file ;
@@ -70,6 +69,7 @@ struct ckpt_ctx {atomic_t tasks_count;/* sync of tasks: used to coordinate */ struct completion complete;/* container root and other tasks on */ wait_queue_head_t waitq;/* start, end, and restart ordering */ +struct cred *realcred, *ecred;/* tmp storage for cred at restart */ };/* ckpt_ctx: kflags */
include/linux/cred.h +13 -0
@@ -77,6 +77,14 @@ extern int groups_search(const struct group_info *, gid_t);extern int in_group_p (gid_t );extern int in_egroup_p (gid_t ); +#ifdef CONFIG_CHECKPOINT +struct ckpt_ctx ; +int checkpoint_write_groupinfo (struct ckpt_ctx *,struct group_info *); +struct group_info *restore_read_groupinfo (struct ckpt_ctx *); +int checkpoint_write_user (struct ckpt_ctx *,struct user_struct *); +struct user_struct *restore_read_user (struct ckpt_ctx *); +#endif +/* * The common credentials for a thread group * - shared by CLONE_THREAD
@@ -352,4 +360,9 @@ 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); +#ifdef CONFIG_CHECKPOINT +int checkpoint_write_cred (struct ckpt_ctx *,const struct cred *); +struct cred *restore_read_cred (struct ckpt_ctx *); +#endif +#endif /* _LINUX_CRED_H */
include/linux/user_namespace.h +6 -0
@@ -62,4 +62,10 @@ static inline void put_user_ns(struct user_namespace *ns)#endif +#ifdef CONFIG_CHECKPOINT +struct ckpt_ctx ; +int checkpoint_write_userns (struct ckpt_ctx *,struct user_namespace *); +struct user_namespace *restore_read_userns (struct ckpt_ctx *); +#endif +#endif /* _LINUX_USER_H */
kernel/cred.c +117 -0
126 lines not on this page · raw message
kernel/groups.c +59 -0
68 lines not on this page · raw message
kernel/user.c +147 -0
156 lines not on this page · raw message
kernel/user_namespace.c +86 -0
95 lines not on this page · raw message
Signature · 1 line
1.6.1
A message that is not in the archive (sent off-list or not yet received): 20090529223229.GA14536-r/[email protected]
PATCH 7/9 cr: restore file->f_cred
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 | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-)
checkpoint/files.c +14 -2
@@ -154,7 +154,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 ; }
@@ -377,8 +381,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 -1
@@ -296,7 +296,7 @@ struct ckpt_hdr_file {__u32 f_type;__u32 f_mode;__u32 f_flags; -__u32 _padding; +__s32 f_credref;__u64 f_pos;__u64 f_version; } __attribute__((aligned(8)));
Signature · 1 line
1.6.1
PATCH 8/9 user namespaces: debug refcounts
In reply to a message not in the archiveCreate /proc/userns, which prints out all user namespaces. It prints the address of the user_ns itself, the uid and userns address of the user who created it, and the reference count.
--- include/linux/user_namespace.h | 2 + kernel/user.c | 1 + kernel/user_namespace.c | 84 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 0 deletions(-)
include/linux/user_namespace.h +2 -0
@@ -14,8 +14,10 @@ struct user_namespace {struct hlist_head uidhash_table[UIDHASH_SZ ];struct user_struct *creator;struct work_struct destroyer; +struct list_head list; }; +extern spinlock_t usernslist_lock;extern struct user_namespace init_user_ns;#ifdef CONFIG_USER_NS
kernel/user.c +1 -0
@@ -24,6 +24,7 @@ struct user_namespace init_user_ns = { .refcount = ATOMIC_INIT(2), }, .creator = &root_user, + .list = LIST_HEAD_INIT(init_user_ns.list), };EXPORT_SYMBOL_GPL (init_user_ns);
kernel/user_namespace.c +84 -0
108 lines not on this page · raw message
Signature · 1 line
1.6.1
Re: [PATCH 8/9] user namespaces: debug refcounts
kernel/user_namespace.c void free_user_ns(struct kref *kref) · line 127
Quoted 12 lines · Serge E. Hallyn
Create
/proc/userns, which prints out all user namespaces. It prints the address of theuser_nsitself, the uid and userns address of the user who created it, and the reference count.kernel/user_namespace.c +8
-0+static int proc_userns_show (struct seq_file *m,void *v) +{ +struct user_namespace *ns = v; +seq_printf (m,"userns %p creator (uid %d ns %p) count %d\n" , + (void *)ns, ns->creator->uid, (void *) ns->creator->user_ns, +atomic_read (&ns->kref.refcount)); +return 0 ; +}
Kernel shouldn't expose location of kernel objects to userspace.
Serge E. Hallyn
maintainerRe: [PATCH 8/9] user namespaces: debug refcounts
Quoted 5 lines · Alexey Dobriyan
Quoted 3 lines · Serge E. Hallyn
Create
/proc/userns, which prints out all user namespaces. It prints the address of theuser_nsitself, the uid and userns address of the user who created it, and the reference count.
Quoted 10 lines
kernel/user_namespace.c void free_user_ns(struct kref *kref) · line 127
Quoted 8 lines
kernel/user_namespace.c +8
-0+static int proc_userns_show (struct seq_file *m,void *v) +{ +struct user_namespace *ns = v; +seq_printf (m,"userns %p creator (uid %d ns %p) count %d\n" , + (void *)ns, ns->creator->uid, (void *) ns->creator->user_ns, +atomic_read (&ns->kref.refcount)); +return 0 ; +}Kernel shouldn't expose location of kernel objects to userspace.
This one was just so ppl could verify things were working as promised. I won't be sending it again.
(OTOH, noone noticed i wasn't actually calling the securebits c/r helpers... I'll be sending a new set of patches fixing that, not including this patch, and hopefully addressing Andrew's and Oren's latest replies.
thanks,
-serge
PATCH 9/9 cr: ipc: reset kern_ipc_perms
In reply to Serge E. HallynReset the checkpointed uid and gid info on ipc objects.
Right now, we return -EPERM if the user calling sys_restart() isn't allowed to create an object with the checkpointed uid. We may prefer to simply use the caller's uid in that case - but that could lead to subtle userspace bugs? Unsure, so going for the stricter behavior.
TODO: restore kern_ipc_perms->security.
--- ipc/checkpoint.c | 33 +++++++++++++++++++++++++++++++-- 1 files changed, 31 insertions(+), 2 deletions(-)
ipc/checkpoint.c +31 -2
@@ -119,6 +119,26 @@ int checkpoint_ipc_ns(struct ckpt_ctx *ctx, struct ipc_namespace *ipc_ns)* Restart */ +/* +* check whether current task may create ipc object with +* checkpointed uids and gids. +* Return 1 if ok, 0 if not. +*/ +static int validate_created_perms (struct ckpt_hdr_ipc_perms *h) +{ +const struct cred *cred =current_cred (); +uid_t uid = cred->uid, euid = cred->euid; + +/* actually I don't know - is CAP_IPC_OWNER the right one? */ +if (((h->uid != uid && h->uid == euid) || + (h->cuid != uid && h->cuid != euid) || + !in_group_p (h->cgid) || + !in_group_p (h->gid)) && + !capable (CAP_IPC_OWNER )) +return 0 ; +return 1 ; +} +int restore_load_ipc_perms (struct ckpt_hdr_ipc_perms *h,struct kern_ipc_perm *perm) {
@@ -139,14 +159,23 @@ int restore_load_ipc_perms(struct ckpt_hdr_ipc_perms *h, perm->id = h->id; perm->key = h->key; -#if 0 /* FIX: requires security checks */ + +if (!validate_created_perms (h)) +return -EPERM ; perm->uid = h->uid; perm->gid = h->gid; perm->cuid = h->cuid; perm->cgid = h->cgid; -#endif perm->mode = h->mode; perm->seq = h->seq; +/* +* Todo: restore perm->security. +* At the moment it gets set by security_x_alloc() called through +* ipcget()->ipcget_public()->ops-.getnew (->nequeue for instance) +* We will want to ask the LSM to consider resetting the +* checkpointed ->security, based on current_security(), +* the checkpointed ->security, and the checkpoint file context. +*/ return 0 ; }
Signature · 1 line
1.6.1