cr: lsm: restore LSM contexts for ipc objects
Subsystems (3)
PATCH 1/1 cr: lsm: restore LSM contexts for ipc objects
Here is the next version of the patch implementing checkpoint and restore of LSM contexts. This is just handling IPC objects as a proof of concept. But actually, looking ahead and both files and tasks, I see that selinux stores several sids in the security structs. For instance, for tasks there is the current sid, exec sid, create sid, keycreate_sid, and sockcreate_sid. So I guess I'll have to ask the LSM for how many secids it wants to checkpoint, then checkpoint an array of contexts?
From 19669b07cdfef4d377f3f188e2421c4124e38708 Mon Sep 17 00:00:00 2001
From: Serge E. Hallyn <[email protected]>
Date: Wed, 17 Jun 2009 12:00:21 -0400
Subject: [PATCH 1/1] cr: lsm: restore LSM contexts for ipc objects
Introduce a cache of secids for checkpoint and restart. At checkpoint, it takes a secid, stores the corresponding context string, and stores the objref for later use. At restart, read the context from checkpoint image, ask the security module for a secid, and store the secid on the objhash.
The per-object security c/r code will be responsible for getting secid from void*security at checkpoint time, and converting secid to void*security at restore time.
The code to c/r contexts for IPC objects is also in this patch.
For Smack, assign the label of the process doing sys_restart() if !capable(CAP_MAC_ADMIN), otherwise use the checkpointed label.
For SELinux, define a new 'restore' permission for ipc objects. (A corresponding trival policy patch adding 'restore' to the common flask permissions for refpolicy is also needed). The caller of sys_restart() must have the class:restore permission to assign the checkpointed label, else restart will be refused.
--- checkpoint/objhash.c | 10 ++ checkpoint/sys.c | 15 ++ include/linux/checkpoint_hdr.h | 12 ++- include/linux/checkpoint_types.h | 7 + include/linux/security.h | 92 ++++++++++++ ipc/checkpoint.c | 20 ++- ipc/checkpoint_msg.c | 45 ++++++- ipc/checkpoint_sem.c | 18 +++- ipc/checkpoint_shm.c | 18 +++- ipc/util.h | 3 +- security/capability.c | 38 +++++ security/security.c | 169 ++++++++++++++++++++++ security/selinux/hooks.c | 48 ++++++ security/selinux/include/av_inherit.h | 8 +- security/selinux/include/av_permissions.h | 10 +- security/selinux/include/common_perm_to_string.h | 1 + security/smack/smack_lsm.c | 77 ++++++++++ 17 files changed, 571 insertions(+), 20 deletions(-)
checkpoint/objhash.c +10 -0
@@ -18,6 +18,7 @@#include <linux/sched.h> #include <linux/ipc_namespace.h> #include <linux/user_namespace.h> +#include <linux/security.h> #include <linux/checkpoint.h> #include <linux/checkpoint_hdr.h>
@@ -365,6 +366,15 @@ static struct ckpt_obj_ops ckpt_obj_ops[] = { .checkpoint = checkpoint_groupinfo, .restore = restore_groupinfo, }, +/* LSM context */ + { + .obj_name = "SECURITY", + .obj_type = CKPT_OBJ_SECURITY, + .ref_grab = obj_no_grab, + .ref_drop = obj_no_drop, + .checkpoint = checkpoint_security, + .restore = restore_security, + }, };
checkpoint/sys.c +15 -0
@@ -20,6 +20,7 @@#include <linux/file.h> #include <linux/uaccess.h> #include <linux/capability.h> +#include <linux/security.h> #include <linux/checkpoint.h> #include <linux/deferqueue.h>
@@ -188,6 +189,16 @@ static void task_arr_free(struct ckpt_ctx *ctx)kfree (ctx->tasks_arr); } +void free_secreflist (struct ckpt_ctx *ctx) +{ +struct sec_store *s, *p; + +list_for_each_entry_safe (s, p, &ctx->secref_list, list) { +list_del (&s->list); +kfree (s); + } +} +static void ckpt_ctx_free (struct ckpt_ctx *ctx) {int ret;
@@ -217,6 +228,7 @@ static void ckpt_ctx_free(struct ckpt_ctx *ctx)put_task_struct (ctx->root_task);if (ctx->root_freezer)put_task_struct (ctx->root_freezer); +free_secreflist (ctx);kfree (ctx->pids_arr);
@@ -233,6 +245,9 @@ static struct ckpt_ctx *ckpt_ctx_alloc(int fd, unsigned long uflags,if (!ctx)return ERR_PTR (-ENOMEM ); +spin_lock_init (&ctx->secref_lock); +INIT_LIST_HEAD (&ctx->secref_list); + ctx->uflags = uflags; ctx->kflags = kflags; ctx->ktime_begin =ktime_get ();
include/linux/checkpoint_hdr.h +11 -1
@@ -62,6 +62,7 @@ enum {CKPT_HDR_USER ,CKPT_HDR_GROUPINFO ,CKPT_HDR_TASK_CREDS , + CKPT_HDR_SECURITY,/* 201-299: reserved for arch-dependent */
@@ -114,6 +115,7 @@ enum obj_type {CKPT_OBJ_CRED ,CKPT_OBJ_USER ,CKPT_OBJ_GROUPINFO , +CKPT_OBJ_SECURITY , CKPT_OBJ_MAX };
@@ -192,6 +194,12 @@ struct ckpt_capabilities {__u32 padding; } __attribute__((aligned(8))); +/* LSM security contexts (shared) */ +struct ckpt_hdr_sec { +struct ckpt_hdr h; +char str[]; +} __attribute__((aligned (8 ))); +struct ckpt_hdr_task_creds {struct ckpt_hdr h;__s32 cred_ref;
@@ -418,7 +426,7 @@ struct ckpt_hdr_ipc_perms {__u32 cuid;__u32 cgid;__u32 mode; -__u32 _padding; +__s32 secref;__u64 seq; } __attribute__((aligned(8)));
@@ -453,6 +461,8 @@ struct ckpt_hdr_ipc_msg_msg {struct ckpt_hdr h;__s32 m_type;__u32 m_ts; +__s32 secref; +__u32 padding; } __attribute__((aligned(8)));struct ckpt_hdr_ipc_sem {
include/linux/checkpoint_types.h +7 -0
@@ -73,6 +73,13 @@ struct ckpt_ctx {struct cred *realcred, *ecred;/* tmp storage for cred at restart */ struct ckpt_stats stats;/* statistics */ + +/* +* next two form basis for a mini-cache of LSM contexts +* turn it into a rbtree or hash +*/ +spinlock_t secref_lock; + struct list_head secref_list; };#endif /* __KERNEL__ */
include/linux/security.h +92 -0
194 lines not on this page · raw message
ipc/checkpoint.c +13 -7
@@ -15,6 +15,7 @@#include <linux/msg.h> #include <linux/sched.h> #include <linux/ipc_namespace.h> +#include <linux/security.h> #include <linux/checkpoint.h> #include <linux/checkpoint_hdr.h>
@@ -31,9 +32,12 @@ static char *ipc_ind_to_str[] = { "sem", "msg", "shm" };* Checkpoint */ -int checkpoint_fill_ipc_perms (struct ckpt_hdr_ipc_perms *h, +int checkpoint_fill_ipc_perms (struct ckpt_ctx *ctx, +struct ckpt_hdr_ipc_perms *h,struct kern_ipc_perm *perm) { +int secid; +if (ipcperms (perm,S_IROTH ))return -EACCES ;
@@ -46,6 +50,11 @@ int checkpoint_fill_ipc_perms(struct ckpt_hdr_ipc_perms *h, h->mode = perm->mode &S_IRWXUGO ; h->seq = perm->seq; +security_ipc_getsecid (perm, &secid); + h->secref =checkpoint_security_getsecref (ctx, secid); +if (h->secref <0 ) +return h->secref; +return 0 ; }
@@ -185,13 +194,10 @@ int restore_load_ipc_perms(struct ckpt_hdr_ipc_perms *h, 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. +* The checkpointed ->security value will be restored +* (and verified) by our caller. */ + perm->security =NULL ;return 0 ; }
ipc/checkpoint_msg.c +42 -3
91 lines not on this page · raw message
ipc/checkpoint_sem.c +17 -1
@@ -17,6 +17,7 @@#include <linux/sched.h> #include <linux/syscalls.h> #include <linux/nsproxy.h> +#include <linux/security.h> #include <linux/ipc_namespace.h> struct msg_msg ;
@@ -37,7 +38,7 @@ static int fill_ipc_sem_hdr(struct ckpt_ctx *ctx,ipc_lock_by_ptr (&sem->sem_perm); - ret =checkpoint_fill_ipc_perms (&h->perms, &sem->sem_perm); + ret =checkpoint_fill_ipc_perms (ctx, &h->perms, &sem->sem_perm);if (ret <0 ) goto unlock;
@@ -112,11 +113,26 @@ static int load_ipc_sem_hdr(struct ckpt_ctx *ctx, struct sem_array *sem) {int ret =0 ; +int secid =0 ; ret =restore_load_ipc_perms (&h->perms, &sem->sem_perm);if (ret <0 )return ret; +if (h->perms.secref) { +struct sec_store *s; + s =ckpt_obj_fetch (ctx, h->perms.secref,CKPT_OBJ_SECURITY ); +if (IS_ERR (s)) +return PTR_ERR (s); + secid = s->secid; + } + ret =security_sem_alloc (sem); +if (ret) +return ret; + ret =security_sem_restore (sem, secid); +if (ret <0 ) +return ret; +ckpt_debug ("sem: nsems %u\n" , h->sem_nsems); sem->sem_otime = h->sem_otime;
ipc/checkpoint_shm.c +17 -1
@@ -21,6 +21,7 @@#include <linux/syscalls.h> #include <linux/nsproxy.h> #include <linux/ipc_namespace.h> +#include <linux/security.h> #include <linux/deferqueue.h> #include <linux/msg.h> /* needed for util.h that uses 'struct msg_msg' */
@@ -41,7 +42,7 @@ static int fill_ipc_shm_hdr(struct ckpt_ctx *ctx,ipc_lock_by_ptr (&shp->shm_perm); - ret =checkpoint_fill_ipc_perms (&h->perms, &shp->shm_perm); + ret =checkpoint_fill_ipc_perms (ctx, &h->perms, &shp->shm_perm);if (ret <0 ) goto unlock;
@@ -148,11 +149,26 @@ static int load_ipc_shm_hdr(struct ckpt_ctx *ctx, struct shmid_kernel *shp) {int ret; +int secid =0 ; ret =restore_load_ipc_perms (&h->perms, &shp->shm_perm);if (ret <0 )return ret; +if (h->perms.secref) { +struct sec_store *s; + s =ckpt_obj_fetch (ctx, h->perms.secref,CKPT_OBJ_SECURITY ); +if (IS_ERR (s)) +return PTR_ERR (s); + secid = s->secid; + } + ret =security_shm_alloc (shp); +if (ret) +return ret; + ret =security_shm_restore (shp, secid); +if (ret <0 ) +return ret; +ckpt_debug ("shm: cprid %d lprid %d segsz %lld mlock %d\n" , h->shm_cprid, h->shm_lprid, h->shm_segsz, h->mlock_uid);
ipc/util.h +2 -1
@@ -199,7 +199,8 @@ extern void freeary(struct ipc_namespace *, struct kern_ipc_perm *);extern void do_shm_rmid (struct ipc_namespace *ns,struct kern_ipc_perm *ipcp);#ifdef CONFIG_CHECKPOINT -extern int checkpoint_fill_ipc_perms (struct ckpt_hdr_ipc_perms *h, +extern int checkpoint_fill_ipc_perms (struct ckpt_ctx *ctx, +struct ckpt_hdr_ipc_perms *h,struct kern_ipc_perm *perm);extern int restore_load_ipc_perms (struct ckpt_hdr_ipc_perms *h,struct kern_ipc_perm *perm);
security/capability.c +38 -0
@@ -494,6 +494,18 @@ static void cap_msg_msg_free_security(struct msg_msg *msg) { } +static void cap_msg_msg_getsecid (struct msg_msg *msg,u32 *secid) +{ + *secid =0 ; +} + +static int cap_msg_msg_restore (struct msg_msg *msg,u32 secid) +{ +if (secid) +return -EINVAL ; +return 0 ; +} +static int cap_msg_queue_alloc_security (struct msg_queue *msq) {return 0 ;
@@ -525,6 +537,13 @@ static int cap_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,return 0 ; } +static int cap_msg_queue_restore (struct msg_queue *msq,u32 secid) +{ +if (secid) +return -EINVAL ; +return 0 ; +} +static int cap_shm_alloc_security (struct shmid_kernel *shp) {return 0 ;
@@ -550,6 +569,13 @@ static int cap_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr,return 0 ; } +static int cap_shm_restore (struct shmid_kernel *shp,u32 secid) +{ +if (secid) +return -EINVAL ; +return 0 ; +} +static int cap_sem_alloc_security (struct sem_array *sma) {return 0 ;
@@ -575,6 +601,13 @@ static int cap_sem_semop(struct sem_array *sma, struct sembuf *sops,return 0 ; } +static int cap_sem_restore (struct sem_array *sma,u32 secid) +{ +if (secid) +return -EINVAL ; +return 0 ; +} +#ifdef CONFIG_SECURITY_NETWORK static int cap_unix_stream_connect (struct socket *sock,struct socket *other,struct sock *newsk)
@@ -977,22 +1010,27 @@ void security_fixup_ops(struct security_operations *ops)set_to_cap_if_null (ops, ipc_getsecid);set_to_cap_if_null (ops, msg_msg_alloc_security);set_to_cap_if_null (ops, msg_msg_free_security); +set_to_cap_if_null (ops, msg_msg_getsecid); +set_to_cap_if_null (ops, msg_msg_restore);set_to_cap_if_null (ops, msg_queue_alloc_security);set_to_cap_if_null (ops, msg_queue_free_security);set_to_cap_if_null (ops, msg_queue_associate);set_to_cap_if_null (ops, msg_queue_msgctl);set_to_cap_if_null (ops, msg_queue_msgsnd);set_to_cap_if_null (ops, msg_queue_msgrcv); +set_to_cap_if_null (ops, msg_queue_restore);set_to_cap_if_null (ops, shm_alloc_security);set_to_cap_if_null (ops, shm_free_security);set_to_cap_if_null (ops, shm_associate);set_to_cap_if_null (ops, shm_shmctl);set_to_cap_if_null (ops, shm_shmat); +set_to_cap_if_null (ops, shm_restore);set_to_cap_if_null (ops, sem_alloc_security);set_to_cap_if_null (ops, sem_free_security);set_to_cap_if_null (ops, sem_associate);set_to_cap_if_null (ops, sem_semctl);set_to_cap_if_null (ops, sem_semop); +set_to_cap_if_null (ops, sem_restore);set_to_cap_if_null (ops, netlink_send);set_to_cap_if_null (ops, netlink_recv);set_to_cap_if_null (ops, d_instantiate);
security/security.c +169 -0
202 lines not on this page · raw message
security/selinux/hooks.c +48 -0
102 lines not on this page · raw message
security/selinux/include/av_inherit.h +4 -4
@@ -15,10 +15,10 @@ S_(SECCLASS_KEY_SOCKET, socket, 0x00400000UL) S_(SECCLASS_UNIX_STREAM_SOCKET, socket, 0x00400000UL) S_(SECCLASS_UNIX_DGRAM_SOCKET, socket, 0x00400000UL) - S_(SECCLASS_IPC, ipc, 0x00000200UL) - S_(SECCLASS_SEM, ipc, 0x00000200UL) - S_(SECCLASS_MSGQ, ipc, 0x00000200UL) - S_(SECCLASS_SHM, ipc, 0x00000200UL) + S_(SECCLASS_IPC, ipc, 0x00000400UL) + S_(SECCLASS_SEM, ipc, 0x00000400UL) + S_(SECCLASS_MSGQ, ipc, 0x00000400UL) + S_(SECCLASS_SHM, ipc, 0x00000400UL) S_(SECCLASS_NETLINK_ROUTE_SOCKET, socket, 0x00400000UL) S_(SECCLASS_NETLINK_FIREWALL_SOCKET, socket, 0x00400000UL)S_ (SECCLASS_NETLINK_TCPDIAG_SOCKET , socket,0x00400000UL )
security/selinux/include/av_permissions.h +8 -2
@@ -47,6 +47,7 @@#define COMMON_IPC__ASSOCIATE 0x00000040UL#define COMMON_IPC__UNIX_READ 0x00000080UL#define COMMON_IPC__UNIX_WRITE 0x00000100UL +#define COMMON_IPC__RESTORE 0x00000200UL#define FILESYSTEM__MOUNT 0x00000001UL#define FILESYSTEM__REMOUNT 0x00000002UL#define FILESYSTEM__UNMOUNT 0x00000004UL
@@ -462,6 +463,7 @@#define IPC__ASSOCIATE 0x00000040UL#define IPC__UNIX_READ 0x00000080UL#define IPC__UNIX_WRITE 0x00000100UL +#define IPC__RESTORE 0x00000200UL#define SEM__CREATE 0x00000001UL#define SEM__DESTROY 0x00000002UL#define SEM__GETATTR 0x00000004UL
@@ -471,6 +473,7 @@#define SEM__ASSOCIATE 0x00000040UL#define SEM__UNIX_READ 0x00000080UL#define SEM__UNIX_WRITE 0x00000100UL +#define SEM__RESTORE 0x00000200UL#define MSGQ__CREATE 0x00000001UL#define MSGQ__DESTROY 0x00000002UL#define MSGQ__GETATTR 0x00000004UL
@@ -480,9 +483,11 @@#define MSGQ__ASSOCIATE 0x00000040UL#define MSGQ__UNIX_READ 0x00000080UL#define MSGQ__UNIX_WRITE 0x00000100UL -#define MSGQ__ENQUEUE 0x00000200UL +#define MSGQ__RESTORE 0x00000200UL +#define MSGQ__ENQUEUE 0x00000400UL#define MSG__SEND 0x00000001UL#define MSG__RECEIVE 0x00000002UL +#define MSG__RESTORE 0x00000004UL#define SHM__CREATE 0x00000001UL#define SHM__DESTROY 0x00000002UL#define SHM__GETATTR 0x00000004UL
@@ -492,7 +497,8 @@#define SHM__ASSOCIATE 0x00000040UL#define SHM__UNIX_READ 0x00000080UL#define SHM__UNIX_WRITE 0x00000100UL -#define SHM__LOCK 0x00000200UL +#define SHM__RESTORE 0x00000200UL +#define SHM__LOCK 0x00000400UL#define SECURITY__COMPUTE_AV 0x00000001UL#define SECURITY__COMPUTE_CREATE 0x00000002UL#define SECURITY__COMPUTE_MEMBER 0x00000004UL
security/selinux/include/common_perm_to_string.h +1 -0
@@ -54,5 +54,6 @@ TB_(common_ipc_perm_to_string) S_("associate") S_("unix_read") S_("unix_write") + S_("restore")TE_ (common_ipc_perm_to_string)
security/smack/smack_lsm.c +77 -0
125 lines not on this page · raw message
Signature · 1 line
1.6.1
James Morris
maintainerQuoted 9 lines · Serge E. Hallyn
Here is the next version of the patch implementing checkpoint and restore of LSM contexts. This is just handling IPC objects as a proof of concept. But actually, looking ahead and both files and tasks, I see that selinux stores several sids in the security structs. For instance, for tasks there is the current sid, exec sid, create sid,
keycreate_sid, andsockcreate_sid. So I guess I'll have to ask the LSM for how many secids it wants to checkpoint, then checkpoint an array of contexts?
Can you please explain exactly what checkpoint/restart is?
Signature · 2 lines
James Morris <[email protected]>
Quoted 12 lines · James Morris
Quoted 9 lines · Serge E. Hallyn
Here is the next version of the patch implementing checkpoint and restore of LSM contexts. This is just handling IPC objects as a proof of concept. But actually, looking ahead and both files and tasks, I see that selinux stores several sids in the security structs. For instance, for tasks there is the current sid, exec sid, create sid,
keycreate_sid, andsockcreate_sid. So I guess I'll have to ask the LSM for how many secids it wants to checkpoint, then checkpoint an array of contexts?
Quoted 1 line
Can you please explain exactly what checkpoint/restart is?
Take a container or (it is still subject to debate whether to allow this) any process tree, freeze it, record the state of the tasks, all objects they own, and the filesystem. The result is a checkpoint image file for later use. Unfreeze, and either continue running or kill. Later, restart from the checkpoint image, which will create a new container containing all of the needed objects (IPC semaphores, open files, sockets, etc) and restart all tasks exactly where they left off.
While it seems very likely that in the end (when it hits upstream) we will require privilege to use restart at all, we are doing our best to design it so that it is safe for unprivileged users. That means that every object creation must be contingent on the authorization of the task calling sys_restart(). After all, it is a trivial matter to call sys_checkpoint() on your own vim process, edit the checkpoint file to change the filename to /etc/passwd and the process uid to 0, and then call sys_restart() on the result.
Since we don't want to talk about any 'trusted' user in SELinux at all, the same mindset required to support unprivileged restart for the DAC perms very much applies to c/r of SELinux state.
I'll add an explanation to the next version of the patch.
thanks,
-serge
A message that is not in the archive (sent off-list or not yet received): 20090620013216.GA4435-r/[email protected]
Quoted 8 lines · Serge E. Hallyn
Here is the next version of the patch implementing checkpoint and restore of LSM contexts. This is just handling IPC objects as a proof of concept. But actually, looking ahead and both files and tasks, I see that selinux stores several sids in the security structs. For instance, for tasks there is the current sid, exec sid, create sid,
keycreate_sid, andsockcreate_sid. So I guess I'll have to ask the LSM for how many secids it wants to checkpoint, then checkpoint an array of contexts?
You will need to support checkpointing multiple secids/contexts per object, but what about other state that might live in the security structs, e.g. flags fields, policy seqno, etc.
Quoted 6 lines
Quoted 1 line
From
19669b07cdfef4d377f3f188e2421c4124e38708Mon Sep 17 00:00:00 2001From: Serge E. Hallyn <[email protected]>
Date: Wed, 17 Jun 2009 12:00:21 -0400
Subject: [PATCH 1/1] cr: lsm: restore LSM contexts for ipc objectsIntroduce a cache of secids for checkpoint and restart.
Not sure you need to cache them in the cr layer (vs. just using the mapping functions provided by the LSM hook interface, and letting the security module handle caching internally).
Quoted 30 lines
At checkpoint, it takes a secid, stores the corresponding context string, and stores the objref for later use. At restart, read the context from checkpoint image, ask the security module for a secid, and store the secid on the objhash.
The per-object security c/r code will be responsible for getting secid from void*security at checkpoint time, and converting secid to void*security at restore time.
The code to c/r contexts for IPC objects is also in this patch.
For Smack, assign the label of the process doing
sys_restart()if !capable(CAP_MAC_ADMIN), otherwise use the checkpointed label.For SELinux, define a new 'restore' permission for ipc objects. (A corresponding trival policy patch adding 'restore' to the common flask permissions for refpolicy is also needed). The caller of
sys_restart()must have the class:restore permission to assign the checkpointed label, else restart will be refused.Signed-off-by Serge E. Hallyn <[email protected]>include/linux/checkpoint_hdr.h +0
-0
include/linux/checkpoint_hdr.h struct ckpt_hdr_ipc_perms { · line 429
Quoted 5 lines
include/linux/checkpoint_hdr.h +1
-1@@ -418,7 +426,7 @@ struct ckpt_hdr_ipc_perms {__u32 cuid;__u32 cgid;__u32 mode; -__u32 _padding; +__s32 secref;
Why s32 vs u32? secids are u32 and 0 means they aren't supported by the security module.
Signature · 8 lines
Stephen Smalley National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.
Quoted 9 lines · Stephen Smalley
Quoted 8 lines · Serge E. Hallyn
Here is the next version of the patch implementing checkpoint and restore of LSM contexts. This is just handling IPC objects as a proof of concept. But actually, looking ahead and both files and tasks, I see that selinux stores several sids in the security structs. For instance, for tasks there is the current sid, exec sid, create sid,
keycreate_sid, andsockcreate_sid. So I guess I'll have to ask the LSM for how many secids it wants to checkpoint, then checkpoint an array of contexts?
Again thanks for taking a look, Stephen.
Quoted 3 lines
You will need to support checkpointing multiple secids/contexts per object, but what about other state that might live in the security structs, e.g. flags fields, policy seqno, etc.
I think the LSM should handle things like sb_flags and sclass automatically as the objects are restored. Allowing them to be specified in the checkpoint image only increases the number of ways in which a corrupted checkpoint image can mess with the kernel. (Note that at the moment the restart code doesn't address mounts and it's undecide whether that will be done manually in userspace, or done in the kernel by the restart code). As for seqno, see below.
Quoted 10 lines
Quoted 6 lines
Quoted 1 line
From
19669b07cdfef4d377f3f188e2421c4124e38708Mon Sep 17 00:00:00 2001From: Serge E. Hallyn <[email protected]>
Date: Wed, 17 Jun 2009 12:00:21 -0400
Subject: [PATCH 1/1] cr: lsm: restore LSM contexts for ipc objectsIntroduce a cache of secids for checkpoint and restart.
Not sure you need to cache them in the cr layer (vs. just using the mapping functions provided by the LSM hook interface, and letting the security module handle caching internally).
Do I understand correctly that secids are supposed to be consistent across machines and reboots, but not across policy versions?
There are several ways we could handle this. One is to have security_checkpoint_object() spit out an arbitrary void* which describes the *full* security context, with the checkpoint/restart layer completely unaware about the meaning of the contents.
Another is to have security_checkpoint_header() output the policy version, and for each checkpointed object just write out an array of secids. If any file has a seqno which is not the same as the rest of the container's, then refuse the checkpoint?
A third, which is what I was doing here, is to write out textual context representations, and expect the LSM on _restore() to know of a single meaningful interpretation for the context_str. Maybe adding a security_checkpoint_header() at the top of the checkpoint file would help with that (so that in the general case, if policy version at restart is different from the checkpointed one, we refuse restart, assuming that we can't meaningfully intepret even system_u:object_r:user_file_t).
Quoted 25 lines
Quoted 24 lines
At checkpoint, it takes a secid, stores the corresponding context string, and stores the objref for later use. At restart, read the context from checkpoint image, ask the security module for a secid, and store the secid on the objhash.
The per-object security c/r code will be responsible for getting secid from void*security at checkpoint time, and converting secid to void*security at restore time.
The code to c/r contexts for IPC objects is also in this patch.
For Smack, assign the label of the process doing
sys_restart()if !capable(CAP_MAC_ADMIN), otherwise use the checkpointed label.For SELinux, define a new 'restore' permission for ipc objects. (A corresponding trival policy patch adding 'restore' to the common flask permissions for refpolicy is also needed). The caller of
sys_restart()must have the class:restore permission to assign the checkpointed label, else restart will be refused.Signed-off-by Serge E. Hallyn <[email protected]>
Quoted 13 lines
include/linux/checkpoint_hdr.h struct ckpt_hdr_ipc_perms { · line 429
Quoted 10 lines
include/linux/checkpoint_hdr.h +1
-1@@ -418,7 +426,7 @@ struct ckpt_hdr_ipc_perms {__u32 cuid;__u32 cgid;__u32 mode; -__u32 _padding; +__s32 secref;Why s32 vs u32? secids are u32 and 0 means they aren't supported by the security module.
The secref is a reference to an object in the checkpoint/restart object hashtable, not a secid. Those are signed, with <0 meaning error and 0 being a special case (in this case, 'not applicable')
If we write out the secids directly, which it sounds like you are advocating, and not the secid_to_secctx string, then we can store a u32 numsecs followed by __u32 secid[] which will have numsecs entries.
thanks,
-serge
Quoted 7 lines · Serge E. Hallyn
Quoted 3 lines · Stephen Smalley
Not sure you need to cache them in the cr layer (vs. just using the mapping functions provided by the LSM hook interface, and letting the security module handle caching internally).
Do I understand correctly that secids are supposed to be consistent across machines and reboots, but not across policy versions?
No, secids are temporal - they are dynamically allocated at runtime like file descriptors. You should only store security contexts in the images.
Quoted 9 lines
There are several ways we could handle this. One is to have
security_checkpoint_object()spit out an arbitrary void* which describes the *full* security context, with the checkpoint/restart layer completely unaware about the meaning of the contents.Another is to have
security_checkpoint_header()output the policy version, and for each checkpointed object just write out an array of secids. If any file has a seqno which is not the same as the rest of the container's, then refuse the checkpoint?
No, I was referring to the seqno cached in the open file to determine whether we need to revalidate on read/write. I suppose resetting it to zero on restore won't affect behavior, just performance.
Quoted 3 lines
A third, which is what I was doing here, is to write out textual context representations, and expect the LSM on
_restore()to know of a single meaningful interpretation for thecontext_str.
That's the right approach.
Quoted 45 lines
Maybe adding a
security_checkpoint_header()at the top of the checkpoint file would help with that (so that in the general case, if policy version at restart is different from the checkpointed one, we refuse restart, assuming that we can't meaningfully intepret even system_u:object_r:user_file_t).Quoted 25 lines
Quoted 24 lines
At checkpoint, it takes a secid, stores the corresponding context string, and stores the objref for later use. At restart, read the context from checkpoint image, ask the security module for a secid, and store the secid on the objhash.
The per-object security c/r code will be responsible for getting secid from void*security at checkpoint time, and converting secid to void*security at restore time.
The code to c/r contexts for IPC objects is also in this patch.
For Smack, assign the label of the process doing
sys_restart()if !capable(CAP_MAC_ADMIN), otherwise use the checkpointed label.For SELinux, define a new 'restore' permission for ipc objects. (A corresponding trival policy patch adding 'restore' to the common flask permissions for refpolicy is also needed). The caller of
sys_restart()must have the class:restore permission to assign the checkpointed label, else restart will be refused.Signed-off-by Serge E. Hallyn <[email protected]>Quoted 13 lines
include/linux/checkpoint_hdr.h struct ckpt_hdr_ipc_perms { · line 429
Quoted 10 lines
include/linux/checkpoint_hdr.h +1
-1@@ -418,7 +426,7 @@ struct ckpt_hdr_ipc_perms {__u32 cuid;__u32 cgid;__u32 mode; -__u32 _padding; +__s32 secref;Why s32 vs u32? secids are u32 and 0 means they aren't supported by the security module.
Quoted 8 lines
The secref is a reference to an object in the checkpoint/restart object hashtable, not a secid. Those are signed, with <0 meaning error and 0 being a special case (in this case, 'not applicable')
If we write out the secids directly, which it sounds like you are advocating, and not the
secid_to_secctxstring, then we can store a u32 numsecs followed by__u32secid[] which will have numsecs entries.
No, I just misunderstood what you meant by caching of the secids and by the use of secref - never mind.
Signature · 8 lines
Stephen Smalley National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.
Casey Schaufler
maintainerQuoted 8 lines · Stephen Smalley
Quoted 6 lines · Serge E. Hallyn
Quoted 4 lines · Stephen Smalley
Not sure you need to cache them in the cr layer (vs. just using the mapping functions provided by the LSM hook interface, and letting the security module handle caching internally).
Quoted 8 lines
Quoted 3 lines
Do I understand correctly that secids are supposed to be consistent across machines and reboots, but not across policy versions?
No, secids are temporal - they are dynamically allocated at runtime like file descriptors. You should only store security contexts in the images.
Like he said. Smack would be happier if secid's went away, but there's too much left over from the era when SELinux was the only LSM for that to happen without crying and gnashing of teeth. A secid is good only for the current invocation of the current instance of the kernel.
Quoted 4 lines · Serge E. Hallyn
ipc/checkpoint_msg.c +0
-0
<snip>
Quoted 13 lines
ipc/checkpoint_msg.c +4
-0@@ -175,11 +183,26 @@ static int load_ipc_msg_hdr(struct ckpt_ctx *ctx, struct msg_queue *msq) {int ret =0 ; +int secid =0 ; ret =restore_load_ipc_perms (&h->perms, &msq->q_perm);if (ret <0 )return ret; +if (h->perms.secref) { +struct sec_store *s; + s =ckpt_obj_fetch (ctx, h->perms.secref,CKPT_OBJ_SECURITY );
ipc/checkpoint_msg.c static int load_ipc_msg_hdr(struct ckpt_ctx *ctx, · line 204
Quoted 10 lines
ipc/checkpoint_msg.c +10
-0+if (IS_ERR (s)) +return PTR_ERR (s); + secid = s->secid; + } + ret =security_msg_queue_alloc (msq); +if (ret) +return ret; + ret =security_msg_queue_restore (msq, secid); +if (ret <0 ) +return ret;
I don't think you want to call security_msg_queue_alloc() here, as that both allocates the security struct and performs the create check. So I would just call the _restore() function, and let it internally call ipc_alloc_security() to allocate the struct but then apply its own distinct restore check. Likewise for the rest of them.
Also, where do we get to veto attempts to checkpoint the task in the first place? If ptrace, I think we'd want it treated as a PTRACE_MODE_ATTACH (also used for /proc/pid/mem) rather than just PTRACE_MODE_READ (reading other /proc/pid info).
Signature · 8 lines
Stephen Smalley National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.
Quoted 27 lines · Stephen Smalley
Quoted 4 lines · Serge E. Hallyn
ipc/checkpoint_msg.c +0
-0<snip>
Quoted 21 lines
ipc/checkpoint_msg.c +12
-0@@ -175,11 +183,26 @@ static int load_ipc_msg_hdr(struct ckpt_ctx *ctx, struct msg_queue *msq) {int ret =0 ; +int secid =0 ; ret =restore_load_ipc_perms (&h->perms, &msq->q_perm);if (ret <0 )return ret; +if (h->perms.secref) { +struct sec_store *s; + s =ckpt_obj_fetch (ctx, h->perms.secref,CKPT_OBJ_SECURITY ); +if (IS_ERR (s)) +return PTR_ERR (s); + secid = s->secid; + } + ret =security_msg_queue_alloc (msq); +if (ret) +return ret; + ret =security_msg_queue_restore (msq, secid);
Quoted 8 lines
ipc/checkpoint_msg.c static int load_ipc_msg_hdr(struct ckpt_ctx *ctx, · line 204
Quoted 2 lines
ipc/checkpoint_msg.c +2
-0+if (ret <0 ) +return ret;I don't think you want to call
security_msg_queue_alloc()here, as that both allocates the security struct and performs the create check. So I would just call the_restore()function, and let it internally callipc_alloc_security()to allocate the struct but then apply its own distinct restore check. Likewise for the rest of them.
Ok, will change that.
Quoted 4 lines
Also, where do we get to veto attempts to checkpoint the task in the first place? If ptrace, I think we'd want it treated as a
PTRACE_MODE_ATTACH(also used for/proc/pid/mem) rather than justPTRACE_MODE_READ(reading other/proc/pidinfo).
The checkpointing of ipc objects goes through an ipcperms(perm, S_IROTH) check in ipc/checkpoint (at top of
http://git.ncl.cs.columbia.edu/?p=linux-cr.git;a=blob;f=ipc/checkpoint.c;h=88996e2b7abf328bd1b263400798ed5bd4924f48;hb=HEAD
)
But yes, for the task itself we check PTRACE_MODE_READ (line 280 in
http://git.ncl.cs.columbia.edu/?p=linux-cr.git;a=blob;f=checkpoint/checkpoint.c;h=a6dee4fb1085a47095f24443c48683a7fbc8ac59;hb=HEAD ) I had thought that PTRACE_MODE_ATTACH implied the permission to
actually modify the task. If it also can imply a "very invasive" read
then changing it certainly seems right.
thanks,
-serge
Quoted 37 lines · Serge E. Hallyn
Quoted 27 lines · Stephen Smalley
Quoted 4 lines · Serge E. Hallyn
ipc/checkpoint_msg.c +0
-0<snip>
Quoted 21 lines
ipc/checkpoint_msg.c +12
-0@@ -175,11 +183,26 @@ static int load_ipc_msg_hdr(struct ckpt_ctx *ctx, struct msg_queue *msq) {int ret =0 ; +int secid =0 ; ret =restore_load_ipc_perms (&h->perms, &msq->q_perm);if (ret <0 )return ret; +if (h->perms.secref) { +struct sec_store *s; + s =ckpt_obj_fetch (ctx, h->perms.secref,CKPT_OBJ_SECURITY ); +if (IS_ERR (s)) +return PTR_ERR (s); + secid = s->secid; + } + ret =security_msg_queue_alloc (msq); +if (ret) +return ret; + ret =security_msg_queue_restore (msq, secid);Quoted 8 lines
ipc/checkpoint_msg.c static int load_ipc_msg_hdr(struct ckpt_ctx *ctx, · line 204
Quoted 2 lines
ipc/checkpoint_msg.c +2
-0+if (ret <0 ) +return ret;I don't think you want to call
security_msg_queue_alloc()here, as that both allocates the security struct and performs the create check. So I would just call the_restore()function, and let it internally callipc_alloc_security()to allocate the struct but then apply its own distinct restore check. Likewise for the rest of them.
Quoted 1 line
Ok, will change that.
Hmm, but that means that if there is some new LSM which allocates memory in security_msg_queue_alloc(), but which does not define security_msg_queue_restore() (for some stupid reason), it'll end up causing a bug.
It's something we can certainly catch through code review, but do we want to set such a scenario up at all?
Speaking just for SELinux, the security_msg_queue_alloc() hook would return -EPERM only if the task calling sys_restart() wasn't allowed to create a msg queue with its own type, right? Is that something which is often disallowed?
I suppose we could have the default (cap_msg_queue_restore) call security_ops->msg_queue_alloc() - feels frail, but maybe it's ok...
thanks,
-serge
Quoted 45 lines · Serge E. Hallyn
Quoted 37 lines · Serge E. Hallyn
Quoted 27 lines · Stephen Smalley
Quoted 4 lines · Serge E. Hallyn
ipc/checkpoint_msg.c +0
-0<snip>
Quoted 21 lines
ipc/checkpoint_msg.c +12
-0@@ -175,11 +183,26 @@ static int load_ipc_msg_hdr(struct ckpt_ctx *ctx, struct msg_queue *msq) {int ret =0 ; +int secid =0 ; ret =restore_load_ipc_perms (&h->perms, &msq->q_perm);if (ret <0 )return ret; +if (h->perms.secref) { +struct sec_store *s; + s =ckpt_obj_fetch (ctx, h->perms.secref,CKPT_OBJ_SECURITY ); +if (IS_ERR (s)) +return PTR_ERR (s); + secid = s->secid; + } + ret =security_msg_queue_alloc (msq); +if (ret) +return ret; + ret =security_msg_queue_restore (msq, secid);Quoted 8 lines
ipc/checkpoint_msg.c static int load_ipc_msg_hdr(struct ckpt_ctx *ctx, · line 204
Quoted 2 lines
ipc/checkpoint_msg.c +2
-0+if (ret <0 ) +return ret;I don't think you want to call
security_msg_queue_alloc()here, as that both allocates the security struct and performs the create check. So I would just call the_restore()function, and let it internally callipc_alloc_security()to allocate the struct but then apply its own distinct restore check. Likewise for the rest of them.Quoted 1 line
Ok, will change that.
Hmm, but that means that if there is some new LSM which allocates memory in
security_msg_queue_alloc(), but which does not definesecurity_msg_queue_restore()(for some stupid reason), it'll end up causing a bug.
Quoted 7 lines
It's something we can certainly catch through code review, but do we want to set such a scenario up at all?
Speaking just for SELinux, the
security_msg_queue_alloc()hook would return-EPERMonly if the task callingsys_restart()wasn't allowed to create a msg queue with its own type, right? Is that something which is often disallowed?
Certainly some program domains lack permission to create ipc objects. The ipc _alloc hooks are unusual in that they combine both allocation and create checking unlike the rest of the object alloc hooks. I think that was discussed at the time, but people didn't want two different hook calls at the same call site.
Quoted 2 lines
I suppose we could have the default (
cap_msg_queue_restore) callsecurity_ops->msg_queue_alloc()- feels frail, but maybe it's ok...
Signature · 2 lines
Stephen Smalley National Security Agency
Quoted 54 lines · Stephen Smalley
Quoted 45 lines · Serge E. Hallyn
Quoted 37 lines · Serge E. Hallyn
Quoted 27 lines · Stephen Smalley
Quoted 4 lines · Serge E. Hallyn
ipc/checkpoint_msg.c +0
-0<snip>
Quoted 21 lines
ipc/checkpoint_msg.c +12
-0@@ -175,11 +183,26 @@ static int load_ipc_msg_hdr(struct ckpt_ctx *ctx, struct msg_queue *msq) {int ret =0 ; +int secid =0 ; ret =restore_load_ipc_perms (&h->perms, &msq->q_perm);if (ret <0 )return ret; +if (h->perms.secref) { +struct sec_store *s; + s =ckpt_obj_fetch (ctx, h->perms.secref,CKPT_OBJ_SECURITY ); +if (IS_ERR (s)) +return PTR_ERR (s); + secid = s->secid; + } + ret =security_msg_queue_alloc (msq); +if (ret) +return ret; + ret =security_msg_queue_restore (msq, secid);Quoted 8 lines
ipc/checkpoint_msg.c static int load_ipc_msg_hdr(struct ckpt_ctx *ctx, · line 204
Quoted 2 lines
ipc/checkpoint_msg.c +2
-0+if (ret <0 ) +return ret;I don't think you want to call
security_msg_queue_alloc()here, as that both allocates the security struct and performs the create check. So I would just call the_restore()function, and let it internally callipc_alloc_security()to allocate the struct but then apply its own distinct restore check. Likewise for the rest of them.Quoted 1 line
Ok, will change that.
Hmm, but that means that if there is some new LSM which allocates memory in
security_msg_queue_alloc(), but which does not definesecurity_msg_queue_restore()(for some stupid reason), it'll end up causing a bug.Quoted 7 lines
It's something we can certainly catch through code review, but do we want to set such a scenario up at all?
Speaking just for SELinux, the
security_msg_queue_alloc()hook would return-EPERMonly if the task callingsys_restart()wasn't allowed to create a msg queue with its own type, right? Is that something which is often disallowed?
Quoted 5 lines
Certainly some program domains lack permission to create ipc objects. The ipc
_allochooks are unusual in that they combine both allocation and create checking unlike the rest of the object alloc hooks. I think that was discussed at the time, but people didn't want two different hook calls at the same call site.
Oh, no. I wasn't thinking right.
The objects are actually restored through calls to do_shmget() etc, so that security_xyz_alloc() already gets called.
So I think we'll just leave it as is right now, acknowledging that it might become problematic if we want to confine a restart_t domain to be able to restore but not alloc any ipcs. The actual ramifications of that still somewhat escape me, but I do prefer having the common helpers used whenever possible to recreate objects.
thanks,
-serge
Quoted 61 lines · Serge E. Hallyn
Quoted 54 lines · Stephen Smalley
Quoted 45 lines · Serge E. Hallyn
Quoted 37 lines · Serge E. Hallyn
Quoted 27 lines · Stephen Smalley
Quoted 4 lines · Serge E. Hallyn
ipc/checkpoint_msg.c +0
-0<snip>
Quoted 21 lines
ipc/checkpoint_msg.c +12
-0@@ -175,11 +183,26 @@ static int load_ipc_msg_hdr(struct ckpt_ctx *ctx, struct msg_queue *msq) {int ret =0 ; +int secid =0 ; ret =restore_load_ipc_perms (&h->perms, &msq->q_perm);if (ret <0 )return ret; +if (h->perms.secref) { +struct sec_store *s; + s =ckpt_obj_fetch (ctx, h->perms.secref,CKPT_OBJ_SECURITY ); +if (IS_ERR (s)) +return PTR_ERR (s); + secid = s->secid; + } + ret =security_msg_queue_alloc (msq); +if (ret) +return ret; + ret =security_msg_queue_restore (msq, secid);Quoted 8 lines
ipc/checkpoint_msg.c static int load_ipc_msg_hdr(struct ckpt_ctx *ctx, · line 204
Quoted 2 lines
ipc/checkpoint_msg.c +2
-0+if (ret <0 ) +return ret;I don't think you want to call
security_msg_queue_alloc()here, as that both allocates the security struct and performs the create check. So I would just call the_restore()function, and let it internally callipc_alloc_security()to allocate the struct but then apply its own distinct restore check. Likewise for the rest of them.Quoted 1 line
Ok, will change that.
Hmm, but that means that if there is some new LSM which allocates memory in
security_msg_queue_alloc(), but which does not definesecurity_msg_queue_restore()(for some stupid reason), it'll end up causing a bug.Quoted 7 lines
It's something we can certainly catch through code review, but do we want to set such a scenario up at all?
Speaking just for SELinux, the
security_msg_queue_alloc()hook would return-EPERMonly if the task callingsys_restart()wasn't allowed to create a msg queue with its own type, right? Is that something which is often disallowed?Quoted 5 lines
Certainly some program domains lack permission to create ipc objects. The ipc
_allochooks are unusual in that they combine both allocation and create checking unlike the rest of the object alloc hooks. I think that was discussed at the time, but people didn't want two different hook calls at the same call site.
Quoted 4 lines
Oh, no. I wasn't thinking right.
The objects are actually restored through calls to
do_shmget()etc, so thatsecurity_xyz_alloc()already gets called.
Does this mean that the objects temporarily exist in the wrong security context and are accessible to other threads during the interval between creation and when they get "restored" to the right security context?
Quoted 5 lines
So I think we'll just leave it as is right now, acknowledging that it might become problematic if we want to confine a
restart_tdomain to be able to restore but not alloc any ipcs. The actual ramifications of that still somewhat escape me, but I do prefer having the common helpers used whenever possible to recreate objects.
Signature · 2 lines
Stephen Smalley National Security Agency
Quoted 9 lines · Stephen Smalley
Quoted 4 lines · Serge E. Hallyn
Oh, no. I wasn't thinking right.
The objects are actually restored through calls to
do_shmget()etc, so thatsecurity_xyz_alloc()already gets called.Does this mean that the objects temporarily exist in the wrong security context and are accessible to other threads during the interval between creation and when they get "restored" to the right security context?
They get restored in a private IPC namespace so they aren't accessible to any live tasks. Also, the objects will be created using the default context for the program doing sys_restore(), running as app_restore_t or something, so presumably a policy could ensure that such temporary objects aren't readable by anyone else, just in case something goes wrong before the security_ipcxyz_restore(), right?
-serge
--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.
Quoted 11 lines · Serge E. Hallyn
Quoted 9 lines · Stephen Smalley
Quoted 4 lines · Serge E. Hallyn
Oh, no. I wasn't thinking right.
The objects are actually restored through calls to
do_shmget()etc, so thatsecurity_xyz_alloc()already gets called.Does this mean that the objects temporarily exist in the wrong security context and are accessible to other threads during the interval between creation and when they get "restored" to the right security context?
Quoted 6 lines
They get restored in a private IPC namespace so they aren't accessible to any live tasks. Also, the objects will be created using the default context for the program doing
sys_restore(), running asapp_restore_tor something, so presumably a policy could ensure that such temporary objects aren't readable by anyone else, just in case something goes wrong before thesecurity_ipcxyz_restore(), right?
That could be confusing if the program ever needs to legitimately create any objects of its own for other purposes. But the private IPC namespace should be sufficient.
Signature · 2 lines
Stephen Smalley National Security Agency
Quoted 2 lines · Serge E. Hallyn
Quoted 1 line · Stephen Smalley
On Fri, 2009-06-19 at 20:32 -0500, Serge E. Hallyn wrote:
[...]
Quoted 10 lines
Quoted 4 lines
Also, where do we get to veto attempts to checkpoint the task in the first place? If ptrace, I think we'd want it treated as a
PTRACE_MODE_ATTACH(also used for/proc/pid/mem) rather than justPTRACE_MODE_READ(reading other/proc/pidinfo).The checkpointing of ipc objects goes through an
ipcperms(perm, S_IROTH)check in ipc/checkpoint (at top of
http://git.ncl.cs.columbia.edu/?p=linux-cr.git;a=blob;f=ipc/checkpoint.c;h=88996e2b7abf328bd1b263400798ed5bd4924f48;hb=HEAD
)
Quoted 5 lines
But yes, for the task itself we check
PTRACE_MODE_READ(line 280 in
http://git.ncl.cs.columbia.edu/?p=linux-cr.git;a=blob;f=checkpoint/checkpoint.c;h=a6dee4fb1085a47095f24443c48683a7fbc8ac59;hb=HEAD ) I had thought thatPTRACE_MODE_ATTACHimplied the permission to
actually modify the task. If it also can imply a "very invasive" read
then changing it certainly seems right.
Hmmm... I was unaware of this: http://lwn.net/Articles/282930/
So yes, probably need to change that.
Oren.