add lsm name and lsm_info (policy header) to container info
Subsystems (5)
PATCH 1/4 add lsm name and lsm_info (policy header) to container info
The LSM name is 'selinux', 'smack', 'tomoyo', or 'dummy'. We add that to the container configuration section. We also add a LSM policy configuration section. That is placed after the LSM name. It is written by the LSM in security_checkpoint_header(), called during checkpoint container(), and read by the LSM during security_may_restart(), which is called from restore_lsm() in restore_container().
--- Documentation/checkpoint/readme.txt | 24 ++++++++++++++ checkpoint/checkpoint.c | 13 +++++++- checkpoint/restart.c | 41 ++++++++++++++++++++++++ checkpoint/sys.c | 21 ++++++++++++ include/linux/checkpoint.h | 7 +++- include/linux/checkpoint_hdr.h | 16 +++++++++ include/linux/checkpoint_types.h | 2 + include/linux/security.h | 58 +++++++++++++++++++++++++++++++++++ security/capability.c | 24 ++++++++++++++ security/security.c | 26 +++++++++++++++ 10 files changed, 230 insertions(+), 2 deletions(-)
Documentation/checkpoint/readme.txt +24 -0
@@ -340,6 +340,30 @@ So that's why we don't want CAP_SYS_ADMIN required up-front. That way we will be forced to more carefully review each of those features. However, this can be controlled with a sysctl-variable. +LSM +=== + +Security modules use custom labels on subjects and objects to +further mediate access decisions beyond DAC controls. When +checkpoint applications, these labels are [ work in progress ] +checkpointed along with the objects. At restart, the +RESTART_KEEP_LSM flag tells the kernel whether re-created objects +whould keep their checkpointed labels, or get automatically +recalculated labels. Since checkpointed labels will only make +sense to the same LSM which was active at checkpoint time, +sys_restart() with the RESTART_KEEP_LSM flag will fail with +-EINVAL if the LSM active at restart is not the same as that +active at checkpoint. If RESTART_KEEP_LSM is not specified, +then objects will be given whatever default labels the LSM and +their optional policy decide. Of course, when RESTART_KEEP_LSM +is specified, the LSM may choose a different label than the +checkpointed one, or fail the entire restart if the caller +does not have permission to create objects with the checkpointed +label. + +It should always be safe to take a checkpoint of an application +under LSM_1, and restart it without the RESTART_KEEP_LSM flag +under LSM_2. Kernel interfaces =================
checkpoint/checkpoint.c +12 -1
@@ -366,7 +366,18 @@ static int checkpoint_container(struct ckpt_ctx *ctx) ret =ckpt_write_obj (ctx, &h->h);ckpt_hdr_put (ctx, h); -return ret; +if (ret <0 ) +return ret; + +memset (ctx->lsm_name,0 ,CHECKPOINT_LSM_NAME_MAX +1 ); +strlcpy (ctx->lsm_name,security_get_lsm_name (), +CHECKPOINT_LSM_NAME_MAX +1 ); + ret =ckpt_write_buffer (ctx, ctx->lsm_name, +CHECKPOINT_LSM_NAME_MAX +1 ); +if (ret <0 ) +return ret; + +return security_checkpoint_header (ctx); }/* write the checkpoint trailer */
checkpoint/restart.c +41 -0
53 lines not on this page · raw message
checkpoint/sys.c +21 -0
@@ -169,6 +169,27 @@ void *ckpt_hdr_get_type(struct ckpt_ctx *ctx, int len, int type)return h; } +#define DUMMY_LSM_INFO "dummy" + +int ckpt_write_dummy_lsm_info (struct ckpt_ctx *ctx) +{ +return ckpt_write_obj_type (ctx,DUMMY_LSM_INFO , +strlen (DUMMY_LSM_INFO ),CKPT_HDR_LSM_INFO ); +} + +/* +* ckpt_snarf_lsm_info +* If there is a CKPT_HDR_LSM_INFO field, toss it. +* Used when the current LSM doesn't care about this field. +*/ +void ckpt_snarf_lsm_info (struct ckpt_ctx *ctx) +{ +struct ckpt_hdr *h; + + h =ckpt_read_buf_type (ctx,CKPT_LSM_INFO_LEN ,CKPT_HDR_LSM_INFO ); +if (!IS_ERR (h)) +ckpt_hdr_put (ctx, h); +}/* * Helpers to manage c/r contexts: allocated for each checkpoint and/or
include/linux/checkpoint.h +6 -1
@@ -10,7 +10,7 @@* distribution for more details. */ -#define CHECKPOINT_VERSION 3 +#define CHECKPOINT_VERSION 4/* checkpoint user flags */ #define CHECKPOINT_SUBTREE 0x1
@@ -19,6 +19,7 @@#define RESTART_TASKSELF 0x1#define RESTART_FROZEN 0x2#define RESTART_GHOST 0x4 +#define RESTART_KEEP_LSM 0x8#ifdef __KERNEL__#ifdef CONFIG_CHECKPOINT
@@ -48,7 +49,9 @@#define RESTART_USER_FLAGS \ (RESTART_TASKSELF | \ RESTART_FROZEN | \ + RESTART_KEEP_LSM | \ RESTART_GHOST) +#define CKPT_LSM_INFO_LEN 200 extern int walk_task_subtree(struct task_struct *task, int (*func)(struct task_struct *, void *),
@@ -62,6 +65,8 @@ extern void _ckpt_hdr_put(struct ckpt_ctx *ctx, void *ptr, int n);extern void ckpt_hdr_put (struct ckpt_ctx *ctx,void *ptr);extern void *ckpt_hdr_get (struct ckpt_ctx *ctx,int n);extern void *ckpt_hdr_get_type (struct ckpt_ctx *ctx,int n,int type); +extern int ckpt_write_dummy_lsm_info (struct ckpt_ctx *ctx); +extern void ckpt_snarf_lsm_info (struct ckpt_ctx *ctx);extern int ckpt_write_obj (struct ckpt_ctx *ctx,struct ckpt_hdr *h); extern int ckpt_write_obj_type(struct ckpt_ctx *ctx,
include/linux/checkpoint_hdr.h +16 -0
@@ -27,6 +27,15 @@#endif /* +* /usr/include/linux/security.h is not exported to userspace, so +* we need this value here for userspace restart.c to read. +* +* CHECKPOINT_LSM_NAME_MAX should be SECURITY_NAME_MAX +* security_may_restart() has a BUILD_BUG_ON to enforce that. +*/ +#define CHECKPOINT_LSM_NAME_MAX 10 + +/* * To maintain compatibility between 32-bit and 64-bit architecture flavors, * keep data 64-bit aligned: use padding for structure members, and use * __attribute__((aligned (8))) for the entire structure.
@@ -71,6 +80,8 @@ enum {#define CKPT_HDR_STRING CKPT_HDR_STRING CKPT_HDR_OBJREF,#define CKPT_HDR_OBJREF CKPT_HDR_OBJREF + CKPT_HDR_LSM_INFO, +#define CKPT_HDR_LSM_INFO CKPT_HDR_LSM_INFO CKPT_HDR_TREE = 101,#define CKPT_HDR_TREE CKPT_HDR_TREE
@@ -252,6 +263,11 @@ struct ckpt_const {/* container configuration section header */ struct ckpt_hdr_container {struct ckpt_hdr h; +/* +* the header is followed by the string: +* char lsm_name[SECURITY_NAME_MAX + 1] +* plus the CKPT_HDR_LSM_INFO section +*/ };/* checkpoint image header */
include/linux/checkpoint_types.h +2 -0
@@ -21,6 +21,7 @@#include <linux/fs.h> #include <linux/ktime.h> #include <linux/wait.h> +#include <linux/security.h> struct ckpt_stats {int uts_ns;
@@ -42,6 +43,7 @@ struct ckpt_ctx {struct task_struct *root_task;/* [container] root task */ struct nsproxy *root_nsproxy;/* [container] root nsproxy */ struct task_struct *root_freezer;/* [container] root task */ +char lsm_name[SECURITY_NAME_MAX +1 ];/* security module at ckpt */ unsigned long kflags;/* kerenl flags */ unsigned long uflags;/* user flags */
include/linux/security.h +58 -0
94 lines not on this page · raw message
security/capability.c +24 -0
@@ -792,6 +792,26 @@ static void cap_release_secctx(char *secdata, u32 seclen) { } +#ifdef CONFIG_CHECKPOINT +static int cap_may_restart (struct ckpt_ctx *ctx) +{ +/* +* Note that all construction of kernel resources, credentials, +* etc is already authorized per the caller's credentials. This +* hook is intended for the LSM to make further decisions about +* a task not being allowed to restart at all, for instance if +* the policy has changed since checkpoint. +*/ +ckpt_snarf_lsm_info (ctx); +return 0 ; +} + +static int cap_checkpoint_header (struct ckpt_ctx *ctx) +{ +return ckpt_write_dummy_lsm_info (ctx); +} +#endif +#ifdef CONFIG_KEYS static int cap_key_alloc (struct key *key,const struct cred *cred,unsigned long flags)
@@ -992,6 +1012,10 @@ void security_fixup_ops(struct security_operations *ops)set_to_cap_if_null (ops, secid_to_secctx);set_to_cap_if_null (ops, secctx_to_secid);set_to_cap_if_null (ops, release_secctx); +#ifdef CONFIG_CHECKPOINT +set_to_cap_if_null (ops, may_restart); +set_to_cap_if_null (ops, checkpoint_header); +#endif #ifdef CONFIG_SECURITY_NETWORK set_to_cap_if_null (ops, unix_stream_connect);set_to_cap_if_null (ops, unix_may_send);
security/security.c +26 -0
@@ -16,6 +16,9 @@#include <linux/init.h> #include <linux/kernel.h> #include <linux/security.h> +#ifdef CONFIG_CHECKPOINT +#include <linux/checkpoint.h> +#endif /* Boot-time LSM user choice */ static __initdata char chosen_lsm[SECURITY_NAME_MAX +1 ];
@@ -122,6 +125,11 @@ int register_security(struct security_operations *ops)return 0 ; } +char *security_get_lsm_name (void ) +{ +return security_ops->name; +} +/* Security operations */ int security_ptrace_may_access (struct task_struct *child,unsigned int mode)
@@ -959,6 +967,24 @@ void security_release_secctx(char *secdata, u32 seclen) }EXPORT_SYMBOL (security_release_secctx); +#ifdef CONFIG_CHECKPOINT +int security_may_restart (struct ckpt_ctx *ctx) +{ +/* +* SECURITY_NAME_MAX is defined in linux/security.h, +* CHECKPOINT_LSM_NAME_MAX in linux/checkpoint_hdr.h +*/ +BUILD_BUG_ON (CHECKPOINT_LSM_NAME_MAX !=SECURITY_NAME_MAX ); + +return security_ops->may_restart (ctx); +} + +int security_checkpoint_header (struct ckpt_ctx *ctx) +{ +return security_ops->checkpoint_header (ctx); +} +#endif +#ifdef CONFIG_SECURITY_NETWORK int security_unix_stream_connect(struct socket *sock, struct socket *other,
Signature · 1 line
1.6.1
A message that is not in the archive (sent off-list or not yet received): 20091019144315.GA30535-r/[email protected]
PATCH 2/4 cr: add generic LSM c/r support (v6)
Documentation/checkpoint/readme.txt begins:
"""
Application checkpoint/restart is the ability to save the state of a running application so that it can later resume its execution from the time at which it was checkpointed.
"""
This patch adds generic support for c/r of LSM credentials. Support for Smack and SELinux (and TOMOYO if appropriate) will be added later. Capabilities is already supported through generic creds code.
This patch supports ipc_perm, msg_msg, cred (task) and file ->security fields. Inodes, superblocks, netif, and xfrm currently are restored not through sys_restart() but through container creation, and so the security fields should be done then as well. Network should be added when network c/r is added.
Briefly, all security fields must be exported by the LSM as a simple null-terminated string. They are checkpointed through the security_checkpoint_obj() helper, because we must pass it an extra sectype field. Splitting SECURITY_OBJ_SEC into one type per object type would not work because, in Smack, one void* security is used for all object types. But we must pass the sectype field because in SELinux a different type of structure is stashed in each object type.
The RESTART_KEEP_LSM flag indicates that the LSM should attempt to reuse checkpointed security labels. It is always invalid when the LSM at restart differs from that at checkpoint. It is currently only usable for capabilities.
(For capabilities, restart without RESTART_KEEP_LSM is technically not implemented. There actually might be a use case for that, but the safety of it is dubious so for now we always re-create checkpointed capability sets whether RESTART_KEEP_LSM is specified or not)
Changelog:
sep 3: fix memory leak on LSM restore error path
Sep 3: provide 2 hooks, may_restart and checkpoint_header, to facilitate
an LSM tracking policy changes.
sep 10: merge RESTART_KEEP_LSM patch with basic LSM c/r
support patches.
sep 10: rename security_xyz_get_ctx() to security_xyz_checkpoint(),
in order to avoid confusing with the various other 'context' helpers in the security_ namespace, relating to secids and sysfs xattrs.
sep 10: pass context file to security_cred_restore. SELinux will
want the file's security context to authorize it as an entrypoint for the new process context.
oct 01: roll up some generic c/r debug hunks from selinux patch. oct 05: address set of Oren comments, including:
1. fix memleak in restore_msg_contents_one
2. use a separate container checkpoint image section
3. define SECURITY_CTX_NONE
4. allocate the right size to l in security_checkpoint_obj
5. fix ckpt_hdr_lsm alignment
oct 09: at checkpoint, key on the void*security in the objhash,
and don't cache the ckpt_stored_lsm at all. At restart, do_restore_security (now moved to security/security.c) creates and caches the ckpt_stored_lsm.
oct 19: At checkpoint, we insert the void* security into the
objhash. The first time that we do so, we next write out the string representation of the context to the checkpoint image, along with the value of the objref for the void* security, and insert that into the objhash. Then at restart, when we read a LSM context, we read the objref which the void* security had at checkpoint, and we then insert the string context with that objref as well.
--- checkpoint/files.c | 29 ++++++- checkpoint/objhash.c | 102 +++++++++++++++++++++++ include/linux/checkpoint.h | 1 + include/linux/checkpoint_hdr.h | 20 +++++ include/linux/checkpoint_types.h | 7 ++ include/linux/security.h | 143 ++++++++++++++++++++++++++++++++ ipc/checkpoint.c | 21 ++--- ipc/checkpoint_msg.c | 17 +++- ipc/checkpoint_sem.c | 4 +- ipc/checkpoint_shm.c | 4 +- ipc/util.h | 6 +- kernel/cred.c | 29 ++++++- security/capability.c | 48 +++++++++++ security/security.c | 167 ++++++++++++++++++++++++++++++++++++++ 14 files changed, 571 insertions(+), 27 deletions(-)
checkpoint/files.c +27 -2
@@ -145,9 +145,25 @@ static int scan_fds(struct files_struct *files, int **fdtable)return n; } +#ifdef CONFIG_SECURITY +int checkpoint_file_security (struct ckpt_ctx *ctx,struct file *file, +int *secref) +{ +return security_checkpoint_obj (ctx, file->f_security, +CKPT_SECURITY_FILE , secref); +} +#else +int checkpoint_file_security (struct ckpt_ctx *ctx,struct file *file, +int *secref) +{ +return -EOPNOTSUPP ; +} +#endif +int checkpoint_file_common (struct ckpt_ctx *ctx,struct file *file,struct ckpt_hdr_file *h) { +int ret;struct cred *f_cred = (struct cred *) file->f_cred; h->f_flags = file->f_flags;
@@ -159,8 +175,12 @@ int checkpoint_file_common(struct ckpt_ctx *ctx, struct file *file,if (h->f_credref <0 )return h->f_credref; -ckpt_debug ("file %s credref %d" , file->f_dentry->d_name.name, - h->f_credref); + ret =checkpoint_file_security (ctx, file, &h->f_secref); +if (ret <0 ) +return ret; + +ckpt_debug ("file %s credref %d secref %d\n" , + file->f_dentry->d_name.name, h->f_credref, h->f_secref);/* FIX: need also file->f_owner, etc */
@@ -510,6 +530,11 @@ int restore_file_common(struct ckpt_ctx *ctx, struct file *file,put_cred (file->f_cred); file->f_cred =get_cred (cred); + ret =security_restore_obj (ctx, (void *) file,CKPT_SECURITY_FILE , + h->f_secref); +if (ret <0 ) +return ret; +/* 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);if (ret <0 )
checkpoint/objhash.c +102 -0
123 lines not on this page · raw message
include/linux/checkpoint.h +1 -0
@@ -52,6 +52,7 @@ RESTART_KEEP_LSM | \ RESTART_GHOST)#define CKPT_LSM_INFO_LEN 200 +#define CKPT_LSM_STRING_MAX 1024 extern int walk_task_subtree(struct task_struct *task, int (*func)(struct task_struct *, void *),
include/linux/checkpoint_hdr.h +20 -0
@@ -82,6 +82,8 @@ enum {#define CKPT_HDR_OBJREF CKPT_HDR_OBJREF CKPT_HDR_LSM_INFO,#define CKPT_HDR_LSM_INFO CKPT_HDR_LSM_INFO + CKPT_HDR_SECURITY, +#define CKPT_HDR_SECURITY CKPT_HDR_SECURITY CKPT_HDR_TREE = 101,#define CKPT_HDR_TREE CKPT_HDR_TREE
@@ -234,6 +236,10 @@ enum obj_type {#define CKPT_OBJ_SOCK CKPT_OBJ_SOCK CKPT_OBJ_TTY,#define CKPT_OBJ_TTY CKPT_OBJ_TTY + CKPT_OBJ_SECURITY_PTR, +#define CKPT_OBJ_SECURITY_PTR CKPT_OBJ_SECURITY_PTR + CKPT_OBJ_SECURITY, +#define CKPT_OBJ_SECURITY CKPT_OBJ_SECURITY CKPT_OBJ_MAX#define CKPT_OBJ_MAX CKPT_OBJ_MAX };
@@ -364,6 +370,7 @@ struct ckpt_hdr_cred {__u32 gid, sgid, egid, fsgid;__s32 user_ref;__s32 groupinfo_ref; +__s32 sec_ref;struct ckpt_capabilities cap_s; } __attribute__((aligned(8)));
@@ -376,6 +383,16 @@ struct ckpt_hdr_groupinfo {__u32 groups[0 ]; } __attribute__((aligned(8))); +struct ckpt_hdr_lsm { +struct ckpt_hdr h; +__s32 ptrref; +__u8 sectype; +__u8 padding; +/* +* This is followed by a string of size len+1, +* null-terminated +*/ +} __attribute__((aligned (8 )));/* * todo - keyrings and LSM * These may be better done with userspace help though
@@ -505,6 +522,7 @@ struct ckpt_hdr_file {__s32 f_credref;__u64 f_pos;__u64 f_version; +__s32 f_secref; } __attribute__((aligned(8)));struct ckpt_hdr_file_generic {
@@ -765,6 +783,7 @@ struct ckpt_hdr_ipc_perms {__u32 mode;__u32 _padding;__u64 seq; +__s32 sec_ref; } __attribute__((aligned(8)));struct ckpt_hdr_ipc_shm {
@@ -798,6 +817,7 @@ struct ckpt_hdr_ipc_msg_msg {struct ckpt_hdr h;__s32 m_type;__u32 m_ts; +__s32 sec_ref; } __attribute__((aligned(8)));struct ckpt_hdr_ipc_sem {
include/linux/checkpoint_types.h +7 -0
@@ -89,6 +89,13 @@ struct ckpt_ctx {#endif }; +/* stored on hashtable */ +struct ckpt_lsm_string { +struct kref kref; +int sectype;/* Containing object (file,cred,&c) */ +int ptrref;/* the objref for the void* security */ +char *string; +};#endif /* __KERNEL__ */ #endif /* _LINUX_CHECKPOINT_TYPES_H_ */
include/linux/security.h +143 -0
240 lines not on this page · raw message
ipc/checkpoint.c +8 -13
@@ -31,7 +31,8 @@ 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) {if (ipcperms (perm,S_IROTH ))
@@ -45,8 +46,8 @@ int checkpoint_fill_ipc_perms(struct ckpt_hdr_ipc_perms *h, h->cgid = perm->cgid; h->mode = perm->mode &S_IRWXUGO ; h->seq = perm->seq; - -return 0 ; +return security_checkpoint_obj (ctx, perm->security,CKPT_SECURITY_IPC , + &h->sec_ref); } static int checkpoint_ipc_any(struct ckpt_ctx *ctx,
@@ -176,7 +177,8 @@ static int validate_created_perms(struct ckpt_hdr_ipc_perms *h)return 1 ; } -int restore_load_ipc_perms (struct ckpt_hdr_ipc_perms *h, +int restore_load_ipc_perms (struct ckpt_ctx *ctx, +struct ckpt_hdr_ipc_perms *h,struct kern_ipc_perm *perm) {if (h->id <0 )
@@ -205,16 +207,9 @@ int restore_load_ipc_perms(struct ckpt_hdr_ipc_perms *h, perm->cgid = h->cgid; 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 ; +return security_restore_obj (ctx, (void *)perm,CKPT_SECURITY_IPC , + h->sec_ref); } static int restore_ipc_any(struct ckpt_ctx *ctx, struct ipc_namespace *ipc_ns,
ipc/checkpoint_msg.c +14 -3
@@ -37,7 +37,7 @@ static int fill_ipc_msg_hdr(struct ckpt_ctx *ctx,ipc_lock_by_ptr (&msq->q_perm); - ret =checkpoint_fill_ipc_perms (&h->perms, &msq->q_perm); + ret =checkpoint_fill_ipc_perms (ctx, &h->perms, &msq->q_perm);if (ret <0 ) goto unlock;
@@ -63,14 +63,20 @@ static int checkpoint_msg_contents(struct ckpt_ctx *ctx, struct msg_msg *msg)struct ckpt_hdr_ipc_msg_msg *h;struct msg_msgseg *seg;int total, len; -int ret; +int secref, ret; + ret =security_checkpoint_obj (ctx, msg->security, +CKPT_SECURITY_MSG_MSG , + &secref); +if (ret <0 ) +return ret; h =ckpt_hdr_get_type (ctx,sizeof (*h),CKPT_HDR_IPC_MSG_MSG );if (!h)return -ENOMEM ; h->m_type = msg->m_type; h->m_ts = msg->m_ts; + h->sec_ref = secref; ret =ckpt_write_obj (ctx, &h->h);ckpt_hdr_put (ctx, h);
@@ -177,7 +183,7 @@ static int load_ipc_msg_hdr(struct ckpt_ctx *ctx, {int ret =0 ; - ret =restore_load_ipc_perms (&h->perms, &msq->q_perm); + ret =restore_load_ipc_perms (ctx, &h->perms, &msq->q_perm);if (ret <0 )return ret;
@@ -224,6 +230,11 @@ static struct msg_msg *restore_msg_contents_one(struct ckpt_ctx *ctx, int *clen) msg->next =NULL ; pseg = &msg->next; + ret =security_restore_obj (ctx, (void *) msg,CKPT_SECURITY_MSG_MSG , + h->sec_ref); +if (ret <0 ) + goto out; + ret =_ckpt_read_buffer (ctx, (msg +1 ), len);if (ret <0 ) goto out;
ipc/checkpoint_sem.c +2 -2
@@ -37,7 +37,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;
@@ -113,7 +113,7 @@ static int load_ipc_sem_hdr(struct ckpt_ctx *ctx, {int ret =0 ; - ret =restore_load_ipc_perms (&h->perms, &sem->sem_perm); + ret =restore_load_ipc_perms (ctx, &h->perms, &sem->sem_perm);if (ret <0 )return ret;
ipc/checkpoint_shm.c +2 -2
@@ -41,7 +41,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;
@@ -165,7 +165,7 @@ static int load_ipc_shm_hdr(struct ckpt_ctx *ctx, {int ret; - ret =restore_load_ipc_perms (&h->perms, &shp->shm_perm); + ret =restore_load_ipc_perms (ctx, &h->perms, &shp->shm_perm);if (ret <0 )return ret;
ipc/util.h +4 -2
@@ -199,9 +199,11 @@ void freeary(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, +extern int restore_load_ipc_perms (struct ckpt_ctx *ctx, +struct ckpt_hdr_ipc_perms *h,struct kern_ipc_perm *perm);extern int ckpt_collect_ipc_shm (int id,void *p,void *data);
kernel/cred.c +26 -3
@@ -706,10 +706,25 @@ int cred_setfsgid(struct cred *new, gid_t gid, gid_t *old_fsgid) }#ifdef CONFIG_CHECKPOINT +#ifdef CONFIG_SECURITY +int checkpoint_cred_security (struct ckpt_ctx *ctx,struct cred *cred, +int *secref) +{ +return security_checkpoint_obj (ctx, cred->security, +CKPT_SECURITY_CRED , secref); +} +#else +int checkpoint_cred_security (struct ckpt_ctx *ctx,struct cred *cred, +int *secref) +{ +return -EOPNOTSUPP ; +} +#endif +static int do_checkpoint_cred (struct ckpt_ctx *ctx,struct cred *cred) {int ret; -int groupinfo_ref, user_ref; +int groupinfo_ref, user_ref, secref;struct ckpt_hdr_cred *h; groupinfo_ref = checkpoint_obj(ctx, cred->group_info,
@@ -719,13 +734,16 @@ static int do_checkpoint_cred(struct ckpt_ctx *ctx, struct cred *cred) user_ref =checkpoint_obj (ctx, cred->user,CKPT_OBJ_USER );if (user_ref <0 )return user_ref; + ret =checkpoint_cred_security (ctx, cred, &secref); +if (ret <0 ) +return ret; h =ckpt_hdr_get_type (ctx,sizeof (*h),CKPT_HDR_CRED );if (!h)return -ENOMEM ; -ckpt_debug ("cred uid %d fsuid %d gid %d\n" , cred->uid, cred->fsuid, - cred->gid); +ckpt_debug ("cred uid %d fsuid %d gid %d secref %d\n" , cred->uid, + cred->fsuid, cred->gid, secref); h->uid = cred->uid; h->suid = cred->suid; h->euid = cred->euid;
@@ -735,6 +753,7 @@ static int do_checkpoint_cred(struct ckpt_ctx *ctx, struct cred *cred) h->sgid = cred->sgid; h->egid = cred->egid; h->fsgid = cred->fsgid; + h->sec_ref = secref;checkpoint_capabilities (&h->cap_s, cred);
@@ -808,6 +827,10 @@ static struct cred *do_restore_cred(struct ckpt_ctx *ctx) ret =cred_setfsgid (cred, h->fsgid, &oldgid);if (oldgid != h->fsgid && ret <0 ) goto err_putcred; + ret =security_restore_obj (ctx, (void *) cred,CKPT_SECURITY_CRED , + h->sec_ref); +if (ret) + goto err_putcred; ret =restore_capabilities (&h->cap_s, cred);if (ret) goto err_putcred;
security/capability.c +48 -0
90 lines not on this page · raw message
security/security.c +167 -0
193 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): 20091019144341.GA30566-r/[email protected]
Re: [PATCH 2/4] cr: add generic LSM c/r support (v6)
Quoted 35 lines · Serge E. Hallyn
Documentation/checkpoint/readme.txtbegins:
"""
Application checkpoint/restart is the ability to save the state of a running application so that it can later resume its execution from the time at which it was checkpointed.
"""This patch adds generic support for c/r of LSM credentials. Support for Smack and SELinux (and TOMOYO if appropriate) will be added later. Capabilities is already supported through generic creds code.
This patch supports
ipc_perm,msg_msg, cred (task) and file ->security fields. Inodes, superblocks, netif, and xfrm currently are restored not throughsys_restart()but through container creation, and so the security fields should be done then as well. Network should be added when network c/r is added.Briefly, all security fields must be exported by the LSM as a simple null-terminated string. They are checkpointed through the
security_checkpoint_obj()helper, because we must pass it an extra sectype field. SplittingSECURITY_OBJ_SECinto one type per object type would not work because, in Smack, one void* security is used for all object types. But we must pass the sectype field because in SELinux a different type of structure is stashed in each object type.The
RESTART_KEEP_LSMflag indicates that the LSM should attempt to reuse checkpointed security labels. It is always invalid when the LSM at restart differs from that at checkpoint. It is currently only usable for capabilities.(For capabilities, restart without
RESTART_KEEP_LSMis technically not implemented. There actually might be a use case for that, but the safety of it is dubious so for now we always re-create checkpointed capability sets whetherRESTART_KEEP_LSMis specified or not)
[...]
Quoted 8 lines
oct 19: At checkpoint, we insert the void* security into the
objhash. The first time that we do so, we next write out the string representation of the context to the checkpoint image, along with the value of the objref for the void* security, and insert that into the objhash. Then at restart, when we read a LSM context, we read the objref which the void* security had at checkpoint, and we then insert the string context with that objref as well.
I hoped to see similar comment inlined in the code.
[...]
checkpoint/files.c int checkpoint_file_common(struct ckpt_ctx *ctx, struct file *file, · line 180
Quoted 9 lines
checkpoint/files.c +3
-2@@ -159,8 +175,12 @@ int checkpoint_file_common(struct ckpt_ctx *ctx, struct file *file,if (h->f_credref <0 )return h->f_credref; -ckpt_debug ("file %s credref %d" , file->f_dentry->d_name.name, - h->f_credref); + ret =checkpoint_file_security (ctx, file, &h->f_secref); +if (ret <0 ) +return ret;
How about a ckpt_write_err() here, or in checkpoint_file_security(), or in security_checkpoint_obj(), or all of the above.
Quoted 3 lines
checkpoint/files.c +3
-0+ +ckpt_debug ("file %s credref %d secref %d\n" , + file->f_dentry->d_name.name, h->f_credref, h->f_secref);
[...]
checkpoint/objhash.c static struct ckpt_obj_ops ckpt_obj_ops[] = { · line 473
Quoted 11 lines
checkpoint/objhash.c +7
-0@@ -433,6 +464,22 @@ static struct ckpt_obj_ops ckpt_obj_ops[] = { .checkpoint = checkpoint_tty, .restore = restore_tty, }, +/* LSM void *security on objhash - at checkpoint */ + { + .obj_name = "SECURITY PTR", + .obj_type = CKPT_OBJ_SECURITY_PTR, + .ref_drop = obj_no_drop, + .ref_grab = obj_no_grab, + },
I really wish there was a comment explaining why it's ok to not drop/grab the reference (because the security is always referenced by an object that is itself grabbed, e.g. file, ipc etc ?).
Quoted 10 lines
checkpoint/objhash.c +9
-0+/* LSM security strings - at restart */ + { + .obj_name = "SECURITY STRING", + .obj_type = CKPT_OBJ_SECURITY, + .ref_grab = lsm_string_grab, + .ref_drop = lsm_string_drop, + .checkpoint = checkpoint_lsm_string, + .restore = restore_lsm_string_wrap, + }, };
[...]
include/linux/checkpoint_hdr.h struct ckpt_hdr_groupinfo { · line 390
Quoted 9 lines
include/linux/checkpoint_hdr.h +5
-0@@ -376,6 +383,16 @@ struct ckpt_hdr_groupinfo {__u32 groups[0 ]; } __attribute__((aligned(8))); +struct ckpt_hdr_lsm { +struct ckpt_hdr h; +__s32 ptrref; +__u8 sectype; +__u8 padding;
I don't think padding is necessary here...
Quoted 5 lines
include/linux/checkpoint_hdr.h +5
-0+/* +* This is followed by a string of size len+1, +* null-terminated +*/ +} __attribute__((aligned(8)));
[...]
Quoted 7 lines
security/security.c +7
-0+/** +* security_checkpoint_obj - if first checkpoint of this void* security, +* then 1. ask the LSM for a string representing the context, 2. checkpoint +* that string +* @ctx: the checkpoint context +* @security: the void* security being checkpointed +* @sectype: indicates the type of object, because LSMs can (and do) store
security/security.c int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, · line 1332
Quoted 10 lines
security/security.c +10
-0+* @secref: We return the objref here +* different types of data for different types of objects. +* +* Returns the objref of the checkpointed ckpt_lsm_string representing the +* context, or -error on error. +* +* This is only used at checkpoint of course. +*/ +int security_checkpoint_obj (struct ckpt_ctx *ctx,void *security, +int sectype,int *secref)
This function returns 0 for success or a negative error. It should return the @secref instead of passing it by reference (see your description of the return value above !)
[...]
security/security.c int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, · line 1417
Quoted 5 lines
security/security.c +5
-0+/* Ask the LSM to apply a void*security to the object +* based on the checkpointed context string */ +switch (sectype) { +case CKPT_SECURITY_IPC : + ret =security_ipc_restore (v, l->string);
Nit: I know it's not strictly necessary, but adding an explicit type conversion here and in the other three seems cleaner
Quoted 8 lines
security/security.c +8
-0+break ; +case CKPT_SECURITY_MSG_MSG : + ret =security_msg_msg_restore (v, l->string); +break ; +case CKPT_SECURITY_FILE : + ret =security_file_restore (v, l->string); +break ; +case CKPT_SECURITY_CRED :
security/security.c int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, · line 1435
Quoted 10 lines
security/security.c +10
-0+ ret =security_cred_restore (ctx->file, v, l->string); +break ; +default : + ret = -EINVAL ; + } +if (ret) +ckpt_debug ("sectype %d objref %d lsm's hook returned %d\n" , + sectype, secref, ret); +if (ret == -EOPNOTSUPP ) + ret =0 ;
If you silently ignore EOPNOTSUPP, how can a user tell if a restarted succeeded fully or by silently skipping the security part ?
Should the user approve this behavior (e.g. RESTART_SECURITY_LAX...) ?
Also, I suggest the s/EOPNOTSUPP/ENOSYS/ all over the patch.
security/security.c int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, · line 1439
Quoted 4 lines
security/security.c +4
-0+ + return ret; +} +#endif
Oren.
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 2/4] cr: add generic LSM c/r support (v6)
Quoted 10 lines · Oren Laadan
Quoted 8 lines
oct 19: At checkpoint, we insert the void* security into the
objhash. The first time that we do so, we next write out the string representation of the context to the checkpoint image, along with the value of the objref for the void* security, and insert that into the objhash. Then at restart, when we read a LSM context, we read the objref which the void* security had at checkpoint, and we then insert the string context with that objref as well.I hoped to see similar comment inlined in the code.
If we're happy with this approach, then I will add good comments above security_checkpoint_obj and security_restore_obj, and above the objhash entries.
Quoted 6 lines
[...]
Quoted 4 lines
checkpoint/files.c +0
-0@@ -159,8 +175,12 @@ int checkpoint_file_common(struct ckpt_ctx *ctx, struct file *file,if (h->f_credref <0 )return h->f_credref;
Quoted 8 lines
checkpoint/files.c int checkpoint_file_common(struct ckpt_ctx *ctx, struct file *file, · line 180
Quoted 5 lines
checkpoint/files.c +3
-2-ckpt_debug ("file %s credref %d" , file->f_dentry->d_name.name, - h->f_credref); + ret =checkpoint_file_security (ctx, file, &h->f_secref); +if (ret <0 ) +return ret;How about a
ckpt_write_err()here, or incheckpoint_file_security(), or insecurity_checkpoint_obj(), or all of the above.
Yeah, definately, at each of the checkpoint failures I add.
Quoted 6 lines
Quoted 3 lines
checkpoint/files.c +3
-0+ +ckpt_debug ("file %s credref %d secref %d\n" , + file->f_dentry->d_name.name, h->f_credref, h->f_secref);[...]
Quoted 15 lines
checkpoint/objhash.c static struct ckpt_obj_ops ckpt_obj_ops[] = { · line 473
Quoted 11 lines
checkpoint/objhash.c +7
-0@@ -433,6 +464,22 @@ static struct ckpt_obj_ops ckpt_obj_ops[] = { .checkpoint = checkpoint_tty, .restore = restore_tty, }, +/* LSM void *security on objhash - at checkpoint */ + { + .obj_name = "SECURITY PTR", + .obj_type = CKPT_OBJ_SECURITY_PTR, + .ref_drop = obj_no_drop, + .ref_grab = obj_no_grab, + },I really wish there was a comment explaining why it's ok to not drop/grab the reference (because the security is always referenced by an object that is itself grabbed, e.g. file, ipc etc ?).
Yes.
Quoted 17 lines
Quoted 10 lines
checkpoint/objhash.c +9
-0+/* LSM security strings - at restart */ + { + .obj_name = "SECURITY STRING", + .obj_type = CKPT_OBJ_SECURITY, + .ref_grab = lsm_string_grab, + .ref_drop = lsm_string_drop, + .checkpoint = checkpoint_lsm_string, + .restore = restore_lsm_string_wrap, + }, };[...]
Quoted 4 lines
include/linux/checkpoint_hdr.h +0
-0@@ -376,6 +383,16 @@ struct ckpt_hdr_groupinfo {__u32 groups[0 ]; } __attribute__((aligned(8)));
Quoted 7 lines
include/linux/checkpoint_hdr.h struct ckpt_hdr_groupinfo { · line 390
Quoted 5 lines
include/linux/checkpoint_hdr.h +5
-0+struct ckpt_hdr_lsm { +struct ckpt_hdr h; +__s32 ptrref; +__u8 sectype; +__u8 padding;I don't think padding is necessary here...
Ok, I'll take it out.
Quoted 30 lines
Quoted 5 lines
include/linux/checkpoint_hdr.h +5
-0+/* +* This is followed by a string of size len+1, +* null-terminated +*/ +} __attribute__((aligned(8)));[...]
Quoted 7 lines
security/security.c +7
-0+/** +* security_checkpoint_obj - if first checkpoint of this void* security, +* then 1. ask the LSM for a string representing the context, 2. checkpoint +* that string +* @ctx: the checkpoint context +* @security: the void* security being checkpointed +* @sectype: indicates the type of object, because LSMs can (and do) store security/security.c int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, · line 1332
Quoted 10 lines
security/security.c +10
-0+* @secref: We return the objref here +* different types of data for different types of objects. +* +* Returns the objref of the checkpointed ckpt_lsm_string representing the +* context, or -error on error. +* +* This is only used at checkpoint of course. +*/ +int security_checkpoint_obj (struct ckpt_ctx *ctx,void *security, +int sectype,int *secref)This function returns 0 for success or a negative error. It should return the @secref instead of passing it by reference (see your description of the return value above !)
Quoted 1 line
[...]
Yes the comment is out of date but the API is imo an improvement. Note that SECURITY_CTX_NONE, -1, is a meaningful secref, and at the sametime -EPERM, -1, is conceivably a valid error code (though at the moment no lsm will return it).
So I think overloading the secref with error codes is wrong here.
Quoted 8 lines
security/security.c int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, · line 1417
Quoted 5 lines
security/security.c +5
-0+/* Ask the LSM to apply a void*security to the object +* based on the checkpointed context string */ +switch (sectype) { +case CKPT_SECURITY_IPC : + ret =security_ipc_restore (v, l->string);Nit: I know it's not strictly necessary, but adding an explicit type conversion here and in the other three seems cleaner
Hmm, it'll make some lines wrap making it harder to read, so it was a tossup. But ok I'll change it.
Quoted 13 lines
Quoted 13 lines
security/security.c +13
-0+break ; +case CKPT_SECURITY_MSG_MSG : + ret =security_msg_msg_restore (v, l->string); +break ; +case CKPT_SECURITY_FILE : + ret =security_file_restore (v, l->string); +break ; +case CKPT_SECURITY_CRED : + ret =security_cred_restore (ctx->file, v, l->string); +break ; +default : + ret = -EINVAL ; + }
Quoted 8 lines
security/security.c int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, · line 1435
Quoted 5 lines
security/security.c +5
-0+if (ret) +ckpt_debug ("sectype %d objref %d lsm's hook returned %d\n" , + sectype, secref, ret); +if (ret == -EOPNOTSUPP ) + ret =0 ;If you silently ignore EOPNOTSUPP, how can a user tell if a restarted succeeded fully or by silently skipping the security part ?
Actually I agree, EOPNOTSUPP (or ENOSYS) with RESTART_KEEP_LSM should just return failure.
Quoted 3 lines
Should the user approve this behavior (e.g.
RESTART_SECURITY_LAX...) ?Also, I suggest the s/EOPNOTSUPP/ENOSYS/ all over the patch.
thanks,
-serge
A message that is not in the archive (sent off-list or not yet received): 20091019190227.GA7201-r/[email protected]
Re: [PATCH 2/4] cr: add generic LSM c/r support (v6)
Quoted 14 lines · Serge E. Hallyn
Quoted 9 lines · Oren Laadan
Quoted 8 lines
oct 19: At checkpoint, we insert the void* security into the
objhash. The first time that we do so, we next write out the string representation of the context to the checkpoint image, along with the value of the objref for the void* security, and insert that into the objhash. Then at restart, when we read a LSM context, we read the objref which the void* security had at checkpoint, and we then insert the string context with that objref as well.I hoped to see similar comment inlined in the code.
If we're happy with this approach, then I will add good comments above
security_checkpoint_objandsecurity_restore_obj, and above the objhash entries.
[...]
Quoted 21 lines
Quoted 21 lines
Quoted 7 lines
security/security.c +7
-0+/** +* security_checkpoint_obj - if first checkpoint of this void* security, +* then 1. ask the LSM for a string representing the context, 2. checkpoint +* that string +* @ctx: the checkpoint context +* @security: the void* security being checkpointed +* @sectype: indicates the type of object, because LSMs can (and do) store security/security.c int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, · line 1332
Quoted 10 lines
security/security.c +10
-0+* @secref: We return the objref here +* different types of data for different types of objects. +* +* Returns the objref of the checkpointed ckpt_lsm_string representing the +* context, or -error on error. +* +* This is only used at checkpoint of course. +*/ +int security_checkpoint_obj (struct ckpt_ctx *ctx,void *security, +int sectype,int *secref)This function returns 0 for success or a negative error. It should return the @secref instead of passing it by reference (see your description of the return value above !)
Quoted 8 lines
Quoted 1 line
[...]
Yes the comment is out of date but the API is imo an improvement. Note that
SECURITY_CTX_NONE, -1, is a meaningful secref, and at the sametime-EPERM, -1, is conceivably a valid error code (though at the moment no lsm will return it).So I think overloading the secref with error codes is wrong here.
How about #define SECURITY_CTX_NONE 0 ?
it isn't a valid objref anyway.
[...]
Oren.
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 2/4] cr: add generic LSM c/r support (v6)
Quoted 48 lines · Oren Laadan
Quoted 14 lines · Serge E. Hallyn
Quoted 9 lines · Oren Laadan
Quoted 8 lines
oct 19: At checkpoint, we insert the void* security into the
objhash. The first time that we do so, we next write out the string representation of the context to the checkpoint image, along with the value of the objref for the void* security, and insert that into the objhash. Then at restart, when we read a LSM context, we read the objref which the void* security had at checkpoint, and we then insert the string context with that objref as well.I hoped to see similar comment inlined in the code.
If we're happy with this approach, then I will add good comments above
security_checkpoint_objandsecurity_restore_obj, and above the objhash entries.[...]
Quoted 28 lines
Quoted 21 lines
Quoted 7 lines
(quoted diff) +7
-0+/** + * security_checkpoint_obj - if first checkpoint of this void* security, + * then 1. ask the LSM for a string representing the context, 2. checkpoint + * that string + * @ctx: the checkpoint context + * @security: the void* security being checkpointed + * @sectype: indicates the type of object, because LSMs can (and do) storeReview
Quoted 10 lines
(quoted diff) +10
-0+ * @secref: We return the objref here + * different types of data for different types of objects. + * + * Returns the objref of the checkpointed ckpt_lsm_string representing the + * context, or -error on error. + * + * This is only used at checkpoint of course. + */ +int security_checkpoint_obj(struct ckpt_ctx *ctx, void *security, + int sectype, int *secref)This function returns 0 for success or a negative error. It should return the @secref instead of passing it by reference (see your description of the return value above !)
Quoted 1 line
[...]
Yes the comment is out of date but the API is imo an improvement. Note that
SECURITY_CTX_NONE, -1, is a meaningful secref, and at the sametime-EPERM, -1, is conceivably a valid error code (though at the moment no lsm will return it).
Quoted 4 lines
Quoted 1 line
So I think overloading the secref with error codes is wrong here.
How about #define
SECURITY_CTX_NONE0 ?
it isn't a valid objref anyway.
Ok, I thought we'd decided using 0 wasn't right for some reason, but I'll do that then.
-serge
A message that is not in the archive (sent off-list or not yet received): 20091021011846.GA26728-r/[email protected]
Re: [PATCH 2/4] cr: add generic LSM c/r support (v6)
Quoted 45 lines · Serge E. Hallyn
Quoted 44 lines · Oren Laadan
Quoted 13 lines · Serge E. Hallyn
Quoted 9 lines · Oren Laadan
Quoted 8 lines
oct 19: At checkpoint, we insert the void* security into the
objhash. The first time that we do so, we next write out the string representation of the context to the checkpoint image, along with the value of the objref for the void* security, and insert that into the objhash. Then at restart, when we read a LSM context, we read the objref which the void* security had at checkpoint, and we then insert the string context with that objref as well.I hoped to see similar comment inlined in the code.
If we're happy with this approach, then I will add good comments above
security_checkpoint_objandsecurity_restore_obj, and above the objhash entries.[...]
Quoted 27 lines
Quoted 21 lines
Quoted 7 lines
(quoted diff) +7
-0+/** + * security_checkpoint_obj - if first checkpoint of this void* security, + * then 1. ask the LSM for a string representing the context, 2. checkpoint + * that string + * @ctx: the checkpoint context + * @security: the void* security being checkpointed + * @sectype: indicates the type of object, because LSMs can (and do) storeReview
Quoted 10 lines
(quoted diff) +10
-0+ * @secref: We return the objref here + * different types of data for different types of objects. + * + * Returns the objref of the checkpointed ckpt_lsm_string representing the + * context, or -error on error. + * + * This is only used at checkpoint of course. + */ +int security_checkpoint_obj(struct ckpt_ctx *ctx, void *security, + int sectype, int *secref)This function returns 0 for success or a negative error. It should return the @secref instead of passing it by reference (see your description of the return value above !)
Quoted 1 line
[...]
Yes the comment is out of date but the API is imo an improvement. Note that
SECURITY_CTX_NONE, -1, is a meaningful secref, and at the sametime-EPERM, -1, is conceivably a valid error code (though at the moment no lsm will return it).
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
So I think overloading the secref with error codes is wrong here.
How about #define
SECURITY_CTX_NONE0 ?
it isn't a valid objref anyway.Ok, I thought we'd decided using 0 wasn't right for some reason, but I'll do that then.
An objref == 0 may have a special meaning when handled by restore_obj().
But here it's entirely private to security_{checkpoint/restart}_obj().
Oren.
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 2/4] cr: add generic LSM c/r support (v6)
Quoted 4 lines · Oren Laadan
Quoted 4 lines
Quoted 3 lines
Quoted 1 line
So I think overloading the secref with error codes is wrong here.
How about #define
SECURITY_CTX_NONE0 ?
it isn't a valid objref anyway.
Quoted 8 lines
Quoted 2 lines
Ok, I thought we'd decided using 0 wasn't right for some reason, but I'll do that then.
An objref == 0 may have a special meaning when handled by
restore_obj().But here it's entirely private to security_{checkpoint/restart}_obj().
Oren.
So here is a new version doing that:
From: Serge E. Hallyn <serue-r/[email protected]>
Date: Fri, 16 Oct 2009 14:05:33 -0400
Subject: [PATCH 2/4] cr: add generic LSM c/r support (v7)
Documentation/checkpoint/readme.txt begins:
"""
Application checkpoint/restart is the ability to save the state of a running application so that it can later resume its execution from the time at which it was checkpointed.
"""
This patch adds generic support for c/r of LSM credentials. Support for Smack and SELinux (and TOMOYO if appropriate) will be added later. Capabilities is already supported through generic creds code.
This patch supports ipc_perm, msg_msg, cred (task) and file ->security fields. Inodes, superblocks, netif, and xfrm currently are restored not through sys_restart() but through container creation, and so the security fields should be done then as well. Network should be added when network c/r is added.
Briefly, all security fields must be exported by the LSM as a simple null-terminated string. They are checkpointed through the security_checkpoint_obj() helper, because we must pass it an extra sectype field. Splitting SECURITY_OBJ_SEC into one type per object type would not work because, in Smack, one void* security is used for all object types. But we must pass the sectype field because in SELinux a different type of structure is stashed in each object type.
The RESTART_KEEP_LSM flag indicates that the LSM should attempt to reuse checkpointed security labels. It is always invalid when the LSM at restart differs from that at checkpoint. It is currently only usable for capabilities.
(For capabilities, restart without RESTART_KEEP_LSM is technically not implemented. There actually might be a use case for that, but the safety of it is dubious so for now we always re-create checkpointed capability sets whether RESTART_KEEP_LSM is specified or not)
Changelog:
sep 3: fix memory leak on LSM restore error path
Sep 3: provide 2 hooks, may_restart and checkpoint_header, to facilitate
an LSM tracking policy changes.
sep 10: merge RESTART_KEEP_LSM patch with basic LSM c/r
support patches.
sep 10: rename security_xyz_get_ctx() to security_xyz_checkpoint(),
in order to avoid confusing with the various other 'context' helpers in the security_ namespace, relating to secids and sysfs xattrs.
sep 10: pass context file to security_cred_restore. SELinux will
want the file's security context to authorize it as an entrypoint for the new process context.
oct 01: roll up some generic c/r debug hunks from selinux patch. oct 05: address set of Oren comments, including:
1. fix memleak in restore_msg_contents_one
2. use a separate container checkpoint image section
3. define SECURITY_CTX_NONE
4. allocate the right size to l in security_checkpoint_obj
5. fix ckpt_hdr_lsm alignment
oct 09: at checkpoint, key on the void*security in the objhash,
and don't cache the ckpt_stored_lsm at all. At restart, do_restore_security (now moved to security/security.c) creates and caches the ckpt_stored_lsm.
oct 19: At checkpoint, we insert the void* security into the
objhash. The first time that we do so, we next write out the string representation of the context to the checkpoint image, along with the value of the objref for the void* security, and insert that into the objhash. Then at restart, when we read a LSM context, we read the objref which the void* security had at checkpoint, and we then insert the string context with that objref as well.
oct 19: Address a bunch of Oren comments: add ckpt_write_err()s,
more commenting, use -ENOSYS not -EOPNOTSUPP. The biggest change is always failing restart when RESTART_KEEP_LSM is used but one of the security_XYZ_restore() returns -ENOSYS.
oct 20: SECURITY_CTX_NONE becomes 0 (from -1) and security_checkpoint_obj
returns an objref or SECURITY_CTX_NONE on success.
--- checkpoint/files.c | 28 +++++- checkpoint/objhash.c | 130 ++++++++++++++++++++++++++ include/linux/checkpoint.h | 4 + include/linux/checkpoint_hdr.h | 19 ++++ include/linux/checkpoint_types.h | 7 ++ include/linux/security.h | 168 +++++++++++++++++++++++++++++++++ ipc/checkpoint.c | 24 +++--- ipc/checkpoint_msg.c | 18 +++- ipc/checkpoint_sem.c | 4 +- ipc/checkpoint_shm.c | 4 +- ipc/util.h | 6 +- kernel/cred.c | 28 +++++- security/capability.c | 48 ++++++++++ security/security.c | 191 ++++++++++++++++++++++++++++++++++++++ 14 files changed, 653 insertions(+), 26 deletions(-)
checkpoint/files.c +26 -2
@@ -145,6 +145,19 @@ static int scan_fds(struct files_struct *files, int **fdtable)return n; } +#ifdef CONFIG_SECURITY +int checkpoint_file_security (struct ckpt_ctx *ctx,struct file *file) +{ +return security_checkpoint_obj (ctx, file->f_security, +CKPT_SECURITY_FILE ); +} +#else +int checkpoint_file_security (struct ckpt_ctx *ctx,struct file *file) +{ +return SECURITY_CTX_NONE ; +} +#endif +int checkpoint_file_common (struct ckpt_ctx *ctx,struct file *file,struct ckpt_hdr_file *h) {
@@ -159,8 +172,14 @@ int checkpoint_file_common(struct ckpt_ctx *ctx, struct file *file,if (h->f_credref <0 )return h->f_credref; -ckpt_debug ("file %s credref %d" , file->f_dentry->d_name.name, - h->f_credref); + h->f_secref =checkpoint_file_security (ctx, file); +if (h->f_secref <0 ) { +ckpt_write_err (ctx,"TE" ,"file->f_security" , h->f_secref); +return h->f_secref; + } + +ckpt_debug ("file %s credref %d secref %d\n" , + file->f_dentry->d_name.name, h->f_credref, h->f_secref);/* FIX: need also file->f_owner, etc */
@@ -510,6 +529,11 @@ int restore_file_common(struct ckpt_ctx *ctx, struct file *file,put_cred (file->f_cred); file->f_cred =get_cred (cred); + ret =security_restore_obj (ctx, (void *) file,CKPT_SECURITY_FILE , + h->f_secref); +if (ret <0 ) +return ret; +/* 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);if (ret <0 )
checkpoint/objhash.c +130 -0
151 lines not on this page · raw message
include/linux/checkpoint.h +4 -0
@@ -52,6 +52,7 @@ RESTART_KEEP_LSM | \ RESTART_GHOST)#define CKPT_LSM_INFO_LEN 200 +#define CKPT_LSM_STRING_MAX 1024 extern int walk_task_subtree(struct task_struct *task, int (*func)(struct task_struct *, void *),
@@ -100,6 +101,9 @@ extern char *ckpt_fill_fname(struct path *path, struct path *root,extern pid_t ckpt_pid_nr (struct ckpt_ctx *ctx,struct pid *pid);extern struct pid *_ckpt_find_pgrp (struct ckpt_ctx *ctx,pid_t pgid); +/* defined in objhash.c and also used in security/security.c */ +extern void lsm_string_free (struct kref *kref); +/* socket functions */ extern int ckpt_sock_getnames(struct ckpt_ctx *ctx, struct socket *socket,
include/linux/checkpoint_hdr.h +19 -0
@@ -82,6 +82,8 @@ enum {#define CKPT_HDR_OBJREF CKPT_HDR_OBJREF CKPT_HDR_LSM_INFO,#define CKPT_HDR_LSM_INFO CKPT_HDR_LSM_INFO + CKPT_HDR_SECURITY, +#define CKPT_HDR_SECURITY CKPT_HDR_SECURITY CKPT_HDR_TREE = 101,#define CKPT_HDR_TREE CKPT_HDR_TREE
@@ -234,6 +236,10 @@ enum obj_type {#define CKPT_OBJ_SOCK CKPT_OBJ_SOCK CKPT_OBJ_TTY,#define CKPT_OBJ_TTY CKPT_OBJ_TTY + CKPT_OBJ_SECURITY_PTR, +#define CKPT_OBJ_SECURITY_PTR CKPT_OBJ_SECURITY_PTR + CKPT_OBJ_SECURITY, +#define CKPT_OBJ_SECURITY CKPT_OBJ_SECURITY CKPT_OBJ_MAX#define CKPT_OBJ_MAX CKPT_OBJ_MAX };
@@ -364,6 +370,7 @@ struct ckpt_hdr_cred {__u32 gid, sgid, egid, fsgid;__s32 user_ref;__s32 groupinfo_ref; +__s32 sec_ref;struct ckpt_capabilities cap_s; } __attribute__((aligned(8)));
@@ -376,6 +383,15 @@ struct ckpt_hdr_groupinfo {__u32 groups[0 ]; } __attribute__((aligned(8))); +struct ckpt_hdr_lsm { +struct ckpt_hdr h; +__s32 ptrref; +__u8 sectype; +/* +* This is followed by a string of size len+1, +* null-terminated +*/ +} __attribute__((aligned (8 )));/* * todo - keyrings and LSM * These may be better done with userspace help though
@@ -505,6 +521,7 @@ struct ckpt_hdr_file {__s32 f_credref;__u64 f_pos;__u64 f_version; +__s32 f_secref; } __attribute__((aligned(8)));struct ckpt_hdr_file_generic {
@@ -765,6 +782,7 @@ struct ckpt_hdr_ipc_perms {__u32 mode;__u32 _padding;__u64 seq; +__s32 sec_ref; } __attribute__((aligned(8)));struct ckpt_hdr_ipc_shm {
@@ -798,6 +816,7 @@ struct ckpt_hdr_ipc_msg_msg {struct ckpt_hdr h;__s32 m_type;__u32 m_ts; +__s32 sec_ref; } __attribute__((aligned(8)));struct ckpt_hdr_ipc_sem {
include/linux/checkpoint_types.h +7 -0
@@ -89,6 +89,13 @@ struct ckpt_ctx {#endif }; +/* stored on hashtable */ +struct ckpt_lsm_string { +struct kref kref; +int sectype;/* Containing object (file,cred,&c) */ +int ptrref;/* the objref for the void* security */ +char *string; +};#endif /* __KERNEL__ */ #endif /* _LINUX_CHECKPOINT_TYPES_H_ */
include/linux/security.h +168 -0
265 lines not on this page · raw message
ipc/checkpoint.c +12 -12
@@ -31,7 +31,8 @@ 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) {if (ipcperms (perm,S_IROTH ))
@@ -45,7 +46,12 @@ int checkpoint_fill_ipc_perms(struct ckpt_hdr_ipc_perms *h, h->cgid = perm->cgid; h->mode = perm->mode &S_IRWXUGO ; h->seq = perm->seq; - + h->sec_ref =security_checkpoint_obj (ctx, perm->security, +CKPT_SECURITY_IPC ); +if (h->sec_ref <0 ) { +ckpt_write_err (ctx,"TE" ,"ipc_perm->security" , h->sec_ref); +return h->sec_ref; + }return 0 ; }
@@ -176,7 +182,8 @@ static int validate_created_perms(struct ckpt_hdr_ipc_perms *h)return 1 ; } -int restore_load_ipc_perms (struct ckpt_hdr_ipc_perms *h, +int restore_load_ipc_perms (struct ckpt_ctx *ctx, +struct ckpt_hdr_ipc_perms *h,struct kern_ipc_perm *perm) {if (h->id <0 )
@@ -205,16 +212,9 @@ int restore_load_ipc_perms(struct ckpt_hdr_ipc_perms *h, perm->cgid = h->cgid; 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 ; +return security_restore_obj (ctx, (void *)perm,CKPT_SECURITY_IPC , + h->sec_ref); } static int restore_ipc_any(struct ckpt_ctx *ctx, struct ipc_namespace *ipc_ns,
ipc/checkpoint_msg.c +15 -3
@@ -37,7 +37,7 @@ static int fill_ipc_msg_hdr(struct ckpt_ctx *ctx,ipc_lock_by_ptr (&msq->q_perm); - ret =checkpoint_fill_ipc_perms (&h->perms, &msq->q_perm); + ret =checkpoint_fill_ipc_perms (ctx, &h->perms, &msq->q_perm);if (ret <0 ) goto unlock;
@@ -63,14 +63,21 @@ static int checkpoint_msg_contents(struct ckpt_ctx *ctx, struct msg_msg *msg)struct ckpt_hdr_ipc_msg_msg *h;struct msg_msgseg *seg;int total, len; -int ret; +int secref, ret; + secref =security_checkpoint_obj (ctx, msg->security, +CKPT_SECURITY_MSG_MSG ); +if (secref <0 ) { +ckpt_write_err (ctx,"TE" ,"msg_msg->security" , secref); +return secref; + } h =ckpt_hdr_get_type (ctx,sizeof (*h),CKPT_HDR_IPC_MSG_MSG );if (!h)return -ENOMEM ; h->m_type = msg->m_type; h->m_ts = msg->m_ts; + h->sec_ref = secref; ret =ckpt_write_obj (ctx, &h->h);ckpt_hdr_put (ctx, h);
@@ -177,7 +184,7 @@ static int load_ipc_msg_hdr(struct ckpt_ctx *ctx, {int ret =0 ; - ret =restore_load_ipc_perms (&h->perms, &msq->q_perm); + ret =restore_load_ipc_perms (ctx, &h->perms, &msq->q_perm);if (ret <0 )return ret;
@@ -224,6 +231,11 @@ static struct msg_msg *restore_msg_contents_one(struct ckpt_ctx *ctx, int *clen) msg->next =NULL ; pseg = &msg->next; + ret =security_restore_obj (ctx, (void *) msg,CKPT_SECURITY_MSG_MSG , + h->sec_ref); +if (ret <0 ) + goto out; + ret =_ckpt_read_buffer (ctx, (msg +1 ), len);if (ret <0 ) goto out;
ipc/checkpoint_sem.c +2 -2
@@ -37,7 +37,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;
@@ -113,7 +113,7 @@ static int load_ipc_sem_hdr(struct ckpt_ctx *ctx, {int ret =0 ; - ret =restore_load_ipc_perms (&h->perms, &sem->sem_perm); + ret =restore_load_ipc_perms (ctx, &h->perms, &sem->sem_perm);if (ret <0 )return ret;
ipc/checkpoint_shm.c +2 -2
@@ -41,7 +41,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;
@@ -165,7 +165,7 @@ static int load_ipc_shm_hdr(struct ckpt_ctx *ctx, {int ret; - ret =restore_load_ipc_perms (&h->perms, &shp->shm_perm); + ret =restore_load_ipc_perms (ctx, &h->perms, &shp->shm_perm);if (ret <0 )return ret;
ipc/util.h +4 -2
@@ -199,9 +199,11 @@ void freeary(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, +extern int restore_load_ipc_perms (struct ckpt_ctx *ctx, +struct ckpt_hdr_ipc_perms *h,struct kern_ipc_perm *perm);extern int ckpt_collect_ipc_shm (int id,void *p,void *data);
kernel/cred.c +25 -3
@@ -706,10 +706,22 @@ int cred_setfsgid(struct cred *new, gid_t gid, gid_t *old_fsgid) }#ifdef CONFIG_CHECKPOINT +#ifdef CONFIG_SECURITY +int checkpoint_cred_security (struct ckpt_ctx *ctx,struct cred *cred) +{ +return security_checkpoint_obj (ctx, cred->security,CKPT_SECURITY_CRED ); +} +#else +int checkpoint_cred_security (struct ckpt_ctx *ctx,struct cred *cred) +{ +return SECURITY_CTX_NONE ; +} +#endif +static int do_checkpoint_cred (struct ckpt_ctx *ctx,struct cred *cred) {int ret; -int groupinfo_ref, user_ref; +int groupinfo_ref, user_ref, secref;struct ckpt_hdr_cred *h; groupinfo_ref = checkpoint_obj(ctx, cred->group_info,
@@ -719,13 +731,18 @@ static int do_checkpoint_cred(struct ckpt_ctx *ctx, struct cred *cred) user_ref =checkpoint_obj (ctx, cred->user,CKPT_OBJ_USER );if (user_ref <0 )return user_ref; + secref =checkpoint_cred_security (ctx, cred); +if (secref <0 ) { +ckpt_write_err (ctx,"TE" ,"cred->security" , secref); +return secref; + } h =ckpt_hdr_get_type (ctx,sizeof (*h),CKPT_HDR_CRED );if (!h)return -ENOMEM ; -ckpt_debug ("cred uid %d fsuid %d gid %d\n" , cred->uid, cred->fsuid, - cred->gid); +ckpt_debug ("cred uid %d fsuid %d gid %d secref %d\n" , cred->uid, + cred->fsuid, cred->gid, secref); h->uid = cred->uid; h->suid = cred->suid; h->euid = cred->euid;
@@ -735,6 +752,7 @@ static int do_checkpoint_cred(struct ckpt_ctx *ctx, struct cred *cred) h->sgid = cred->sgid; h->egid = cred->egid; h->fsgid = cred->fsgid; + h->sec_ref = secref;checkpoint_capabilities (&h->cap_s, cred);
@@ -808,6 +826,10 @@ static struct cred *do_restore_cred(struct ckpt_ctx *ctx) ret =cred_setfsgid (cred, h->fsgid, &oldgid);if (oldgid != h->fsgid && ret <0 ) goto err_putcred; + ret =security_restore_obj (ctx, (void *) cred,CKPT_SECURITY_CRED , + h->sec_ref); +if (ret) + goto err_putcred; ret =restore_capabilities (&h->cap_s, cred);if (ret) goto err_putcred;
security/capability.c +48 -0
90 lines not on this page · raw message
security/security.c +191 -0
217 lines not on this page · raw message
Signature · 1 line
1.5.4.3
Re: [PATCH 2/4] cr: add generic LSM c/r support (v6)
In reply to a message not in the archiveQuoting Oren Laadan ([email protected]):
Here is an updated version hopefully addressing your comments. I also fixed up the fact that checkpoint was broken under a few configs!
The rest of the patches are unchanged.
Subject: [PATCH 2/4] cr: add generic LSM c/r support (v7)
Documentation/checkpoint/readme.txt begins:
"""
Application checkpoint/restart is the ability to save the state of a running application so that it can later resume its execution from the time at which it was checkpointed.
"""
This patch adds generic support for c/r of LSM credentials. Support for Smack and SELinux (and TOMOYO if appropriate) will be added later. Capabilities is already supported through generic creds code.
This patch supports ipc_perm, msg_msg, cred (task) and file ->security fields. Inodes, superblocks, netif, and xfrm currently are restored not through sys_restart() but through container creation, and so the security fields should be done then as well. Network should be added when network c/r is added.
Briefly, all security fields must be exported by the LSM as a simple null-terminated string. They are checkpointed through the security_checkpoint_obj() helper, because we must pass it an extra sectype field. Splitting SECURITY_OBJ_SEC into one type per object type would not work because, in Smack, one void* security is used for all object types. But we must pass the sectype field because in SELinux a different type of structure is stashed in each object type.
The RESTART_KEEP_LSM flag indicates that the LSM should attempt to reuse checkpointed security labels. It is always invalid when the LSM at restart differs from that at checkpoint. It is currently only usable for capabilities.
(For capabilities, restart without RESTART_KEEP_LSM is technically not implemented. There actually might be a use case for that, but the safety of it is dubious so for now we always re-create checkpointed capability sets whether RESTART_KEEP_LSM is specified or not)
Changelog:
sep 3: fix memory leak on LSM restore error path
Sep 3: provide 2 hooks, may_restart and checkpoint_header, to facilitate
an LSM tracking policy changes.
sep 10: merge RESTART_KEEP_LSM patch with basic LSM c/r
support patches.
sep 10: rename security_xyz_get_ctx() to security_xyz_checkpoint(),
in order to avoid confusing with the various other 'context' helpers in the security_ namespace, relating to secids and sysfs xattrs.
sep 10: pass context file to security_cred_restore. SELinux will
want the file's security context to authorize it as an entrypoint for the new process context.
oct 01: roll up some generic c/r debug hunks from selinux patch. oct 05: address set of Oren comments, including:
1. fix memleak in restore_msg_contents_one
2. use a separate container checkpoint image section
3. define SECURITY_CTX_NONE
4. allocate the right size to l in security_checkpoint_obj
5. fix ckpt_hdr_lsm alignment
oct 09: at checkpoint, key on the void*security in the objhash,
and don't cache the ckpt_stored_lsm at all. At restart, do_restore_security (now moved to security/security.c) creates and caches the ckpt_stored_lsm.
oct 19: At checkpoint, we insert the void* security into the
objhash. The first time that we do so, we next write out the string representation of the context to the checkpoint image, along with the value of the objref for the void* security, and insert that into the objhash. Then at restart, when we read a LSM context, we read the objref which the void* security had at checkpoint, and we then insert the string context with that objref as well.
oct 19: Address a bunch of Oren comments: add ckpt_write_err()s,
more commenting, use -ENOSYS not -EOPNOTSUPP. The biggest change is always failing restart when RESTART_KEEP_LSM is used but one of the security_XYZ_restore() returns -ENOSYS.
--- checkpoint/files.c | 33 ++++++- checkpoint/objhash.c | 130 +++++++++++++++++++++++++ include/linux/checkpoint.h | 1 + include/linux/checkpoint_hdr.h | 19 ++++ include/linux/checkpoint_types.h | 7 ++ include/linux/security.h | 171 +++++++++++++++++++++++++++++++++ ipc/checkpoint.c | 27 +++--- ipc/checkpoint_msg.c | 19 +++- ipc/checkpoint_sem.c | 4 +- ipc/checkpoint_shm.c | 4 +- ipc/util.h | 6 +- kernel/cred.c | 32 ++++++- security/capability.c | 48 +++++++++ security/security.c | 195 ++++++++++++++++++++++++++++++++++++++ 14 files changed, 669 insertions(+), 27 deletions(-)
checkpoint/files.c +31 -2
@@ -145,9 +145,26 @@ static int scan_fds(struct files_struct *files, int **fdtable)return n; } +#ifdef CONFIG_SECURITY +int checkpoint_file_security (struct ckpt_ctx *ctx,struct file *file, +int *secref) +{ +return security_checkpoint_obj (ctx, file->f_security, +CKPT_SECURITY_FILE , secref); +} +#else +int checkpoint_file_security (struct ckpt_ctx *ctx,struct file *file, +int *secref) +{ + *secref =SECURITY_CTX_NONE ; +return 0 ; +} +#endif +int checkpoint_file_common (struct ckpt_ctx *ctx,struct file *file,struct ckpt_hdr_file *h) { +int ret;struct cred *f_cred = (struct cred *) file->f_cred; h->f_flags = file->f_flags;
@@ -159,8 +176,15 @@ int checkpoint_file_common(struct ckpt_ctx *ctx, struct file *file,if (h->f_credref <0 )return h->f_credref; -ckpt_debug ("file %s credref %d" , file->f_dentry->d_name.name, - h->f_credref); + ret =checkpoint_file_security (ctx, file, &h->f_secref); +if (ret <0 ) { +ckpt_write_err (ctx,"TEO" ,"file->f_security" , ret, + h->f_secref); +return ret; + } + +ckpt_debug ("file %s credref %d secref %d\n" , + file->f_dentry->d_name.name, h->f_credref, h->f_secref);/* FIX: need also file->f_owner, etc */
@@ -510,6 +534,11 @@ int restore_file_common(struct ckpt_ctx *ctx, struct file *file,put_cred (file->f_cred); file->f_cred =get_cred (cred); + ret =security_restore_obj (ctx, (void *) file,CKPT_SECURITY_FILE , + h->f_secref); +if (ret <0 ) +return ret; +/* 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);if (ret <0 )
checkpoint/objhash.c +130 -0
151 lines not on this page · raw message
include/linux/checkpoint.h +1 -0
@@ -52,6 +52,7 @@ RESTART_KEEP_LSM | \ RESTART_GHOST)#define CKPT_LSM_INFO_LEN 200 +#define CKPT_LSM_STRING_MAX 1024 extern int walk_task_subtree(struct task_struct *task, int (*func)(struct task_struct *, void *),
include/linux/checkpoint_hdr.h +19 -0
@@ -82,6 +82,8 @@ enum {#define CKPT_HDR_OBJREF CKPT_HDR_OBJREF CKPT_HDR_LSM_INFO,#define CKPT_HDR_LSM_INFO CKPT_HDR_LSM_INFO + CKPT_HDR_SECURITY, +#define CKPT_HDR_SECURITY CKPT_HDR_SECURITY CKPT_HDR_TREE = 101,#define CKPT_HDR_TREE CKPT_HDR_TREE
@@ -234,6 +236,10 @@ enum obj_type {#define CKPT_OBJ_SOCK CKPT_OBJ_SOCK CKPT_OBJ_TTY,#define CKPT_OBJ_TTY CKPT_OBJ_TTY + CKPT_OBJ_SECURITY_PTR, +#define CKPT_OBJ_SECURITY_PTR CKPT_OBJ_SECURITY_PTR + CKPT_OBJ_SECURITY, +#define CKPT_OBJ_SECURITY CKPT_OBJ_SECURITY CKPT_OBJ_MAX#define CKPT_OBJ_MAX CKPT_OBJ_MAX };
@@ -364,6 +370,7 @@ struct ckpt_hdr_cred {__u32 gid, sgid, egid, fsgid;__s32 user_ref;__s32 groupinfo_ref; +__s32 sec_ref;struct ckpt_capabilities cap_s; } __attribute__((aligned(8)));
@@ -376,6 +383,15 @@ struct ckpt_hdr_groupinfo {__u32 groups[0 ]; } __attribute__((aligned(8))); +struct ckpt_hdr_lsm { +struct ckpt_hdr h; +__s32 ptrref; +__u8 sectype; +/* +* This is followed by a string of size len+1, +* null-terminated +*/ +} __attribute__((aligned (8 )));/* * todo - keyrings and LSM * These may be better done with userspace help though
@@ -505,6 +521,7 @@ struct ckpt_hdr_file {__s32 f_credref;__u64 f_pos;__u64 f_version; +__s32 f_secref; } __attribute__((aligned(8)));struct ckpt_hdr_file_generic {
@@ -765,6 +782,7 @@ struct ckpt_hdr_ipc_perms {__u32 mode;__u32 _padding;__u64 seq; +__s32 sec_ref; } __attribute__((aligned(8)));struct ckpt_hdr_ipc_shm {
@@ -798,6 +816,7 @@ struct ckpt_hdr_ipc_msg_msg {struct ckpt_hdr h;__s32 m_type;__u32 m_ts; +__s32 sec_ref; } __attribute__((aligned(8)));struct ckpt_hdr_ipc_sem {
include/linux/checkpoint_types.h +7 -0
@@ -89,6 +89,13 @@ struct ckpt_ctx {#endif }; +/* stored on hashtable */ +struct ckpt_lsm_string { +struct kref kref; +int sectype;/* Containing object (file,cred,&c) */ +int ptrref;/* the objref for the void* security */ +char *string; +};#endif /* __KERNEL__ */ #endif /* _LINUX_CHECKPOINT_TYPES_H_ */
include/linux/security.h +171 -0
268 lines not on this page · raw message
ipc/checkpoint.c +14 -13
@@ -31,9 +31,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 ret; +if (ipcperms (perm,S_IROTH ))return -EACCES ;
@@ -45,8 +48,12 @@ int checkpoint_fill_ipc_perms(struct ckpt_hdr_ipc_perms *h, h->cgid = perm->cgid; h->mode = perm->mode &S_IRWXUGO ; h->seq = perm->seq; - -return 0 ; + ret =security_checkpoint_obj (ctx, perm->security,CKPT_SECURITY_IPC , + &h->sec_ref); +if (ret <0 ) +ckpt_write_err (ctx,"TEO" ,"ipc_perm->security" , ret, + h->sec_ref); +return ret; } static int checkpoint_ipc_any(struct ckpt_ctx *ctx,
@@ -176,7 +183,8 @@ static int validate_created_perms(struct ckpt_hdr_ipc_perms *h)return 1 ; } -int restore_load_ipc_perms (struct ckpt_hdr_ipc_perms *h, +int restore_load_ipc_perms (struct ckpt_ctx *ctx, +struct ckpt_hdr_ipc_perms *h,struct kern_ipc_perm *perm) {if (h->id <0 )
@@ -205,16 +213,9 @@ int restore_load_ipc_perms(struct ckpt_hdr_ipc_perms *h, perm->cgid = h->cgid; 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 ; +return security_restore_obj (ctx, (void *)perm,CKPT_SECURITY_IPC , + h->sec_ref); } static int restore_ipc_any(struct ckpt_ctx *ctx, struct ipc_namespace *ipc_ns,
ipc/checkpoint_msg.c +16 -3
@@ -37,7 +37,7 @@ static int fill_ipc_msg_hdr(struct ckpt_ctx *ctx,ipc_lock_by_ptr (&msq->q_perm); - ret =checkpoint_fill_ipc_perms (&h->perms, &msq->q_perm); + ret =checkpoint_fill_ipc_perms (ctx, &h->perms, &msq->q_perm);if (ret <0 ) goto unlock;
@@ -63,14 +63,22 @@ static int checkpoint_msg_contents(struct ckpt_ctx *ctx, struct msg_msg *msg)struct ckpt_hdr_ipc_msg_msg *h;struct msg_msgseg *seg;int total, len; -int ret; +int secref, ret; + ret =security_checkpoint_obj (ctx, msg->security, +CKPT_SECURITY_MSG_MSG , + &secref); +if (ret <0 ) { +ckpt_write_err (ctx,"TEO" ,"msg_msg->security" , ret, secref); +return ret; + } h =ckpt_hdr_get_type (ctx,sizeof (*h),CKPT_HDR_IPC_MSG_MSG );if (!h)return -ENOMEM ; h->m_type = msg->m_type; h->m_ts = msg->m_ts; + h->sec_ref = secref; ret =ckpt_write_obj (ctx, &h->h);ckpt_hdr_put (ctx, h);
@@ -177,7 +185,7 @@ static int load_ipc_msg_hdr(struct ckpt_ctx *ctx, {int ret =0 ; - ret =restore_load_ipc_perms (&h->perms, &msq->q_perm); + ret =restore_load_ipc_perms (ctx, &h->perms, &msq->q_perm);if (ret <0 )return ret;
@@ -224,6 +232,11 @@ static struct msg_msg *restore_msg_contents_one(struct ckpt_ctx *ctx, int *clen) msg->next =NULL ; pseg = &msg->next; + ret =security_restore_obj (ctx, (void *) msg,CKPT_SECURITY_MSG_MSG , + h->sec_ref); +if (ret <0 ) + goto out; + ret =_ckpt_read_buffer (ctx, (msg +1 ), len);if (ret <0 ) goto out;
ipc/checkpoint_sem.c +2 -2
@@ -37,7 +37,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;
@@ -113,7 +113,7 @@ static int load_ipc_sem_hdr(struct ckpt_ctx *ctx, {int ret =0 ; - ret =restore_load_ipc_perms (&h->perms, &sem->sem_perm); + ret =restore_load_ipc_perms (ctx, &h->perms, &sem->sem_perm);if (ret <0 )return ret;
ipc/checkpoint_shm.c +2 -2
@@ -41,7 +41,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;
@@ -165,7 +165,7 @@ static int load_ipc_shm_hdr(struct ckpt_ctx *ctx, {int ret; - ret =restore_load_ipc_perms (&h->perms, &shp->shm_perm); + ret =restore_load_ipc_perms (ctx, &h->perms, &shp->shm_perm);if (ret <0 )return ret;
ipc/util.h +4 -2
@@ -199,9 +199,11 @@ void freeary(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, +extern int restore_load_ipc_perms (struct ckpt_ctx *ctx, +struct ckpt_hdr_ipc_perms *h,struct kern_ipc_perm *perm);extern int ckpt_collect_ipc_shm (int id,void *p,void *data);
kernel/cred.c +29 -3
@@ -706,10 +706,26 @@ int cred_setfsgid(struct cred *new, gid_t gid, gid_t *old_fsgid) }#ifdef CONFIG_CHECKPOINT +#ifdef CONFIG_SECURITY +int checkpoint_cred_security (struct ckpt_ctx *ctx,struct cred *cred, +int *secref) +{ +return security_checkpoint_obj (ctx, cred->security, +CKPT_SECURITY_CRED , secref); +} +#else +int checkpoint_cred_security (struct ckpt_ctx *ctx,struct cred *cred, +int *secref) +{ + *secref =SECURITY_CTX_NONE ; +return 0 ; +} +#endif +static int do_checkpoint_cred (struct ckpt_ctx *ctx,struct cred *cred) {int ret; -int groupinfo_ref, user_ref; +int groupinfo_ref, user_ref, secref =SECURITY_CTX_NONE ;struct ckpt_hdr_cred *h; groupinfo_ref = checkpoint_obj(ctx, cred->group_info,
@@ -719,13 +735,18 @@ static int do_checkpoint_cred(struct ckpt_ctx *ctx, struct cred *cred) user_ref =checkpoint_obj (ctx, cred->user,CKPT_OBJ_USER );if (user_ref <0 )return user_ref; + ret =checkpoint_cred_security (ctx, cred, &secref); +if (ret <0 ) { +ckpt_write_err (ctx,"TEO" ,"cred->security" , ret, secref); +return ret; + } h =ckpt_hdr_get_type (ctx,sizeof (*h),CKPT_HDR_CRED );if (!h)return -ENOMEM ; -ckpt_debug ("cred uid %d fsuid %d gid %d\n" , cred->uid, cred->fsuid, - cred->gid); +ckpt_debug ("cred uid %d fsuid %d gid %d secref %d\n" , cred->uid, + cred->fsuid, cred->gid, secref); h->uid = cred->uid; h->suid = cred->suid; h->euid = cred->euid;
@@ -735,6 +756,7 @@ static int do_checkpoint_cred(struct ckpt_ctx *ctx, struct cred *cred) h->sgid = cred->sgid; h->egid = cred->egid; h->fsgid = cred->fsgid; + h->sec_ref = secref;checkpoint_capabilities (&h->cap_s, cred);
@@ -808,6 +830,10 @@ static struct cred *do_restore_cred(struct ckpt_ctx *ctx) ret =cred_setfsgid (cred, h->fsgid, &oldgid);if (oldgid != h->fsgid && ret <0 ) goto err_putcred; + ret =security_restore_obj (ctx, (void *) cred,CKPT_SECURITY_CRED , + h->sec_ref); +if (ret) + goto err_putcred; ret =restore_capabilities (&h->cap_s, cred);if (ret) goto err_putcred;
security/capability.c +48 -0
90 lines not on this page · raw message
security/security.c +195 -0
221 lines not on this page · raw message
Signature · 1 line
1.6.1
PATCH 1/1 restart: accept the lsm_name field in header and add -k flag (v2)
In reply to a message not in the archiveThe checkpoint file header now has an 11-character string containing the name of the active LSM, following the uts info, and a variable length buffer type conaining LSM-specific version information (for instance a sha1sum of policy). Handle these.
Also add a -k (--keeplsm) flag to tell restart to set the RESTART_KEEP_LSM flag to sys_restart().
Changelog:
oct 15: separate out from container config section patch oct 05: 1. move keep_lsm into arg struct
2. read a separate container config section
3. use CHECKPOINT_LSM_NAME_MAX
--- restart.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 files changed, 37 insertions(+), 2 deletions(-)
restart.c +37 -2
@@ -68,6 +68,7 @@ static char usage_str[] =" --signal=SIG send SIG to root task on SIGINT (default: SIGKILL\n" " to container root, SIGINT otherwise)\n" " -w,--wait wait for root task to termiate (default)\n" +" -k,--keeplsm Try to recreate original LSM labels on all objects\n" " --show-status show exit status of root task (implies -w)\n" " --copy-status imitate exit status of root task (implies -w)\n" " -W,--no-wait do not wait for root task to terminate\n"
@@ -352,6 +353,7 @@ struct args {int copy_status;char *freezer;char *input; +int keep_lsm; };static void usage (char *str)
@@ -382,6 +384,7 @@ static void parse_args(struct args *args, int argc, char *argv[]) { "self", no_argument, NULL, 6}, { "signal", required_argument, NULL, 4 }, { "inspect", no_argument, NULL, 5 }, + { "keeplsm", no_argument, NULL, 'k' }, { "input", required_argument, NULL, 'i' }, { "root", required_argument, NULL, 'r' }, { "wait", no_argument, NULL, 'w' },
@@ -393,7 +396,7 @@ static void parse_args(struct args *args, int argc, char *argv[]) { "debug", no_argument, NULL, 'd' }, { NULL, 0, NULL, 0 } }; -static char optc[] ="hdvpPwWF:r:i:" ; +static char optc[] ="hdvpkPwWF:r:i:" ;int sig;
@@ -448,6 +451,9 @@ static void parse_args(struct args *args, int argc, char *argv[])case 'w' : args->wait =1 ;break ; +case 'k' : + args->keep_lsm =RESTART_KEEP_LSM ; +break ;case 'W' : args->wait =0 ;break ;
@@ -929,6 +935,7 @@ static int ckpt_coordinator(struct ckpt_ctx *ctx)if (ctx->args->freezer) flags |=RESTART_FROZEN ; + flags |= ctx->args->keep_lsm; ret =restart (root_pid,STDIN_FILENO , flags);if (ret <0 ) {
@@ -1588,6 +1595,8 @@ static int ckpt_make_tree(struct ckpt_ctx *ctx, struct task *task)if (task->flags & (TASK_GHOST |TASK_DEAD )) flags |=RESTART_GHOST ; + flags |= ctx->args->keep_lsm; +/* on success this doesn't return */ ckpt_dbg ("about to call sys_restart(), flags %#lx\n" , flags); ret =restart (0 ,STDIN_FILENO , flags);
@@ -2134,10 +2143,23 @@ static int ckpt_read_header_arch(struct ckpt_ctx *ctx)static int ckpt_read_container (struct ckpt_ctx *ctx) { +int ret;struct ckpt_hdr_container *h; +char *ptr; h = (struct ckpt_hdr_container *) ctx->container; -return ckpt_read_obj_type (ctx, h,sizeof (*h),CKPT_HDR_CONTAINER ); + ret =ckpt_read_obj_type (ctx, h,sizeof (*h),CKPT_HDR_CONTAINER ); +if (ret <0 ) +return ret; + + ptr = (char *) h; + ptr += ((struct ckpt_hdr *) ptr)->len; + ret =ckpt_read_obj_buffer (ctx, ptr,CHECKPOINT_LSM_NAME_MAX +1 ); +if (ret <0 ) +return ret; + + ptr += ((struct ckpt_hdr *) ptr)->len; +return ckpt_read_obj_type (ctx, ptr,200 ,CKPT_HDR_LSM_INFO ); }static int ckpt_read_tree (struct ckpt_ctx *ctx)
@@ -2215,9 +2237,22 @@ static int ckpt_write_header_arch(struct ckpt_ctx *ctx)static int ckpt_write_container (struct ckpt_ctx *ctx) {char *ptr; +int ret; ptr = (char *) ctx->container;/* write the container info section */ + ret =ckpt_write_obj (ctx, (struct ckpt_hdr *) ptr); +if (ret <0 ) +return ret; + +/* write the lsm name buffer */ + ptr += ((struct ckpt_hdr *) ptr)->len; + ret =ckpt_write_obj (ctx, (struct ckpt_hdr *) ptr); +if (ret <0 ) +return ret; + +/* write the lsm policy section */ + ptr += ((struct ckpt_hdr *) ptr)->len;return ckpt_write_obj (ctx, (struct ckpt_hdr *) ptr); }
Signature · 1 line
1.6.1.1
PATCH 3/4 cr: add smack support to lsm c/r (v6)
In reply to a message not in the archiveDocumentation/checkpoint/readme.txt begins:
"""
Application checkpoint/restart is the ability to save the state of a running application so that it can later resume its execution from the time at which it was checkpointed.
"""
This patch implements checkpoint and restore of Smack security labels. The rules are the same as in previous versions:
1. when objects are created during restore() they are automatically labeled with current_security().
2. if there was a label checkpointed with the object, and that label != current_security() (which is the same as obj->security), then the object is relabeled if the sys_restart() caller has CAP_MAC_ADMIN. Otherwise we return -EPERM.
This has been tested by checkpointing tasks under labels _, vs1, and vs2, and restarting from tasks under _, vs1, and vs2, with and without CAP_MAC_ADMIN in the bounding set, and with and without the '-k' (keep_lsm) flag to mktree. Expected results:
#shell 1:
echo vs1 > /proc/self/attr/current
ckpt > out
echo vs2 > /proc/self/attr/current
mktree -F /cgroup/2 < out
(frozen)
# shell 2:
cat /proc/pidof ckpt/attr/current
vs2
echo THAWED > /cgroup/2/freezer.state
# shell 1:
mktree -k -F /cgroup/2 < out
(frozen)
# shell 2:
cat /proc/pidof ckpt/attr/current
vs1
echo THAWED > /cgroup/2/freezer.state
# shell 1:
capsh --drop=cap_mac_admin --
mktree -k -F /cgroup/2 < out
(permission denied)
There are testcases in git://git.sr71.net/~hallyn/cr_tests.git
under cr_tests/smack, which automate the above (and pass).
Changelog:
sep 3: add a version to smack lsm, accessible through
/smack/version (Casey and Serge)
sep 10: rename xyz_get_ctx() to xyz_checkpoint()
--- checkpoint/restart.c | 1 + security/smack/smack.h | 1 + security/smack/smack_lsm.c | 141 ++++++++++++++++++++++++++++++++++++++++++++ security/smack/smackfs.c | 83 ++++++++++++++++++++++++++ 4 files changed, 226 insertions(+), 0 deletions(-)
checkpoint/restart.c +1 -0
@@ -647,6 +647,7 @@ static int restore_lsm(struct ckpt_ctx *ctx) }if (strcmp (ctx->lsm_name,"lsm_none" ) !=0 && +strcmp (ctx->lsm_name,"smack" ) !=0 &&strcmp (ctx->lsm_name,"default" ) !=0 ) {ckpt_debug ("c/r: RESTART_KEEP_LSM unsupported for %s\n" , ctx->lsm_name);
security/smack/smack.h +1 -0
@@ -216,6 +216,7 @@ u32 smack_to_secid(const char *);extern int smack_cipso_direct;extern char *smack_net_ambient;extern char *smack_onlycap; +extern char *smack_version;extern const char *smack_cipso_option;extern struct smack_known smack_known_floor;
security/smack/smack_lsm.c +141 -0
203 lines not on this page · raw message
security/smack/smackfs.c +83 -0
113 lines not on this page · raw message
Signature · 1 line
1.6.1
PATCH 4/4 cr: add selinux support (v6)
In reply to a message not in the archiveDocumentation/checkpoint/readme.txt begins:
"""
Application checkpoint/restart is the ability to save the state of a running application so that it can later resume its execution from the time at which it was checkpointed.
"""
This patch adds the ability to checkpoint and restore selinux contexts for tasks, open files, and sysvipc objects. Contexts are checkpointed as strings. For tasks and files, where a security struct actually points to several contexts, all contexts are written out in one string, separated by ':::'.
The default behaviors are to checkpoint contexts, but not to restore them. To attempt to restore them, sys_restart() must be given the RESTART_KEEP_LSM flag. If this is given then the caller of sys_restart() must have the new 'restore' permission to the target objclass, or for instance PROCESS__SETFSCREATE to itself to specify a create_sid.
There are some tests under cr_tests/selinux atgit://git.sr71.net/~hallyn/cr_tests.git.
A corresponding simple refpolicy (and /usr/share/selinux/devel/include) patch is needed.
The programs to checkpoint and restart (called 'checkpoint' and 'restart') come from git://git.ncl.cs.columbia.edu/pub/git/user-cr.git.
This patch applies against the checkpoint/restart-enabled kernel tree at git://git.ncl.cs.columbia.edu/pub/git/linux-cr.git/.
Changelog:
oct 09: fix memory overrun in selinux_cred_checkpoint. oct 02: (Stephen Smalley suggestions):
1. s/__u32/u32/
2. enable the fown sid restoration
3. use process_restore to authorize resetting osid
4. don't make new hooks inline.
oct 01: Remove some debugging that is redundant with
avc log data.
sep 10: (Most addressing suggestions by Stephen Smalley)
1. change xyz_get_ctx() to xyz_checkpoint().
2. check entrypoint permission on cred_restore
3. always dec context length by 1
4. don't allow SECSID_NULL when that's not valid
5. when SECSID_NULL is valid, restore it
6. c/r task->osid
7. Just print nothing instead of 'null' for SECSID_NULL
8. sids are __u32, as are lenghts passed to sid_to_context.
--- checkpoint/restart.c | 1 + security/selinux/hooks.c | 366 ++++++++++++++++++++++++++ security/selinux/include/av_perm_to_string.h | 5 + security/selinux/include/av_permissions.h | 5 + 4 files changed, 377 insertions(+), 0 deletions(-)
checkpoint/restart.c +1 -0
@@ -648,6 +648,7 @@ static int restore_lsm(struct ckpt_ctx *ctx)if (strcmp (ctx->lsm_name,"lsm_none" ) !=0 &&strcmp (ctx->lsm_name,"smack" ) !=0 && +strcmp (ctx->lsm_name,"selinux" ) !=0 &&strcmp (ctx->lsm_name,"default" ) !=0 ) {ckpt_debug ("c/r: RESTART_KEEP_LSM unsupported for %s\n" , ctx->lsm_name);
security/selinux/hooks.c +366 -0
416 lines not on this page · raw message
security/selinux/include/av_perm_to_string.h +5 -0
@@ -19,6 +19,8 @@ S_(SECCLASS_FILE, FILE__ENTRYPOINT, "entrypoint") S_(SECCLASS_FILE, FILE__EXECMOD, "execmod") S_(SECCLASS_FILE, FILE__OPEN, "open") + S_(SECCLASS_FILE, FILE__RESTORE, "restore") + S_(SECCLASS_FILE, FILE__FOWN_RESTORE, "fown_restore") S_(SECCLASS_CHR_FILE, CHR_FILE__EXECUTE_NO_TRANS, "execute_no_trans") S_(SECCLASS_CHR_FILE, CHR_FILE__ENTRYPOINT, "entrypoint")S_ (SECCLASS_CHR_FILE ,CHR_FILE__EXECMOD ,"execmod" )
@@ -88,9 +90,11 @@ S_(SECCLASS_PROCESS, PROCESS__EXECHEAP, "execheap") S_(SECCLASS_PROCESS, PROCESS__SETKEYCREATE, "setkeycreate") S_(SECCLASS_PROCESS, PROCESS__SETSOCKCREATE, "setsockcreate") + S_(SECCLASS_PROCESS, PROCESS__RESTORE, "restore") S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue") S_(SECCLASS_MSG, MSG__SEND, "send") S_(SECCLASS_MSG, MSG__RECEIVE, "receive") + S_(SECCLASS_MSG, MSG__RESTORE, "restore") S_(SECCLASS_SHM, SHM__LOCK, "lock") S_(SECCLASS_SECURITY, SECURITY__COMPUTE_AV, "compute_av")S_ (SECCLASS_SECURITY ,SECURITY__COMPUTE_CREATE ,"compute_create" )
@@ -107,6 +111,7 @@ S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, "syslog_read") S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, "syslog_mod") S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE, "syslog_console") + S_(SECCLASS_IPC, IPC__RESTORE, "restore") S_(SECCLASS_CAPABILITY, CAPABILITY__CHOWN, "chown") S_(SECCLASS_CAPABILITY, CAPABILITY__DAC_OVERRIDE, "dac_override")S_ (SECCLASS_CAPABILITY ,CAPABILITY__DAC_READ_SEARCH ,"dac_read_search" )
security/selinux/include/av_permissions.h +5 -0
@@ -101,6 +101,8 @@#define FILE__ENTRYPOINT 0x00040000UL#define FILE__EXECMOD 0x00080000UL#define FILE__OPEN 0x00100000UL +#define FILE__RESTORE 0x00200000UL +#define FILE__FOWN_RESTORE 0x00400000UL#define LNK_FILE__IOCTL 0x00000001UL#define LNK_FILE__READ 0x00000002UL#define LNK_FILE__WRITE 0x00000004UL
@@ -453,6 +455,7 @@#define PROCESS__EXECHEAP 0x08000000UL#define PROCESS__SETKEYCREATE 0x10000000UL#define PROCESS__SETSOCKCREATE 0x20000000UL +#define PROCESS__RESTORE 0x40000000UL#define IPC__CREATE 0x00000001UL#define IPC__DESTROY 0x00000002UL#define IPC__GETATTR 0x00000004UL
@@ -462,6 +465,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
@@ -483,6 +487,7 @@#define MSGQ__ENQUEUE 0x00000200UL#define MSG__SEND 0x00000001UL#define MSG__RECEIVE 0x00000002UL +#define MSG__RESTORE 0x00000004UL#define SHM__CREATE 0x00000001UL#define SHM__DESTROY 0x00000002UL#define SHM__GETATTR 0x00000004UL
Signature · 1 line
1.6.1