diff for duplicates of <20090620013216.GA4435@us.ibm.com> diff --git a/a/1.txt b/N1/1.txt index 771fc25..1bdd0da 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -6,1313 +6,3 @@ 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 <serue@us.ibm.com> -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. - -Signed-off-by: Serge E. Hallyn <serue@us.ibm.com> ---- - 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(-) - -diff --git a/checkpoint/objhash.c b/checkpoint/objhash.c -index b4bc2e4..c266375 100644 ---- a/checkpoint/objhash.c -+++ b/checkpoint/objhash.c -@@ -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, -+ }, - }; - - -diff --git a/checkpoint/sys.c b/checkpoint/sys.c -index 38a5299..06a2c00 100644 ---- a/checkpoint/sys.c -+++ b/checkpoint/sys.c -@@ -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(); -diff --git a/include/linux/checkpoint_hdr.h b/include/linux/checkpoint_hdr.h -index e42e0db..e3fb9b3 100644 ---- a/include/linux/checkpoint_hdr.h -+++ b/include/linux/checkpoint_hdr.h -@@ -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 { -diff --git a/include/linux/checkpoint_types.h b/include/linux/checkpoint_types.h -index 27fbe26..74c218a 100644 ---- a/include/linux/checkpoint_types.h -+++ b/include/linux/checkpoint_types.h -@@ -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__ */ -diff --git a/include/linux/security.h b/include/linux/security.h -index d5fd616..38f643c 100644 ---- a/include/linux/security.h -+++ b/include/linux/security.h -@@ -1092,6 +1092,16 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) - * @msg_msg_free_security: - * Deallocate the security structure for this message. - * @msg contains the message structure to be modified. -+ * @msg_msg_getsecid: -+ * Get the secid associated with the msg_msg object. -+ * @msg contains the message object -+ * @secid contains a pointer to the location where result will be saved. -+ * In case of failure, @secid will be set to zero. -+ * @msg_msg_restore: -+ * Set security context on restored object -+ * @msg contains the newly created msg_msg object -+ * @secid contains the secid corresponding to the checkpointed context. -+ * Return 0 if a proper label was set and permission is granted. - * - * Security hooks for System V IPC Message Queues - * -@@ -1137,6 +1147,11 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) - * @type contains the type of message requested. - * @mode contains the operational flags. - * Return 0 if permission is granted. -+ * @msg_queue_restore: -+ * Set permission on a newly restored msg_queue -+ * @msq contains the message queue being restored. -+ * @secid is the secid corresponding to the checkpointed context. -+ * Return 0 if an appropriate context was set and permission is granted. - * - * Security hooks for System V Shared Memory Segments - * -@@ -1172,6 +1187,11 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) - * @shmaddr contains the address to attach memory region to. - * @shmflg contains the operational flags. - * Return 0 if permission is granted. -+ * @shm_restore: -+ * Set permission on a newly restored shm -+ * @shm contains the shm being restored. -+ * @secid is the secid corresponding to the checkpointed context. -+ * Return 0 if an appropriate context was set and permission is granted. - * - * Security hooks for System V Semaphores - * -@@ -1208,6 +1228,11 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) - * @nsops contains the number of operations to perform. - * @alter contains the flag indicating whether changes are to be made. - * Return 0 if permission is granted. -+ * @sem_restore: -+ * Set permission on a newly restored sem -+ * @sem contains the sem being restored. -+ * @secid is the secid corresponding to the checkpointed context. -+ * Return 0 if an appropriate context was set and permission is granted. - * - * @ptrace_may_access: - * Check permission before allowing the current process to trace the -@@ -1499,6 +1524,8 @@ struct security_operations { - - int (*msg_msg_alloc_security) (struct msg_msg *msg); - void (*msg_msg_free_security) (struct msg_msg *msg); -+ void (*msg_msg_getsecid) (struct msg_msg *msg, u32 *secid); -+ int (*msg_msg_restore) (struct msg_msg *msg, u32 secid); - - int (*msg_queue_alloc_security) (struct msg_queue *msq); - void (*msg_queue_free_security) (struct msg_queue *msq); -@@ -1510,6 +1537,7 @@ struct security_operations { - struct msg_msg *msg, - struct task_struct *target, - long type, int mode); -+ int (*msg_queue_restore) (struct msg_queue *msq, u32 secid); - - int (*shm_alloc_security) (struct shmid_kernel *shp); - void (*shm_free_security) (struct shmid_kernel *shp); -@@ -1517,6 +1545,7 @@ struct security_operations { - int (*shm_shmctl) (struct shmid_kernel *shp, int cmd); - int (*shm_shmat) (struct shmid_kernel *shp, - char __user *shmaddr, int shmflg); -+ int (*shm_restore) (struct shmid_kernel *shp, u32 secid); - - int (*sem_alloc_security) (struct sem_array *sma); - void (*sem_free_security) (struct sem_array *sma); -@@ -1524,6 +1553,7 @@ struct security_operations { - int (*sem_semctl) (struct sem_array *sma, int cmd); - int (*sem_semop) (struct sem_array *sma, - struct sembuf *sops, unsigned nsops, int alter); -+ int (*sem_restore) (struct sem_array *sma, u32 secid); - - int (*netlink_send) (struct sock *sk, struct sk_buff *skb); - int (*netlink_recv) (struct sk_buff *skb, int cap); -@@ -1748,6 +1778,8 @@ int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag); - void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid); - int security_msg_msg_alloc(struct msg_msg *msg); - void security_msg_msg_free(struct msg_msg *msg); -+void security_msg_msg_getsecid(struct msg_msg *msg, u32 *secid); -+int security_msg_msg_restore(struct msg_msg *msg, u32 secid); - int security_msg_queue_alloc(struct msg_queue *msq); - void security_msg_queue_free(struct msg_queue *msq); - int security_msg_queue_associate(struct msg_queue *msq, int msqflg); -@@ -1756,17 +1788,20 @@ int security_msg_queue_msgsnd(struct msg_queue *msq, - struct msg_msg *msg, int msqflg); - int security_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, - struct task_struct *target, long type, int mode); -+int security_msg_queue_restore(struct msg_queue *msq, u32 secid); - int security_shm_alloc(struct shmid_kernel *shp); - void security_shm_free(struct shmid_kernel *shp); - int security_shm_associate(struct shmid_kernel *shp, int shmflg); - int security_shm_shmctl(struct shmid_kernel *shp, int cmd); - int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmflg); -+int security_shm_restore(struct shmid_kernel *shp, u32 secid); - int security_sem_alloc(struct sem_array *sma); - void security_sem_free(struct sem_array *sma); - int security_sem_associate(struct sem_array *sma, int semflg); - int security_sem_semctl(struct sem_array *sma, int cmd); - int security_sem_semop(struct sem_array *sma, struct sembuf *sops, - unsigned nsops, int alter); -+int security_sem_restore(struct sem_array *sma, u32 secid); - void security_d_instantiate(struct dentry *dentry, struct inode *inode); - int security_getprocattr(struct task_struct *p, char *name, char **value); - int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size); -@@ -2393,6 +2428,18 @@ static inline int security_msg_msg_alloc(struct msg_msg *msg) - return 0; - } - -+static inline void security_msg_msg_getsecid(struct msg_msg *msg, u32 *secid) -+{ -+ *secid = 0; -+} -+ -+static inline int security_msg_msg_restore(struct msg_msg *msg, u32 secid) -+{ -+ if (secid) -+ return -EINVAL; -+ return 0; -+} -+ - static inline void security_msg_msg_free(struct msg_msg *msg) - { } - -@@ -2429,6 +2476,14 @@ static inline int security_msg_queue_msgrcv(struct msg_queue *msq, - return 0; - } - -+static inline int security_msg_queue_restore(struct msg_queue *msq, -+ u32 secid) -+{ -+ if (secid) -+ return -EINVAL; -+ return 0; -+} -+ - static inline int security_shm_alloc(struct shmid_kernel *shp) - { - return 0; -@@ -2454,6 +2509,14 @@ static inline int security_shm_shmat(struct shmid_kernel *shp, - return 0; - } - -+static inline int security_shm_restore(struct shmid_kernel *shp, -+ u32 secid) -+{ -+ if (secid) -+ return -EINVAL; -+ return 0; -+} -+ - static inline int security_sem_alloc(struct sem_array *sma) - { - return 0; -@@ -2479,6 +2542,14 @@ static inline int security_sem_semop(struct sem_array *sma, - return 0; - } - -+static inline int security_sem_restore(struct sem_array *sma, -+ u32 secid) -+{ -+ if (secid) -+ return -EINVAL; -+ return 0; -+} -+ - static inline void security_d_instantiate(struct dentry *dentry, struct inode *inode) - { } - -@@ -2975,7 +3046,28 @@ static inline char *alloc_secdata(void) - - static inline void free_secdata(void *secdata) - { } -+ -+#endif /* CONFIG_SECURITY */ -+ -+#ifdef CONFIG_CHECKPOINT -+struct sec_store { -+ int secid; /* LSM secid */ -+ int secref; /* objhash reference */ -+ struct list_head list; -+}; -+#ifdef CONFIG_SECURITY -+extern int checkpoint_security(struct ckpt_ctx *ctx, void *ptr); -+extern void *restore_security(struct ckpt_ctx *ctx); -+extern int checkpoint_security_getsecref(struct ckpt_ctx *ctx, int secid); -+#else /* CONFIG_SECURITY */ -+#define checkpoint_security checkpoint_bad -+#define restore_security restore_bad -+static inline int checkpoint_security_getsecref(struct ckpt_ctx *ctx, int secid) -+{ -+ return 0; -+} - #endif /* CONFIG_SECURITY */ -+#endif /* CONFIG_CHECKPOINT */ - - #endif /* ! __LINUX_SECURITY_H */ - -diff --git a/ipc/checkpoint.c b/ipc/checkpoint.c -index 88996e2..b7641e2 100644 ---- a/ipc/checkpoint.c -+++ b/ipc/checkpoint.c -@@ -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; - } -diff --git a/ipc/checkpoint_msg.c b/ipc/checkpoint_msg.c -index 51385b0..ca55339 100644 ---- a/ipc/checkpoint_msg.c -+++ b/ipc/checkpoint_msg.c -@@ -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> - - #include "util.h" -@@ -36,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; - -@@ -62,12 +63,19 @@ 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 ret, secid, secref; -+ -+ security_msg_msg_getsecid(msg, &secid); -+ secref = checkpoint_security_getsecref(ctx, secid); -+ if (secref < 0) -+ return secref; - - h = ckpt_hdr_get_type(ctx, sizeof(*h), CKPT_HDR_IPC_MSG_MSG); - if (!h) - return -ENOMEM; - -+ h->secref = secref; -+ - h->m_type = msg->m_type; - h->m_ts = msg->m_ts; - -@@ -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); -+ if (ret < 0) -+ return ret; -+ - ckpt_debug("msq: lspid %d lrpid %d qnum %lld qbytes %lld\n", - h->q_lspid, h->q_lrpid, h->q_qnum, h->q_qbytes); - -@@ -201,7 +224,7 @@ static struct msg_msg *restore_msg_contents_one(struct ckpt_ctx *ctx, int *clen) - struct msg_msg *msg = NULL; - struct msg_msgseg *seg, **pseg; - int total, len; -- int ret; -+ int ret, secid = 0; - - h = ckpt_read_obj_type(ctx, sizeof(*h), CKPT_HDR_IPC_MSG_MSG); - if (IS_ERR(h)) -@@ -245,6 +268,22 @@ static struct msg_msg *restore_msg_contents_one(struct ckpt_ctx *ctx, int *clen) - total -= len; - } - -+ if (h->secref) { -+ struct sec_store *s; -+ s = ckpt_obj_fetch(ctx, h->secref, CKPT_OBJ_SECURITY); -+ if (IS_ERR(s)) { -+ ret = PTR_ERR(s); -+ goto out; -+ } -+ secid = s->secid; -+ } -+ ret = security_msg_msg_alloc(msg); -+ if (ret) -+ goto out; -+ ret = security_msg_msg_restore(msg, secid); -+ if (ret < 0) -+ goto out; -+ - msg->m_type = h->m_type; - msg->m_ts = h->m_ts; - *clen = h->m_ts; -diff --git a/ipc/checkpoint_sem.c b/ipc/checkpoint_sem.c -index 64d61ee..609750b 100644 ---- a/ipc/checkpoint_sem.c -+++ b/ipc/checkpoint_sem.c -@@ -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; -diff --git a/ipc/checkpoint_shm.c b/ipc/checkpoint_shm.c -index 41bacfb..a2a0e41 100644 ---- a/ipc/checkpoint_shm.c -+++ b/ipc/checkpoint_shm.c -@@ -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); - -diff --git a/ipc/util.h b/ipc/util.h -index fa974eb..bed25bd 100644 ---- a/ipc/util.h -+++ b/ipc/util.h -@@ -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); -diff --git a/security/capability.c b/security/capability.c -index 21b6cea..d0d2e39 100644 ---- a/security/capability.c -+++ b/security/capability.c -@@ -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); -diff --git a/security/security.c b/security/security.c -index 5284255..d737e0e 100644 ---- a/security/security.c -+++ b/security/security.c -@@ -16,6 +16,7 @@ - #include <linux/init.h> - #include <linux/kernel.h> - #include <linux/security.h> -+#include <linux/checkpoint.h> - - /* Boot-time LSM user choice */ - static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1]; -@@ -832,6 +833,16 @@ void security_msg_msg_free(struct msg_msg *msg) - security_ops->msg_msg_free_security(msg); - } - -+void security_msg_msg_getsecid(struct msg_msg *msg, u32 *secid) -+{ -+ security_ops->msg_msg_getsecid(msg, secid); -+} -+ -+int security_msg_msg_restore(struct msg_msg *msg, u32 secid) -+{ -+ return security_ops->msg_msg_restore(msg, secid); -+} -+ - int security_msg_queue_alloc(struct msg_queue *msq) - { - return security_ops->msg_queue_alloc_security(msq); -@@ -864,6 +875,11 @@ int security_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, - return security_ops->msg_queue_msgrcv(msq, msg, target, type, mode); - } - -+int security_msg_queue_restore(struct msg_queue *msq, u32 secid) -+{ -+ return security_ops->msg_queue_restore(msq, secid); -+} -+ - int security_shm_alloc(struct shmid_kernel *shp) - { - return security_ops->shm_alloc_security(shp); -@@ -889,6 +905,11 @@ int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmfl - return security_ops->shm_shmat(shp, shmaddr, shmflg); - } - -+int security_shm_restore(struct shmid_kernel *shp, u32 secid) -+{ -+ return security_ops->shm_restore(shp, secid); -+} -+ - int security_sem_alloc(struct sem_array *sma) - { - return security_ops->sem_alloc_security(sma); -@@ -915,6 +936,11 @@ int security_sem_semop(struct sem_array *sma, struct sembuf *sops, - return security_ops->sem_semop(sma, sops, nsops, alter); - } - -+int security_sem_restore(struct sem_array *sma, u32 secid) -+{ -+ return security_ops->sem_restore(sma, secid); -+} -+ - void security_d_instantiate(struct dentry *dentry, struct inode *inode) - { - if (unlikely(inode && IS_PRIVATE(inode))) -@@ -1247,3 +1273,146 @@ int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, - } - - #endif /* CONFIG_AUDIT */ -+ -+#ifdef CONFIG_CHECKPOINT -+ -+static int do_checkpoint_security(struct ckpt_ctx *ctx, -+ struct sec_store *s) -+{ -+ char *str; -+ int ret, len; -+ -+ ret = security_secid_to_secctx(s->secid, &str, &len); -+ if (ret) -+ return ret; -+ ret = ckpt_write_obj_type(ctx, str, len, CKPT_HDR_SECURITY); -+ security_release_secctx(str, len); -+ return ret; -+} -+ -+int checkpoint_security(struct ckpt_ctx *ctx, void *ptr) -+{ -+ return do_checkpoint_security(ctx, (struct sec_store *) ptr); -+} -+ -+/* -+ * stupid ordered list insertion Replace with rbtree or hash -+ * return 1 if the secid was already stored -+ * call with ctx->secref_lock held -+ */ -+static int insert_secref(struct ckpt_ctx *ctx, struct sec_store *news) -+{ -+ struct sec_store *last=NULL, *s; -+ -+ if (list_empty(&ctx->secref_list)) { -+ list_add(&news->list, &ctx->secref_list); -+ return 0; -+ } -+ -+ list_for_each_entry(s, &ctx->secref_list, list) { -+ if (s->secid == news->secid) -+ /* race */ -+ return 1; -+ else if (s->secid < news->secid) -+ last = s; -+ else -+ break; -+ } -+ /* -+ * if last is not null, insert after last. Otherwise -+ * this should be the first item -+ */ -+ if (last) -+ list_add(&news->list, &last->list); -+ else -+ list_add(&news->list, &ctx->secref_list); -+ return 0; -+} -+ -+/* just need some sane value */ -+#define MAX_STR_LEN 300 -+static struct sec_store *do_restore_security(struct ckpt_ctx *ctx) -+{ -+ struct ckpt_hdr_sec *h; -+ int id; -+ int ret, conflict; -+ struct sec_store *s; -+ -+ h = ckpt_read_buf_type(ctx, MAX_STR_LEN, CKPT_HDR_SECURITY); -+ if (IS_ERR(h)) -+ return ERR_PTR(PTR_ERR(h)); -+ ret = security_secctx_to_secid(h->str, strlen(h->str)+1, &id); -+ ckpt_hdr_put(ctx, h); -+ if (ret < 0) -+ return ERR_PTR(ret); -+ s = kmalloc(sizeof(*s), GFP_KERNEL); -+ if (!s) -+ return ERR_PTR(-ENOMEM); -+ s->secid = id; -+ spin_lock(&ctx->secref_lock); -+ conflict = insert_secref(ctx, s); -+ spin_unlock(&ctx->secref_lock); -+ if (conflict) /* not possible */ -+ return ERR_PTR(-EINVAL); -+ return s; -+} -+ -+void *restore_security(struct ckpt_ctx *ctx) -+{ -+ return (void *) do_restore_security(ctx); -+} -+ -+/* -+ * if there's already a cached entry with secid, return -+ * its secref. Return -1 if there is no such entry. If -+ * LSMs are actually not supported, then a value of 0 may -+ * in fact be returned as the secref -+ */ -+static int get_secref_from_secid(struct ckpt_ctx *ctx, int secid) -+{ -+ int ret = -1; -+ struct sec_store *s; -+ -+ spin_lock(&ctx->secref_lock); -+ list_for_each_entry(s, &ctx->secref_list, list) -+ if (s->secid == secid) { -+ ret = s->secref; -+ break; -+ } -+ spin_unlock(&ctx->secref_lock); -+ return ret; -+} -+ -+/* -+ * get a objhash reference from a secid -+ * if already stored, return existing ref -+ * else checkpoint it and return the new ref -+ */ -+int checkpoint_security_getsecref(struct ckpt_ctx *ctx, int secid) -+{ -+ int ret, conflict=0, secref = 0; -+ struct sec_store *s; -+ -+again: -+ ret = get_secref_from_secid(ctx, secid); -+ if (ret >= 0) -+ return ret; -+ BUG_ON(conflict!=0); /* a racer added it to list, but now it's gone? */ -+ s = kzalloc(sizeof(*s), GFP_KERNEL); -+ if (!s) -+ return -ENOMEM; -+ s->secid = secid; -+ spin_lock(&ctx->secref_lock); -+ conflict = insert_secref(ctx, s); -+ if (conflict) { -+ spin_unlock(&ctx->secref_lock); -+ kfree(s); -+ goto again; -+ } -+ if (secid != 0) -+ secref = checkpoint_obj(ctx, s, CKPT_OBJ_SECURITY); -+ s->secref = secref; -+ spin_unlock(&ctx->secref_lock); -+ return secref; -+} -+#endif -diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c -index 2fcad7c..591f545 100644 ---- a/security/selinux/hooks.c -+++ b/security/selinux/hooks.c -@@ -4675,6 +4675,19 @@ static void msg_msg_free_security(struct msg_msg *msg) - kfree(msec); - } - -+static int selinux_msg_msg_restore(struct msg_msg *msg, u32 secid) -+{ -+ struct msg_security_struct *msec = msg->security; -+ u32 sid = current_sid(); -+ int ret; -+ -+ ret = avc_has_perm(sid, secid, SECCLASS_MSG, MSG__RESTORE, NULL); -+ if (ret) -+ return ret; -+ msec->sid = secid; -+ return 0; -+} -+ - static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, - u32 perms) - { -@@ -4700,6 +4713,12 @@ static void selinux_msg_msg_free_security(struct msg_msg *msg) - msg_msg_free_security(msg); - } - -+static void selinux_msg_msg_getsecid(struct msg_msg *msg, u32 *secid) -+{ -+ struct msg_security_struct *msec = msg->security; -+ *secid = msec->sid; -+} -+ - /* message queue security operations */ - static int selinux_msg_queue_alloc_security(struct msg_queue *msq) - { -@@ -4841,6 +4860,14 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, - return rc; - } - -+static int selinux_msg_queue_restore(struct msg_queue *msq, u32 secid) -+{ -+ struct ipc_security_struct *isec = msq->q_perm.security; -+ -+ isec->sid = secid; -+ return ipc_has_perm(&msq->q_perm, MSGQ__RESTORE); -+} -+ - /* Shared Memory security operations */ - static int selinux_shm_alloc_security(struct shmid_kernel *shp) - { -@@ -4933,6 +4960,14 @@ static int selinux_shm_shmat(struct shmid_kernel *shp, - return ipc_has_perm(&shp->shm_perm, perms); - } - -+static int selinux_shm_restore(struct shmid_kernel *shp, u32 secid) -+{ -+ struct ipc_security_struct *isec = shp->shm_perm.security; -+ -+ isec->sid = secid; -+ return ipc_has_perm(&shp->shm_perm, SHM__RESTORE); -+} -+ - /* Semaphore security operations */ - static int selinux_sem_alloc_security(struct sem_array *sma) - { -@@ -5034,6 +5069,14 @@ static int selinux_sem_semop(struct sem_array *sma, - return ipc_has_perm(&sma->sem_perm, perms); - } - -+static int selinux_sem_restore(struct sem_array *sma, u32 secid) -+{ -+ struct ipc_security_struct *isec = sma->sem_perm.security; -+ -+ isec->sid = secid; -+ return ipc_has_perm(&sma->sem_perm, SEM__RESTORE); -+} -+ - static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) - { - u32 av = 0; -@@ -5415,6 +5458,8 @@ static struct security_operations selinux_ops = { - - .msg_msg_alloc_security = selinux_msg_msg_alloc_security, - .msg_msg_free_security = selinux_msg_msg_free_security, -+ .msg_msg_getsecid = selinux_msg_msg_getsecid, -+ .msg_msg_restore = selinux_msg_msg_restore, - - .msg_queue_alloc_security = selinux_msg_queue_alloc_security, - .msg_queue_free_security = selinux_msg_queue_free_security, -@@ -5422,18 +5467,21 @@ static struct security_operations selinux_ops = { - .msg_queue_msgctl = selinux_msg_queue_msgctl, - .msg_queue_msgsnd = selinux_msg_queue_msgsnd, - .msg_queue_msgrcv = selinux_msg_queue_msgrcv, -+ .msg_queue_restore = selinux_msg_queue_restore, - - .shm_alloc_security = selinux_shm_alloc_security, - .shm_free_security = selinux_shm_free_security, - .shm_associate = selinux_shm_associate, - .shm_shmctl = selinux_shm_shmctl, - .shm_shmat = selinux_shm_shmat, -+ .shm_restore = selinux_shm_restore, - - .sem_alloc_security = selinux_sem_alloc_security, - .sem_free_security = selinux_sem_free_security, - .sem_associate = selinux_sem_associate, - .sem_semctl = selinux_sem_semctl, - .sem_semop = selinux_sem_semop, -+ .sem_restore = selinux_sem_restore, - - .d_instantiate = selinux_d_instantiate, - -diff --git a/security/selinux/include/av_inherit.h b/security/selinux/include/av_inherit.h -index 8377a4b..0d7689d 100644 ---- a/security/selinux/include/av_inherit.h -+++ b/security/selinux/include/av_inherit.h -@@ -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) -diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h -index d645192..3c3eba6 100644 ---- a/security/selinux/include/av_permissions.h -+++ b/security/selinux/include/av_permissions.h -@@ -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 -diff --git a/security/selinux/include/common_perm_to_string.h b/security/selinux/include/common_perm_to_string.h -index ce5b6e2..fb94053 100644 ---- a/security/selinux/include/common_perm_to_string.h -+++ b/security/selinux/include/common_perm_to_string.h -@@ -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) - -diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c -index 98b3195..070aeb7 100644 ---- a/security/smack/smack_lsm.c -+++ b/security/smack/smack_lsm.c -@@ -1619,6 +1619,33 @@ static void smack_msg_msg_free_security(struct msg_msg *msg) - } - - /** -+ * smack_msg_msg_getsecid - Extract smack security id -+ * @msg: the object -+ * @secid: where result will be saved -+ */ -+static void smack_msg_msg_getsecid(struct msg_msg *msg, u32 *secid) -+{ -+ char *smack = msg->security; -+ -+ *secid = smack_to_secid(smack); -+} -+ -+static int smack_msg_msg_restore(struct msg_msg *msg, u32 secid) -+{ -+ char *smack = smack_from_secid(secid); -+ -+ if (smack == NULL) -+ return -EINVAL; -+ if (current_security() != smack) { -+ if (!capable(CAP_MAC_ADMIN)) -+ return -EPERM; -+ msg->security = smack; -+ } else -+ msg->security = current_security(); -+ return 0; -+} -+ -+/** - * smack_of_shm - the smack pointer for the shm - * @shp: the object - * -@@ -1727,6 +1754,21 @@ static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, - return smk_curacc(ssp, may); - } - -+static int smack_shm_restore(struct shmid_kernel *shp, u32 secid) -+{ -+ char *smack = smack_from_secid(secid); -+ -+ if (smack == NULL) -+ return -EINVAL; -+ if (current_security() != smack) { -+ if (!capable(CAP_MAC_ADMIN)) -+ return -EPERM; -+ shp->shm_perm.security = smack; -+ } else -+ shp->shm_perm.security = current_security(); -+ return 0; -+} -+ - /** - * smack_of_sem - the smack pointer for the sem - * @sma: the object -@@ -1842,6 +1884,21 @@ static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops, - return smk_curacc(ssp, MAY_READWRITE); - } - -+static int smack_sem_restore(struct sem_array *sma, u32 secid) -+{ -+ char *smack = smack_from_secid(secid); -+ -+ if (smack == NULL) -+ return -EINVAL; -+ if (current_security() != smack) { -+ if (!capable(CAP_MAC_ADMIN)) -+ return -EPERM; -+ sma->sem_perm.security = smack; -+ } else -+ sma->sem_perm.security = current_security(); -+ return 0; -+} -+ - /** - * smack_msg_alloc_security - Set the security blob for msg - * @msq: the object -@@ -1967,6 +2024,21 @@ static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, - return smk_curacc(msp, MAY_READWRITE); - } - -+static int smack_msg_queue_restore(struct msg_queue *msq, u32 secid) -+{ -+ char *smack = smack_from_secid(secid); -+ -+ if (smack == NULL) -+ return -EINVAL; -+ if (current_security() != smack) { -+ if (!capable(CAP_MAC_ADMIN)) -+ return -EPERM; -+ msq->q_perm.security = smack; -+ } else -+ msq->q_perm.security = current_security(); -+ return 0; -+} -+ - /** - * smack_ipc_permission - Smack access for ipc_permission() - * @ipp: the object permissions -@@ -2903,6 +2975,8 @@ struct security_operations smack_ops = { - - .msg_msg_alloc_security = smack_msg_msg_alloc_security, - .msg_msg_free_security = smack_msg_msg_free_security, -+ .msg_msg_getsecid = smack_msg_msg_getsecid, -+ .msg_msg_restore = smack_msg_msg_restore, - - .msg_queue_alloc_security = smack_msg_queue_alloc_security, - .msg_queue_free_security = smack_msg_queue_free_security, -@@ -2910,18 +2984,21 @@ struct security_operations smack_ops = { - .msg_queue_msgctl = smack_msg_queue_msgctl, - .msg_queue_msgsnd = smack_msg_queue_msgsnd, - .msg_queue_msgrcv = smack_msg_queue_msgrcv, -+ .msg_queue_restore = smack_msg_queue_restore, - - .shm_alloc_security = smack_shm_alloc_security, - .shm_free_security = smack_shm_free_security, - .shm_associate = smack_shm_associate, - .shm_shmctl = smack_shm_shmctl, - .shm_shmat = smack_shm_shmat, -+ .shm_restore = smack_shm_restore, - - .sem_alloc_security = smack_sem_alloc_security, - .sem_free_security = smack_sem_free_security, - .sem_associate = smack_sem_associate, - .sem_semctl = smack_sem_semctl, - .sem_semop = smack_sem_semop, -+ .sem_restore = smack_sem_restore, - - .netlink_send = cap_netlink_send, - .netlink_recv = cap_netlink_recv, --- -1.6.1 diff --git a/a/content_digest b/N1/content_digest index 75beba4..0762abb 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -17,1316 +17,6 @@ "security structs. For instance, for tasks there is the current\n" "sid, exec sid, create sid, keycreate_sid, and sockcreate_sid.\n" "So I guess I'll have to ask the LSM for how many secids it wants\n" - "to checkpoint, then checkpoint an array of contexts?\n" - "\n" - "From 19669b07cdfef4d377f3f188e2421c4124e38708 Mon Sep 17 00:00:00 2001\n" - "From: Serge E. Hallyn <serue@us.ibm.com>\n" - "Date: Wed, 17 Jun 2009 12:00:21 -0400\n" - "Subject: [PATCH 1/1] cr: lsm: restore LSM contexts for ipc objects\n" - "\n" - "Introduce a cache of secids for checkpoint and restart.\n" - "At checkpoint, it takes a secid, stores the corresponding\n" - "context string, and stores the objref for later use.\n" - "At restart, read the context from checkpoint image,\n" - "ask the security module for a secid, and store the secid\n" - "on the objhash.\n" - "\n" - "The per-object security c/r code will be responsible for\n" - "getting secid from void*security at checkpoint time, and\n" - "converting secid to void*security at restore time.\n" - "\n" - "The code to c/r contexts for IPC objects is also in this\n" - "patch.\n" - "\n" - "For Smack, assign the label of the process doing sys_restart()\n" - "if !capable(CAP_MAC_ADMIN), otherwise use the checkpointed\n" - "label.\n" - "\n" - "For SELinux, define a new 'restore' permission for ipc objects.\n" - "(A corresponding trival policy patch adding 'restore' to the\n" - "common flask permissions for refpolicy is also needed). The\n" - "caller of sys_restart() must have the class:restore permission\n" - "to assign the checkpointed label, else restart will be refused.\n" - "\n" - "Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>\n" - "---\n" - " checkpoint/objhash.c | 10 ++\n" - " checkpoint/sys.c | 15 ++\n" - " include/linux/checkpoint_hdr.h | 12 ++-\n" - " include/linux/checkpoint_types.h | 7 +\n" - " include/linux/security.h | 92 ++++++++++++\n" - " ipc/checkpoint.c | 20 ++-\n" - " ipc/checkpoint_msg.c | 45 ++++++-\n" - " ipc/checkpoint_sem.c | 18 +++-\n" - " ipc/checkpoint_shm.c | 18 +++-\n" - " ipc/util.h | 3 +-\n" - " security/capability.c | 38 +++++\n" - " security/security.c | 169 ++++++++++++++++++++++\n" - " security/selinux/hooks.c | 48 ++++++\n" - " security/selinux/include/av_inherit.h | 8 +-\n" - " security/selinux/include/av_permissions.h | 10 +-\n" - " security/selinux/include/common_perm_to_string.h | 1 +\n" - " security/smack/smack_lsm.c | 77 ++++++++++\n" - " 17 files changed, 571 insertions(+), 20 deletions(-)\n" - "\n" - "diff --git a/checkpoint/objhash.c b/checkpoint/objhash.c\n" - "index b4bc2e4..c266375 100644\n" - "--- a/checkpoint/objhash.c\n" - "+++ b/checkpoint/objhash.c\n" - "@@ -18,6 +18,7 @@\n" - " #include <linux/sched.h>\n" - " #include <linux/ipc_namespace.h>\n" - " #include <linux/user_namespace.h>\n" - "+#include <linux/security.h>\n" - " #include <linux/checkpoint.h>\n" - " #include <linux/checkpoint_hdr.h>\n" - " \n" - "@@ -365,6 +366,15 @@ static struct ckpt_obj_ops ckpt_obj_ops[] = {\n" - " \t\t.checkpoint = checkpoint_groupinfo,\n" - " \t\t.restore = restore_groupinfo,\n" - " \t},\n" - "+\t/* LSM context */\n" - "+\t{\n" - "+\t\t.obj_name = \"SECURITY\",\n" - "+\t\t.obj_type = CKPT_OBJ_SECURITY,\n" - "+\t\t.ref_grab = obj_no_grab,\n" - "+\t\t.ref_drop = obj_no_drop,\n" - "+\t\t.checkpoint = checkpoint_security,\n" - "+\t\t.restore = restore_security,\n" - "+\t},\n" - " };\n" - " \n" - " \n" - "diff --git a/checkpoint/sys.c b/checkpoint/sys.c\n" - "index 38a5299..06a2c00 100644\n" - "--- a/checkpoint/sys.c\n" - "+++ b/checkpoint/sys.c\n" - "@@ -20,6 +20,7 @@\n" - " #include <linux/file.h>\n" - " #include <linux/uaccess.h>\n" - " #include <linux/capability.h>\n" - "+#include <linux/security.h>\n" - " #include <linux/checkpoint.h>\n" - " #include <linux/deferqueue.h>\n" - " \n" - "@@ -188,6 +189,16 @@ static void task_arr_free(struct ckpt_ctx *ctx)\n" - " \tkfree(ctx->tasks_arr);\n" - " }\n" - " \n" - "+void free_secreflist(struct ckpt_ctx *ctx)\n" - "+{\n" - "+\tstruct sec_store *s, *p;\n" - "+\n" - "+\tlist_for_each_entry_safe(s, p, &ctx->secref_list, list) {\n" - "+\t\tlist_del(&s->list);\n" - "+\t\tkfree(s);\n" - "+\t}\n" - "+}\n" - "+\n" - " static void ckpt_ctx_free(struct ckpt_ctx *ctx)\n" - " {\n" - " \tint ret;\n" - "@@ -217,6 +228,7 @@ static void ckpt_ctx_free(struct ckpt_ctx *ctx)\n" - " \t\tput_task_struct(ctx->root_task);\n" - " \tif (ctx->root_freezer)\n" - " \t\tput_task_struct(ctx->root_freezer);\n" - "+\tfree_secreflist(ctx);\n" - " \n" - " \tkfree(ctx->pids_arr);\n" - " \n" - "@@ -233,6 +245,9 @@ static struct ckpt_ctx *ckpt_ctx_alloc(int fd, unsigned long uflags,\n" - " \tif (!ctx)\n" - " \t\treturn ERR_PTR(-ENOMEM);\n" - " \n" - "+\tspin_lock_init(&ctx->secref_lock);\n" - "+\tINIT_LIST_HEAD(&ctx->secref_list);\n" - "+\n" - " \tctx->uflags = uflags;\n" - " \tctx->kflags = kflags;\n" - " \tctx->ktime_begin = ktime_get();\n" - "diff --git a/include/linux/checkpoint_hdr.h b/include/linux/checkpoint_hdr.h\n" - "index e42e0db..e3fb9b3 100644\n" - "--- a/include/linux/checkpoint_hdr.h\n" - "+++ b/include/linux/checkpoint_hdr.h\n" - "@@ -62,6 +62,7 @@ enum {\n" - " \tCKPT_HDR_USER,\n" - " \tCKPT_HDR_GROUPINFO,\n" - " \tCKPT_HDR_TASK_CREDS,\n" - "+\tCKPT_HDR_SECURITY,\n" - " \n" - " \t/* 201-299: reserved for arch-dependent */\n" - " \n" - "@@ -114,6 +115,7 @@ enum obj_type {\n" - " \tCKPT_OBJ_CRED,\n" - " \tCKPT_OBJ_USER,\n" - " \tCKPT_OBJ_GROUPINFO,\n" - "+\tCKPT_OBJ_SECURITY,\n" - " \tCKPT_OBJ_MAX\n" - " };\n" - " \n" - "@@ -192,6 +194,12 @@ struct ckpt_capabilities {\n" - " \t__u32 padding;\n" - " } __attribute__((aligned(8)));\n" - " \n" - "+/* LSM security contexts (shared) */\n" - "+struct ckpt_hdr_sec {\n" - "+\tstruct ckpt_hdr h;\n" - "+\tchar str[];\n" - "+} __attribute__((aligned(8)));\n" - "+\n" - " struct ckpt_hdr_task_creds {\n" - " \tstruct ckpt_hdr h;\n" - " \t__s32 cred_ref;\n" - "@@ -418,7 +426,7 @@ struct ckpt_hdr_ipc_perms {\n" - " \t__u32 cuid;\n" - " \t__u32 cgid;\n" - " \t__u32 mode;\n" - "-\t__u32 _padding;\n" - "+\t__s32 secref;\n" - " \t__u64 seq;\n" - " } __attribute__((aligned(8)));\n" - " \n" - "@@ -453,6 +461,8 @@ struct ckpt_hdr_ipc_msg_msg {\n" - " \tstruct ckpt_hdr h;\n" - " \t__s32 m_type;\n" - " \t__u32 m_ts;\n" - "+\t__s32 secref;\n" - "+\t__u32 padding;\n" - " } __attribute__((aligned(8)));\n" - " \n" - " struct ckpt_hdr_ipc_sem {\n" - "diff --git a/include/linux/checkpoint_types.h b/include/linux/checkpoint_types.h\n" - "index 27fbe26..74c218a 100644\n" - "--- a/include/linux/checkpoint_types.h\n" - "+++ b/include/linux/checkpoint_types.h\n" - "@@ -73,6 +73,13 @@ struct ckpt_ctx {\n" - " \tstruct cred *realcred, *ecred;\t/* tmp storage for cred at restart */\n" - " \n" - " \tstruct ckpt_stats stats;\t/* statistics */\n" - "+\n" - "+\t/*\n" - "+\t * next two form basis for a mini-cache of LSM contexts\n" - "+\t * turn it into a rbtree or hash\n" - "+\t */\n" - "+\tspinlock_t secref_lock;\n" - "+\tstruct list_head secref_list;\n" - " };\n" - " \n" - " #endif /* __KERNEL__ */\n" - "diff --git a/include/linux/security.h b/include/linux/security.h\n" - "index d5fd616..38f643c 100644\n" - "--- a/include/linux/security.h\n" - "+++ b/include/linux/security.h\n" - "@@ -1092,6 +1092,16 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)\n" - " * @msg_msg_free_security:\n" - " *\tDeallocate the security structure for this message.\n" - " *\t@msg contains the message structure to be modified.\n" - "+ * @msg_msg_getsecid:\n" - "+ *\tGet the secid associated with the msg_msg object.\n" - "+ *\t@msg contains the message object\n" - "+ *\t@secid contains a pointer to the location where result will be saved.\n" - "+ *\tIn case of failure, @secid will be set to zero.\n" - "+ * @msg_msg_restore:\n" - "+ *\tSet security context on restored object\n" - "+ *\t@msg contains the newly created msg_msg object\n" - "+ *\t@secid contains the secid corresponding to the checkpointed context.\n" - "+ *\tReturn 0 if a proper label was set and permission is granted.\n" - " *\n" - " * Security hooks for System V IPC Message Queues\n" - " *\n" - "@@ -1137,6 +1147,11 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)\n" - " *\t@type contains the type of message requested.\n" - " *\t@mode contains the operational flags.\n" - " *\tReturn 0 if permission is granted.\n" - "+ * @msg_queue_restore:\n" - "+ *\tSet permission on a newly restored msg_queue\n" - "+ *\t@msq contains the message queue being restored.\n" - "+ *\t@secid is the secid corresponding to the checkpointed context.\n" - "+ *\tReturn 0 if an appropriate context was set and permission is granted.\n" - " *\n" - " * Security hooks for System V Shared Memory Segments\n" - " *\n" - "@@ -1172,6 +1187,11 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)\n" - " *\t@shmaddr contains the address to attach memory region to.\n" - " *\t@shmflg contains the operational flags.\n" - " *\tReturn 0 if permission is granted.\n" - "+ * @shm_restore:\n" - "+ *\tSet permission on a newly restored shm\n" - "+ *\t@shm contains the shm being restored.\n" - "+ *\t@secid is the secid corresponding to the checkpointed context.\n" - "+ *\tReturn 0 if an appropriate context was set and permission is granted.\n" - " *\n" - " * Security hooks for System V Semaphores\n" - " *\n" - "@@ -1208,6 +1228,11 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)\n" - " *\t@nsops contains the number of operations to perform.\n" - " *\t@alter contains the flag indicating whether changes are to be made.\n" - " *\tReturn 0 if permission is granted.\n" - "+ * @sem_restore:\n" - "+ *\tSet permission on a newly restored sem\n" - "+ *\t@sem contains the sem being restored.\n" - "+ *\t@secid is the secid corresponding to the checkpointed context.\n" - "+ *\tReturn 0 if an appropriate context was set and permission is granted.\n" - " *\n" - " * @ptrace_may_access:\n" - " *\tCheck permission before allowing the current process to trace the\n" - "@@ -1499,6 +1524,8 @@ struct security_operations {\n" - " \n" - " \tint (*msg_msg_alloc_security) (struct msg_msg *msg);\n" - " \tvoid (*msg_msg_free_security) (struct msg_msg *msg);\n" - "+\tvoid (*msg_msg_getsecid) (struct msg_msg *msg, u32 *secid);\n" - "+\tint (*msg_msg_restore) (struct msg_msg *msg, u32 secid);\n" - " \n" - " \tint (*msg_queue_alloc_security) (struct msg_queue *msq);\n" - " \tvoid (*msg_queue_free_security) (struct msg_queue *msq);\n" - "@@ -1510,6 +1537,7 @@ struct security_operations {\n" - " \t\t\t\t struct msg_msg *msg,\n" - " \t\t\t\t struct task_struct *target,\n" - " \t\t\t\t long type, int mode);\n" - "+\tint (*msg_queue_restore) (struct msg_queue *msq, u32 secid);\n" - " \n" - " \tint (*shm_alloc_security) (struct shmid_kernel *shp);\n" - " \tvoid (*shm_free_security) (struct shmid_kernel *shp);\n" - "@@ -1517,6 +1545,7 @@ struct security_operations {\n" - " \tint (*shm_shmctl) (struct shmid_kernel *shp, int cmd);\n" - " \tint (*shm_shmat) (struct shmid_kernel *shp,\n" - " \t\t\t char __user *shmaddr, int shmflg);\n" - "+\tint (*shm_restore) (struct shmid_kernel *shp, u32 secid);\n" - " \n" - " \tint (*sem_alloc_security) (struct sem_array *sma);\n" - " \tvoid (*sem_free_security) (struct sem_array *sma);\n" - "@@ -1524,6 +1553,7 @@ struct security_operations {\n" - " \tint (*sem_semctl) (struct sem_array *sma, int cmd);\n" - " \tint (*sem_semop) (struct sem_array *sma,\n" - " \t\t\t struct sembuf *sops, unsigned nsops, int alter);\n" - "+\tint (*sem_restore) (struct sem_array *sma, u32 secid);\n" - " \n" - " \tint (*netlink_send) (struct sock *sk, struct sk_buff *skb);\n" - " \tint (*netlink_recv) (struct sk_buff *skb, int cap);\n" - "@@ -1748,6 +1778,8 @@ int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag);\n" - " void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid);\n" - " int security_msg_msg_alloc(struct msg_msg *msg);\n" - " void security_msg_msg_free(struct msg_msg *msg);\n" - "+void security_msg_msg_getsecid(struct msg_msg *msg, u32 *secid);\n" - "+int security_msg_msg_restore(struct msg_msg *msg, u32 secid);\n" - " int security_msg_queue_alloc(struct msg_queue *msq);\n" - " void security_msg_queue_free(struct msg_queue *msq);\n" - " int security_msg_queue_associate(struct msg_queue *msq, int msqflg);\n" - "@@ -1756,17 +1788,20 @@ int security_msg_queue_msgsnd(struct msg_queue *msq,\n" - " \t\t\t struct msg_msg *msg, int msqflg);\n" - " int security_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,\n" - " \t\t\t struct task_struct *target, long type, int mode);\n" - "+int security_msg_queue_restore(struct msg_queue *msq, u32 secid);\n" - " int security_shm_alloc(struct shmid_kernel *shp);\n" - " void security_shm_free(struct shmid_kernel *shp);\n" - " int security_shm_associate(struct shmid_kernel *shp, int shmflg);\n" - " int security_shm_shmctl(struct shmid_kernel *shp, int cmd);\n" - " int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmflg);\n" - "+int security_shm_restore(struct shmid_kernel *shp, u32 secid);\n" - " int security_sem_alloc(struct sem_array *sma);\n" - " void security_sem_free(struct sem_array *sma);\n" - " int security_sem_associate(struct sem_array *sma, int semflg);\n" - " int security_sem_semctl(struct sem_array *sma, int cmd);\n" - " int security_sem_semop(struct sem_array *sma, struct sembuf *sops,\n" - " \t\t\tunsigned nsops, int alter);\n" - "+int security_sem_restore(struct sem_array *sma, u32 secid);\n" - " void security_d_instantiate(struct dentry *dentry, struct inode *inode);\n" - " int security_getprocattr(struct task_struct *p, char *name, char **value);\n" - " int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size);\n" - "@@ -2393,6 +2428,18 @@ static inline int security_msg_msg_alloc(struct msg_msg *msg)\n" - " \treturn 0;\n" - " }\n" - " \n" - "+static inline void security_msg_msg_getsecid(struct msg_msg *msg, u32 *secid)\n" - "+{\n" - "+\t*secid = 0;\n" - "+}\n" - "+\n" - "+static inline int security_msg_msg_restore(struct msg_msg *msg, u32 secid)\n" - "+{\n" - "+\tif (secid)\n" - "+\t\treturn -EINVAL;\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - " static inline void security_msg_msg_free(struct msg_msg *msg)\n" - " { }\n" - " \n" - "@@ -2429,6 +2476,14 @@ static inline int security_msg_queue_msgrcv(struct msg_queue *msq,\n" - " \treturn 0;\n" - " }\n" - " \n" - "+static inline int security_msg_queue_restore(struct msg_queue *msq,\n" - "+\t\t\t\t\t\tu32 secid)\n" - "+{\n" - "+\tif (secid)\n" - "+\t\treturn -EINVAL;\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - " static inline int security_shm_alloc(struct shmid_kernel *shp)\n" - " {\n" - " \treturn 0;\n" - "@@ -2454,6 +2509,14 @@ static inline int security_shm_shmat(struct shmid_kernel *shp,\n" - " \treturn 0;\n" - " }\n" - " \n" - "+static inline int security_shm_restore(struct shmid_kernel *shp,\n" - "+\t\t\t\t\tu32 secid)\n" - "+{\n" - "+\tif (secid)\n" - "+\t\treturn -EINVAL;\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - " static inline int security_sem_alloc(struct sem_array *sma)\n" - " {\n" - " \treturn 0;\n" - "@@ -2479,6 +2542,14 @@ static inline int security_sem_semop(struct sem_array *sma,\n" - " \treturn 0;\n" - " }\n" - " \n" - "+static inline int security_sem_restore(struct sem_array *sma,\n" - "+\t\t\t\t\tu32 secid)\n" - "+{\n" - "+\tif (secid)\n" - "+\t\treturn -EINVAL;\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - " static inline void security_d_instantiate(struct dentry *dentry, struct inode *inode)\n" - " { }\n" - " \n" - "@@ -2975,7 +3046,28 @@ static inline char *alloc_secdata(void)\n" - " \n" - " static inline void free_secdata(void *secdata)\n" - " { }\n" - "+\n" - "+#endif /* CONFIG_SECURITY */\n" - "+\n" - "+#ifdef CONFIG_CHECKPOINT\n" - "+struct sec_store {\n" - "+\tint secid; /* LSM secid */\n" - "+\tint secref; /* objhash reference */\n" - "+\tstruct list_head list;\n" - "+};\n" - "+#ifdef CONFIG_SECURITY\n" - "+extern int checkpoint_security(struct ckpt_ctx *ctx, void *ptr);\n" - "+extern void *restore_security(struct ckpt_ctx *ctx);\n" - "+extern int checkpoint_security_getsecref(struct ckpt_ctx *ctx, int secid);\n" - "+#else /* CONFIG_SECURITY */\n" - "+#define checkpoint_security checkpoint_bad\n" - "+#define restore_security restore_bad\n" - "+static inline int checkpoint_security_getsecref(struct ckpt_ctx *ctx, int secid)\n" - "+{\n" - "+\treturn 0;\n" - "+}\n" - " #endif /* CONFIG_SECURITY */\n" - "+#endif /* CONFIG_CHECKPOINT */\n" - " \n" - " #endif /* ! __LINUX_SECURITY_H */\n" - " \n" - "diff --git a/ipc/checkpoint.c b/ipc/checkpoint.c\n" - "index 88996e2..b7641e2 100644\n" - "--- a/ipc/checkpoint.c\n" - "+++ b/ipc/checkpoint.c\n" - "@@ -15,6 +15,7 @@\n" - " #include <linux/msg.h>\n" - " #include <linux/sched.h>\n" - " #include <linux/ipc_namespace.h>\n" - "+#include <linux/security.h>\n" - " #include <linux/checkpoint.h>\n" - " #include <linux/checkpoint_hdr.h>\n" - " \n" - "@@ -31,9 +32,12 @@ static char *ipc_ind_to_str[] = { \"sem\", \"msg\", \"shm\" };\n" - " * Checkpoint\n" - " */\n" - " \n" - "-int checkpoint_fill_ipc_perms(struct ckpt_hdr_ipc_perms *h,\n" - "+int checkpoint_fill_ipc_perms(struct ckpt_ctx *ctx,\n" - "+\t\t\t struct ckpt_hdr_ipc_perms *h,\n" - " \t\t\t struct kern_ipc_perm *perm)\n" - " {\n" - "+\tint secid;\n" - "+\n" - " \tif (ipcperms(perm, S_IROTH))\n" - " \t\treturn -EACCES;\n" - " \n" - "@@ -46,6 +50,11 @@ int checkpoint_fill_ipc_perms(struct ckpt_hdr_ipc_perms *h,\n" - " \th->mode = perm->mode & S_IRWXUGO;\n" - " \th->seq = perm->seq;\n" - " \n" - "+\tsecurity_ipc_getsecid(perm, &secid);\n" - "+\th->secref = checkpoint_security_getsecref(ctx, secid);\n" - "+\tif (h->secref < 0)\n" - "+\t\treturn h->secref;\n" - "+\n" - " \treturn 0;\n" - " }\n" - " \n" - "@@ -185,13 +194,10 @@ int restore_load_ipc_perms(struct ckpt_hdr_ipc_perms *h,\n" - " \tperm->mode = h->mode;\n" - " \tperm->seq = h->seq;\n" - " \t/*\n" - "-\t * Todo: restore perm->security.\n" - "-\t * At the moment it gets set by security_x_alloc() called through\n" - "-\t * ipcget()->ipcget_public()->ops-.getnew (->nequeue for instance)\n" - "-\t * We will want to ask the LSM to consider resetting the\n" - "-\t * checkpointed ->security, based on current_security(),\n" - "-\t * the checkpointed ->security, and the checkpoint file context.\n" - "+\t * The checkpointed ->security value will be restored\n" - "+\t * (and verified) by our caller.\n" - " \t */\n" - "+\tperm->security = NULL;\n" - " \n" - " \treturn 0;\n" - " }\n" - "diff --git a/ipc/checkpoint_msg.c b/ipc/checkpoint_msg.c\n" - "index 51385b0..ca55339 100644\n" - "--- a/ipc/checkpoint_msg.c\n" - "+++ b/ipc/checkpoint_msg.c\n" - "@@ -17,6 +17,7 @@\n" - " #include <linux/sched.h>\n" - " #include <linux/syscalls.h>\n" - " #include <linux/nsproxy.h>\n" - "+#include <linux/security.h>\n" - " #include <linux/ipc_namespace.h>\n" - " \n" - " #include \"util.h\"\n" - "@@ -36,7 +37,7 @@ static int fill_ipc_msg_hdr(struct ckpt_ctx *ctx,\n" - " \n" - " \tipc_lock_by_ptr(&msq->q_perm);\n" - " \n" - "-\tret = checkpoint_fill_ipc_perms(&h->perms, &msq->q_perm);\n" - "+\tret = checkpoint_fill_ipc_perms(ctx, &h->perms, &msq->q_perm);\n" - " \tif (ret < 0)\n" - " \t\tgoto unlock;\n" - " \n" - "@@ -62,12 +63,19 @@ static int checkpoint_msg_contents(struct ckpt_ctx *ctx, struct msg_msg *msg)\n" - " \tstruct ckpt_hdr_ipc_msg_msg *h;\n" - " \tstruct msg_msgseg *seg;\n" - " \tint total, len;\n" - "-\tint ret;\n" - "+\tint ret, secid, secref;\n" - "+\n" - "+\tsecurity_msg_msg_getsecid(msg, &secid);\n" - "+\tsecref = checkpoint_security_getsecref(ctx, secid);\n" - "+\tif (secref < 0)\n" - "+\t\treturn secref;\n" - " \n" - " \th = ckpt_hdr_get_type(ctx, sizeof(*h), CKPT_HDR_IPC_MSG_MSG);\n" - " \tif (!h)\n" - " \t\treturn -ENOMEM;\n" - " \n" - "+\th->secref = secref;\n" - "+\n" - " \th->m_type = msg->m_type;\n" - " \th->m_ts = msg->m_ts;\n" - " \n" - "@@ -175,11 +183,26 @@ static int load_ipc_msg_hdr(struct ckpt_ctx *ctx,\n" - " \t\t\t struct msg_queue *msq)\n" - " {\n" - " \tint ret = 0;\n" - "+\tint secid = 0;\n" - " \n" - " \tret = restore_load_ipc_perms(&h->perms, &msq->q_perm);\n" - " \tif (ret < 0)\n" - " \t\treturn ret;\n" - " \n" - "+\tif (h->perms.secref) {\n" - "+\t\tstruct sec_store *s;\n" - "+\t\ts = ckpt_obj_fetch(ctx, h->perms.secref, CKPT_OBJ_SECURITY);\n" - "+\t\tif (IS_ERR(s))\n" - "+\t\t\treturn PTR_ERR(s);\n" - "+\t\tsecid = s->secid;\n" - "+\t}\n" - "+\tret = security_msg_queue_alloc(msq);\n" - "+\tif (ret)\n" - "+\t\treturn ret;\n" - "+\tret = security_msg_queue_restore(msq, secid);\n" - "+\tif (ret < 0)\n" - "+\t\treturn ret;\n" - "+\n" - " \tckpt_debug(\"msq: lspid %d lrpid %d qnum %lld qbytes %lld\\n\",\n" - " \t\t h->q_lspid, h->q_lrpid, h->q_qnum, h->q_qbytes);\n" - " \n" - "@@ -201,7 +224,7 @@ static struct msg_msg *restore_msg_contents_one(struct ckpt_ctx *ctx, int *clen)\n" - " \tstruct msg_msg *msg = NULL;\n" - " \tstruct msg_msgseg *seg, **pseg;\n" - " \tint total, len;\n" - "-\tint ret;\n" - "+\tint ret, secid = 0;\n" - " \n" - " \th = ckpt_read_obj_type(ctx, sizeof(*h), CKPT_HDR_IPC_MSG_MSG);\n" - " \tif (IS_ERR(h))\n" - "@@ -245,6 +268,22 @@ static struct msg_msg *restore_msg_contents_one(struct ckpt_ctx *ctx, int *clen)\n" - " \t\ttotal -= len;\n" - " \t}\n" - " \n" - "+\tif (h->secref) {\n" - "+\t\tstruct sec_store *s;\n" - "+\t\ts = ckpt_obj_fetch(ctx, h->secref, CKPT_OBJ_SECURITY);\n" - "+\t\tif (IS_ERR(s)) {\n" - "+\t\t\tret = PTR_ERR(s);\n" - "+\t\t\tgoto out;\n" - "+\t\t}\n" - "+\t\tsecid = s->secid;\n" - "+\t}\n" - "+\tret = security_msg_msg_alloc(msg);\n" - "+\tif (ret)\n" - "+\t\tgoto out;\n" - "+\tret = security_msg_msg_restore(msg, secid);\n" - "+\tif (ret < 0)\n" - "+\t\tgoto out;\n" - "+\n" - " \tmsg->m_type = h->m_type;\n" - " \tmsg->m_ts = h->m_ts;\n" - " \t*clen = h->m_ts;\n" - "diff --git a/ipc/checkpoint_sem.c b/ipc/checkpoint_sem.c\n" - "index 64d61ee..609750b 100644\n" - "--- a/ipc/checkpoint_sem.c\n" - "+++ b/ipc/checkpoint_sem.c\n" - "@@ -17,6 +17,7 @@\n" - " #include <linux/sched.h>\n" - " #include <linux/syscalls.h>\n" - " #include <linux/nsproxy.h>\n" - "+#include <linux/security.h>\n" - " #include <linux/ipc_namespace.h>\n" - " \n" - " struct msg_msg;\n" - "@@ -37,7 +38,7 @@ static int fill_ipc_sem_hdr(struct ckpt_ctx *ctx,\n" - " \n" - " \tipc_lock_by_ptr(&sem->sem_perm);\n" - " \n" - "-\tret = checkpoint_fill_ipc_perms(&h->perms, &sem->sem_perm);\n" - "+\tret = checkpoint_fill_ipc_perms(ctx, &h->perms, &sem->sem_perm);\n" - " \tif (ret < 0)\n" - " \t\tgoto unlock;\n" - " \n" - "@@ -112,11 +113,26 @@ static int load_ipc_sem_hdr(struct ckpt_ctx *ctx,\n" - " \t\t\t struct sem_array *sem)\n" - " {\n" - " \tint ret = 0;\n" - "+\tint secid = 0;\n" - " \n" - " \tret = restore_load_ipc_perms(&h->perms, &sem->sem_perm);\n" - " \tif (ret < 0)\n" - " \t\treturn ret;\n" - " \n" - "+\tif (h->perms.secref) {\n" - "+\t\tstruct sec_store *s;\n" - "+\t\ts = ckpt_obj_fetch(ctx, h->perms.secref, CKPT_OBJ_SECURITY);\n" - "+\t\tif (IS_ERR(s))\n" - "+\t\t\treturn PTR_ERR(s);\n" - "+\t\tsecid = s->secid;\n" - "+\t}\n" - "+\tret = security_sem_alloc(sem);\n" - "+\tif (ret)\n" - "+\t\treturn ret;\n" - "+\tret = security_sem_restore(sem, secid);\n" - "+\tif (ret < 0)\n" - "+\t\treturn ret;\n" - "+\n" - " \tckpt_debug(\"sem: nsems %u\\n\", h->sem_nsems);\n" - " \n" - " \tsem->sem_otime = h->sem_otime;\n" - "diff --git a/ipc/checkpoint_shm.c b/ipc/checkpoint_shm.c\n" - "index 41bacfb..a2a0e41 100644\n" - "--- a/ipc/checkpoint_shm.c\n" - "+++ b/ipc/checkpoint_shm.c\n" - "@@ -21,6 +21,7 @@\n" - " #include <linux/syscalls.h>\n" - " #include <linux/nsproxy.h>\n" - " #include <linux/ipc_namespace.h>\n" - "+#include <linux/security.h>\n" - " #include <linux/deferqueue.h>\n" - " \n" - " #include <linux/msg.h>\t/* needed for util.h that uses 'struct msg_msg' */\n" - "@@ -41,7 +42,7 @@ static int fill_ipc_shm_hdr(struct ckpt_ctx *ctx,\n" - " \n" - " \tipc_lock_by_ptr(&shp->shm_perm);\n" - " \n" - "-\tret = checkpoint_fill_ipc_perms(&h->perms, &shp->shm_perm);\n" - "+\tret = checkpoint_fill_ipc_perms(ctx, &h->perms, &shp->shm_perm);\n" - " \tif (ret < 0)\n" - " \t\tgoto unlock;\n" - " \n" - "@@ -148,11 +149,26 @@ static int load_ipc_shm_hdr(struct ckpt_ctx *ctx,\n" - " \t\t\t struct shmid_kernel *shp)\n" - " {\n" - " \tint ret;\n" - "+\tint secid = 0;\n" - " \n" - " \tret = restore_load_ipc_perms(&h->perms, &shp->shm_perm);\n" - " \tif (ret < 0)\n" - " \t\treturn ret;\n" - " \n" - "+\tif (h->perms.secref) {\n" - "+\t\tstruct sec_store *s;\n" - "+\t\ts = ckpt_obj_fetch(ctx, h->perms.secref, CKPT_OBJ_SECURITY);\n" - "+\t\tif (IS_ERR(s))\n" - "+\t\t\treturn PTR_ERR(s);\n" - "+\t\tsecid = s->secid;\n" - "+\t}\n" - "+\tret = security_shm_alloc(shp);\n" - "+\tif (ret)\n" - "+\t\treturn ret;\n" - "+\tret = security_shm_restore(shp, secid);\n" - "+\tif (ret < 0)\n" - "+\t\treturn ret;\n" - "+\n" - " \tckpt_debug(\"shm: cprid %d lprid %d segsz %lld mlock %d\\n\",\n" - " \t\t h->shm_cprid, h->shm_lprid, h->shm_segsz, h->mlock_uid);\n" - " \n" - "diff --git a/ipc/util.h b/ipc/util.h\n" - "index fa974eb..bed25bd 100644\n" - "--- a/ipc/util.h\n" - "+++ b/ipc/util.h\n" - "@@ -199,7 +199,8 @@ extern void freeary(struct ipc_namespace *, struct kern_ipc_perm *);\n" - " extern void do_shm_rmid(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp);\n" - " \n" - " #ifdef CONFIG_CHECKPOINT\n" - "-extern int checkpoint_fill_ipc_perms(struct ckpt_hdr_ipc_perms *h,\n" - "+extern int checkpoint_fill_ipc_perms(struct ckpt_ctx *ctx,\n" - "+\t\t\t\t struct ckpt_hdr_ipc_perms *h,\n" - " \t\t\t\t struct kern_ipc_perm *perm);\n" - " extern int restore_load_ipc_perms(struct ckpt_hdr_ipc_perms *h,\n" - " \t\t\t\t struct kern_ipc_perm *perm);\n" - "diff --git a/security/capability.c b/security/capability.c\n" - "index 21b6cea..d0d2e39 100644\n" - "--- a/security/capability.c\n" - "+++ b/security/capability.c\n" - "@@ -494,6 +494,18 @@ static void cap_msg_msg_free_security(struct msg_msg *msg)\n" - " {\n" - " }\n" - " \n" - "+static void cap_msg_msg_getsecid(struct msg_msg *msg, u32 *secid)\n" - "+{\n" - "+\t*secid = 0;\n" - "+}\n" - "+\n" - "+static int cap_msg_msg_restore(struct msg_msg *msg, u32 secid)\n" - "+{\n" - "+\tif (secid)\n" - "+\t\treturn -EINVAL;\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - " static int cap_msg_queue_alloc_security(struct msg_queue *msq)\n" - " {\n" - " \treturn 0;\n" - "@@ -525,6 +537,13 @@ static int cap_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,\n" - " \treturn 0;\n" - " }\n" - " \n" - "+static int cap_msg_queue_restore(struct msg_queue *msq, u32 secid)\n" - "+{\n" - "+\tif (secid)\n" - "+\t\treturn -EINVAL;\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - " static int cap_shm_alloc_security(struct shmid_kernel *shp)\n" - " {\n" - " \treturn 0;\n" - "@@ -550,6 +569,13 @@ static int cap_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr,\n" - " \treturn 0;\n" - " }\n" - " \n" - "+static int cap_shm_restore(struct shmid_kernel *shp, u32 secid)\n" - "+{\n" - "+\tif (secid)\n" - "+\t\treturn -EINVAL;\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - " static int cap_sem_alloc_security(struct sem_array *sma)\n" - " {\n" - " \treturn 0;\n" - "@@ -575,6 +601,13 @@ static int cap_sem_semop(struct sem_array *sma, struct sembuf *sops,\n" - " \treturn 0;\n" - " }\n" - " \n" - "+static int cap_sem_restore(struct sem_array *sma, u32 secid)\n" - "+{\n" - "+\tif (secid)\n" - "+\t\treturn -EINVAL;\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - " #ifdef CONFIG_SECURITY_NETWORK\n" - " static int cap_unix_stream_connect(struct socket *sock, struct socket *other,\n" - " \t\t\t\t struct sock *newsk)\n" - "@@ -977,22 +1010,27 @@ void security_fixup_ops(struct security_operations *ops)\n" - " \tset_to_cap_if_null(ops, ipc_getsecid);\n" - " \tset_to_cap_if_null(ops, msg_msg_alloc_security);\n" - " \tset_to_cap_if_null(ops, msg_msg_free_security);\n" - "+\tset_to_cap_if_null(ops, msg_msg_getsecid);\n" - "+\tset_to_cap_if_null(ops, msg_msg_restore);\n" - " \tset_to_cap_if_null(ops, msg_queue_alloc_security);\n" - " \tset_to_cap_if_null(ops, msg_queue_free_security);\n" - " \tset_to_cap_if_null(ops, msg_queue_associate);\n" - " \tset_to_cap_if_null(ops, msg_queue_msgctl);\n" - " \tset_to_cap_if_null(ops, msg_queue_msgsnd);\n" - " \tset_to_cap_if_null(ops, msg_queue_msgrcv);\n" - "+\tset_to_cap_if_null(ops, msg_queue_restore);\n" - " \tset_to_cap_if_null(ops, shm_alloc_security);\n" - " \tset_to_cap_if_null(ops, shm_free_security);\n" - " \tset_to_cap_if_null(ops, shm_associate);\n" - " \tset_to_cap_if_null(ops, shm_shmctl);\n" - " \tset_to_cap_if_null(ops, shm_shmat);\n" - "+\tset_to_cap_if_null(ops, shm_restore);\n" - " \tset_to_cap_if_null(ops, sem_alloc_security);\n" - " \tset_to_cap_if_null(ops, sem_free_security);\n" - " \tset_to_cap_if_null(ops, sem_associate);\n" - " \tset_to_cap_if_null(ops, sem_semctl);\n" - " \tset_to_cap_if_null(ops, sem_semop);\n" - "+\tset_to_cap_if_null(ops, sem_restore);\n" - " \tset_to_cap_if_null(ops, netlink_send);\n" - " \tset_to_cap_if_null(ops, netlink_recv);\n" - " \tset_to_cap_if_null(ops, d_instantiate);\n" - "diff --git a/security/security.c b/security/security.c\n" - "index 5284255..d737e0e 100644\n" - "--- a/security/security.c\n" - "+++ b/security/security.c\n" - "@@ -16,6 +16,7 @@\n" - " #include <linux/init.h>\n" - " #include <linux/kernel.h>\n" - " #include <linux/security.h>\n" - "+#include <linux/checkpoint.h>\n" - " \n" - " /* Boot-time LSM user choice */\n" - " static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1];\n" - "@@ -832,6 +833,16 @@ void security_msg_msg_free(struct msg_msg *msg)\n" - " \tsecurity_ops->msg_msg_free_security(msg);\n" - " }\n" - " \n" - "+void security_msg_msg_getsecid(struct msg_msg *msg, u32 *secid)\n" - "+{\n" - "+\tsecurity_ops->msg_msg_getsecid(msg, secid);\n" - "+}\n" - "+\n" - "+int security_msg_msg_restore(struct msg_msg *msg, u32 secid)\n" - "+{\n" - "+\treturn security_ops->msg_msg_restore(msg, secid);\n" - "+}\n" - "+\n" - " int security_msg_queue_alloc(struct msg_queue *msq)\n" - " {\n" - " \treturn security_ops->msg_queue_alloc_security(msq);\n" - "@@ -864,6 +875,11 @@ int security_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,\n" - " \treturn security_ops->msg_queue_msgrcv(msq, msg, target, type, mode);\n" - " }\n" - " \n" - "+int security_msg_queue_restore(struct msg_queue *msq, u32 secid)\n" - "+{\n" - "+\treturn security_ops->msg_queue_restore(msq, secid);\n" - "+}\n" - "+\n" - " int security_shm_alloc(struct shmid_kernel *shp)\n" - " {\n" - " \treturn security_ops->shm_alloc_security(shp);\n" - "@@ -889,6 +905,11 @@ int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmfl\n" - " \treturn security_ops->shm_shmat(shp, shmaddr, shmflg);\n" - " }\n" - " \n" - "+int security_shm_restore(struct shmid_kernel *shp, u32 secid)\n" - "+{\n" - "+\treturn security_ops->shm_restore(shp, secid);\n" - "+}\n" - "+\n" - " int security_sem_alloc(struct sem_array *sma)\n" - " {\n" - " \treturn security_ops->sem_alloc_security(sma);\n" - "@@ -915,6 +936,11 @@ int security_sem_semop(struct sem_array *sma, struct sembuf *sops,\n" - " \treturn security_ops->sem_semop(sma, sops, nsops, alter);\n" - " }\n" - " \n" - "+int security_sem_restore(struct sem_array *sma, u32 secid)\n" - "+{\n" - "+\treturn security_ops->sem_restore(sma, secid);\n" - "+}\n" - "+\n" - " void security_d_instantiate(struct dentry *dentry, struct inode *inode)\n" - " {\n" - " \tif (unlikely(inode && IS_PRIVATE(inode)))\n" - "@@ -1247,3 +1273,146 @@ int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule,\n" - " }\n" - " \n" - " #endif /* CONFIG_AUDIT */\n" - "+\n" - "+#ifdef CONFIG_CHECKPOINT\n" - "+\n" - "+static int do_checkpoint_security(struct ckpt_ctx *ctx,\n" - "+\t\t\t\tstruct sec_store *s)\n" - "+{\n" - "+\tchar *str;\n" - "+\tint ret, len;\n" - "+\n" - "+\tret = security_secid_to_secctx(s->secid, &str, &len);\n" - "+\tif (ret)\n" - "+\t\treturn ret;\n" - "+\tret = ckpt_write_obj_type(ctx, str, len, CKPT_HDR_SECURITY);\n" - "+\tsecurity_release_secctx(str, len);\n" - "+\treturn ret;\n" - "+}\n" - "+\n" - "+int checkpoint_security(struct ckpt_ctx *ctx, void *ptr)\n" - "+{\n" - "+\treturn do_checkpoint_security(ctx, (struct sec_store *) ptr);\n" - "+}\n" - "+\n" - "+/*\n" - "+ * stupid ordered list insertion Replace with rbtree or hash\n" - "+ * return 1 if the secid was already stored\n" - "+ * call with ctx->secref_lock held\n" - "+ */\n" - "+static int insert_secref(struct ckpt_ctx *ctx, struct sec_store *news)\n" - "+{\n" - "+\tstruct sec_store *last=NULL, *s;\n" - "+\n" - "+\tif (list_empty(&ctx->secref_list)) {\n" - "+\t\tlist_add(&news->list, &ctx->secref_list);\n" - "+\t\treturn 0;\n" - "+\t}\n" - "+\n" - "+\tlist_for_each_entry(s, &ctx->secref_list, list) {\n" - "+\t\tif (s->secid == news->secid)\n" - "+\t\t\t/* race */\n" - "+\t\t\treturn 1;\n" - "+\t\telse if (s->secid < news->secid)\n" - "+\t\t\tlast = s;\n" - "+\t\telse\n" - "+\t\t\tbreak;\n" - "+\t}\n" - "+\t/*\n" - "+\t * if last is not null, insert after last. Otherwise\n" - "+\t * this should be the first item\n" - "+\t */\n" - "+\tif (last)\n" - "+\t\tlist_add(&news->list, &last->list);\n" - "+\telse\n" - "+\t\tlist_add(&news->list, &ctx->secref_list);\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+/* just need some sane value */\n" - "+#define MAX_STR_LEN 300\n" - "+static struct sec_store *do_restore_security(struct ckpt_ctx *ctx)\n" - "+{\n" - "+\tstruct ckpt_hdr_sec *h;\n" - "+\tint id;\n" - "+\tint ret, conflict;\n" - "+\tstruct sec_store *s;\n" - "+\n" - "+\th = ckpt_read_buf_type(ctx, MAX_STR_LEN, CKPT_HDR_SECURITY);\n" - "+\tif (IS_ERR(h))\n" - "+\t\treturn ERR_PTR(PTR_ERR(h));\n" - "+\tret = security_secctx_to_secid(h->str, strlen(h->str)+1, &id);\n" - "+\tckpt_hdr_put(ctx, h);\n" - "+\tif (ret < 0)\n" - "+\t\treturn ERR_PTR(ret);\n" - "+\ts = kmalloc(sizeof(*s), GFP_KERNEL);\n" - "+\tif (!s)\n" - "+\t\treturn ERR_PTR(-ENOMEM);\n" - "+\ts->secid = id;\n" - "+\tspin_lock(&ctx->secref_lock);\n" - "+\tconflict = insert_secref(ctx, s);\n" - "+\tspin_unlock(&ctx->secref_lock);\n" - "+\tif (conflict) /* not possible */\n" - "+\t\treturn ERR_PTR(-EINVAL);\n" - "+\treturn s;\n" - "+}\n" - "+\n" - "+void *restore_security(struct ckpt_ctx *ctx)\n" - "+{\n" - "+\treturn (void *) do_restore_security(ctx);\n" - "+}\n" - "+\n" - "+/*\n" - "+ * if there's already a cached entry with secid, return\n" - "+ * its secref. Return -1 if there is no such entry. If\n" - "+ * LSMs are actually not supported, then a value of 0 may\n" - "+ * in fact be returned as the secref\n" - "+ */\n" - "+static int get_secref_from_secid(struct ckpt_ctx *ctx, int secid)\n" - "+{\n" - "+\tint ret = -1;\n" - "+\tstruct sec_store *s;\n" - "+\n" - "+\tspin_lock(&ctx->secref_lock);\n" - "+\tlist_for_each_entry(s, &ctx->secref_list, list)\n" - "+\t\tif (s->secid == secid) {\n" - "+\t\t\tret = s->secref;\n" - "+\t\t\tbreak;\n" - "+\t\t}\n" - "+\tspin_unlock(&ctx->secref_lock);\n" - "+\treturn ret;\n" - "+}\n" - "+\n" - "+/*\n" - "+ * get a objhash reference from a secid\n" - "+ * if already stored, return existing ref\n" - "+ * else checkpoint it and return the new ref\n" - "+ */\n" - "+int checkpoint_security_getsecref(struct ckpt_ctx *ctx, int secid)\n" - "+{\n" - "+\tint ret, conflict=0, secref = 0;\n" - "+\tstruct sec_store *s;\n" - "+\n" - "+again:\n" - "+\tret = get_secref_from_secid(ctx, secid);\n" - "+\tif (ret >= 0)\n" - "+\t\treturn ret;\n" - "+\tBUG_ON(conflict!=0); /* a racer added it to list, but now it's gone? */\n" - "+\ts = kzalloc(sizeof(*s), GFP_KERNEL);\n" - "+\tif (!s)\n" - "+\t\treturn -ENOMEM;\n" - "+\ts->secid = secid;\n" - "+\tspin_lock(&ctx->secref_lock);\n" - "+\tconflict = insert_secref(ctx, s);\n" - "+\tif (conflict) {\n" - "+\t\tspin_unlock(&ctx->secref_lock);\n" - "+\t\tkfree(s);\n" - "+\t\tgoto again;\n" - "+\t}\n" - "+\tif (secid != 0)\n" - "+\t\tsecref = checkpoint_obj(ctx, s, CKPT_OBJ_SECURITY);\n" - "+\ts->secref = secref;\n" - "+\tspin_unlock(&ctx->secref_lock);\n" - "+\treturn secref;\n" - "+}\n" - "+#endif\n" - "diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c\n" - "index 2fcad7c..591f545 100644\n" - "--- a/security/selinux/hooks.c\n" - "+++ b/security/selinux/hooks.c\n" - "@@ -4675,6 +4675,19 @@ static void msg_msg_free_security(struct msg_msg *msg)\n" - " \tkfree(msec);\n" - " }\n" - " \n" - "+static int selinux_msg_msg_restore(struct msg_msg *msg, u32 secid)\n" - "+{\n" - "+\tstruct msg_security_struct *msec = msg->security;\n" - "+\tu32 sid = current_sid();\n" - "+\tint ret;\n" - "+\n" - "+\tret = avc_has_perm(sid, secid, SECCLASS_MSG, MSG__RESTORE, NULL);\n" - "+\tif (ret)\n" - "+\t\treturn ret;\n" - "+\tmsec->sid = secid;\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - " static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,\n" - " \t\t\tu32 perms)\n" - " {\n" - "@@ -4700,6 +4713,12 @@ static void selinux_msg_msg_free_security(struct msg_msg *msg)\n" - " \tmsg_msg_free_security(msg);\n" - " }\n" - " \n" - "+static void selinux_msg_msg_getsecid(struct msg_msg *msg, u32 *secid)\n" - "+{\n" - "+\tstruct msg_security_struct *msec = msg->security;\n" - "+\t*secid = msec->sid;\n" - "+}\n" - "+\n" - " /* message queue security operations */\n" - " static int selinux_msg_queue_alloc_security(struct msg_queue *msq)\n" - " {\n" - "@@ -4841,6 +4860,14 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,\n" - " \treturn rc;\n" - " }\n" - " \n" - "+static int selinux_msg_queue_restore(struct msg_queue *msq, u32 secid)\n" - "+{\n" - "+\tstruct ipc_security_struct *isec = msq->q_perm.security;\n" - "+\n" - "+\tisec->sid = secid;\n" - "+\treturn ipc_has_perm(&msq->q_perm, MSGQ__RESTORE);\n" - "+}\n" - "+\n" - " /* Shared Memory security operations */\n" - " static int selinux_shm_alloc_security(struct shmid_kernel *shp)\n" - " {\n" - "@@ -4933,6 +4960,14 @@ static int selinux_shm_shmat(struct shmid_kernel *shp,\n" - " \treturn ipc_has_perm(&shp->shm_perm, perms);\n" - " }\n" - " \n" - "+static int selinux_shm_restore(struct shmid_kernel *shp, u32 secid)\n" - "+{\n" - "+\tstruct ipc_security_struct *isec = shp->shm_perm.security;\n" - "+\n" - "+\tisec->sid = secid;\n" - "+\treturn ipc_has_perm(&shp->shm_perm, SHM__RESTORE);\n" - "+}\n" - "+\n" - " /* Semaphore security operations */\n" - " static int selinux_sem_alloc_security(struct sem_array *sma)\n" - " {\n" - "@@ -5034,6 +5069,14 @@ static int selinux_sem_semop(struct sem_array *sma,\n" - " \treturn ipc_has_perm(&sma->sem_perm, perms);\n" - " }\n" - " \n" - "+static int selinux_sem_restore(struct sem_array *sma, u32 secid)\n" - "+{\n" - "+\tstruct ipc_security_struct *isec = sma->sem_perm.security;\n" - "+\n" - "+\tisec->sid = secid;\n" - "+\treturn ipc_has_perm(&sma->sem_perm, SEM__RESTORE);\n" - "+}\n" - "+\n" - " static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)\n" - " {\n" - " \tu32 av = 0;\n" - "@@ -5415,6 +5458,8 @@ static struct security_operations selinux_ops = {\n" - " \n" - " \t.msg_msg_alloc_security =\tselinux_msg_msg_alloc_security,\n" - " \t.msg_msg_free_security =\tselinux_msg_msg_free_security,\n" - "+\t.msg_msg_getsecid =\t\tselinux_msg_msg_getsecid,\n" - "+\t.msg_msg_restore =\t\tselinux_msg_msg_restore,\n" - " \n" - " \t.msg_queue_alloc_security =\tselinux_msg_queue_alloc_security,\n" - " \t.msg_queue_free_security =\tselinux_msg_queue_free_security,\n" - "@@ -5422,18 +5467,21 @@ static struct security_operations selinux_ops = {\n" - " \t.msg_queue_msgctl =\t\tselinux_msg_queue_msgctl,\n" - " \t.msg_queue_msgsnd =\t\tselinux_msg_queue_msgsnd,\n" - " \t.msg_queue_msgrcv =\t\tselinux_msg_queue_msgrcv,\n" - "+\t.msg_queue_restore =\t\tselinux_msg_queue_restore,\n" - " \n" - " \t.shm_alloc_security =\t\tselinux_shm_alloc_security,\n" - " \t.shm_free_security =\t\tselinux_shm_free_security,\n" - " \t.shm_associate =\t\tselinux_shm_associate,\n" - " \t.shm_shmctl =\t\t\tselinux_shm_shmctl,\n" - " \t.shm_shmat =\t\t\tselinux_shm_shmat,\n" - "+\t.shm_restore =\t\t\tselinux_shm_restore,\n" - " \n" - " \t.sem_alloc_security =\t\tselinux_sem_alloc_security,\n" - " \t.sem_free_security =\t\tselinux_sem_free_security,\n" - " \t.sem_associate =\t\tselinux_sem_associate,\n" - " \t.sem_semctl =\t\t\tselinux_sem_semctl,\n" - " \t.sem_semop =\t\t\tselinux_sem_semop,\n" - "+\t.sem_restore =\t\t\tselinux_sem_restore,\n" - " \n" - " \t.d_instantiate =\t\tselinux_d_instantiate,\n" - " \n" - "diff --git a/security/selinux/include/av_inherit.h b/security/selinux/include/av_inherit.h\n" - "index 8377a4b..0d7689d 100644\n" - "--- a/security/selinux/include/av_inherit.h\n" - "+++ b/security/selinux/include/av_inherit.h\n" - "@@ -15,10 +15,10 @@\n" - " S_(SECCLASS_KEY_SOCKET, socket, 0x00400000UL)\n" - " S_(SECCLASS_UNIX_STREAM_SOCKET, socket, 0x00400000UL)\n" - " S_(SECCLASS_UNIX_DGRAM_SOCKET, socket, 0x00400000UL)\n" - "- S_(SECCLASS_IPC, ipc, 0x00000200UL)\n" - "- S_(SECCLASS_SEM, ipc, 0x00000200UL)\n" - "- S_(SECCLASS_MSGQ, ipc, 0x00000200UL)\n" - "- S_(SECCLASS_SHM, ipc, 0x00000200UL)\n" - "+ S_(SECCLASS_IPC, ipc, 0x00000400UL)\n" - "+ S_(SECCLASS_SEM, ipc, 0x00000400UL)\n" - "+ S_(SECCLASS_MSGQ, ipc, 0x00000400UL)\n" - "+ S_(SECCLASS_SHM, ipc, 0x00000400UL)\n" - " S_(SECCLASS_NETLINK_ROUTE_SOCKET, socket, 0x00400000UL)\n" - " S_(SECCLASS_NETLINK_FIREWALL_SOCKET, socket, 0x00400000UL)\n" - " S_(SECCLASS_NETLINK_TCPDIAG_SOCKET, socket, 0x00400000UL)\n" - "diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h\n" - "index d645192..3c3eba6 100644\n" - "--- a/security/selinux/include/av_permissions.h\n" - "+++ b/security/selinux/include/av_permissions.h\n" - "@@ -47,6 +47,7 @@\n" - " #define COMMON_IPC__ASSOCIATE 0x00000040UL\n" - " #define COMMON_IPC__UNIX_READ 0x00000080UL\n" - " #define COMMON_IPC__UNIX_WRITE 0x00000100UL\n" - "+#define COMMON_IPC__RESTORE 0x00000200UL\n" - " #define FILESYSTEM__MOUNT 0x00000001UL\n" - " #define FILESYSTEM__REMOUNT 0x00000002UL\n" - " #define FILESYSTEM__UNMOUNT 0x00000004UL\n" - "@@ -462,6 +463,7 @@\n" - " #define IPC__ASSOCIATE 0x00000040UL\n" - " #define IPC__UNIX_READ 0x00000080UL\n" - " #define IPC__UNIX_WRITE 0x00000100UL\n" - "+#define IPC__RESTORE 0x00000200UL\n" - " #define SEM__CREATE 0x00000001UL\n" - " #define SEM__DESTROY 0x00000002UL\n" - " #define SEM__GETATTR 0x00000004UL\n" - "@@ -471,6 +473,7 @@\n" - " #define SEM__ASSOCIATE 0x00000040UL\n" - " #define SEM__UNIX_READ 0x00000080UL\n" - " #define SEM__UNIX_WRITE 0x00000100UL\n" - "+#define SEM__RESTORE 0x00000200UL\n" - " #define MSGQ__CREATE 0x00000001UL\n" - " #define MSGQ__DESTROY 0x00000002UL\n" - " #define MSGQ__GETATTR 0x00000004UL\n" - "@@ -480,9 +483,11 @@\n" - " #define MSGQ__ASSOCIATE 0x00000040UL\n" - " #define MSGQ__UNIX_READ 0x00000080UL\n" - " #define MSGQ__UNIX_WRITE 0x00000100UL\n" - "-#define MSGQ__ENQUEUE 0x00000200UL\n" - "+#define MSGQ__RESTORE 0x00000200UL\n" - "+#define MSGQ__ENQUEUE 0x00000400UL\n" - " #define MSG__SEND 0x00000001UL\n" - " #define MSG__RECEIVE 0x00000002UL\n" - "+#define MSG__RESTORE 0x00000004UL\n" - " #define SHM__CREATE 0x00000001UL\n" - " #define SHM__DESTROY 0x00000002UL\n" - " #define SHM__GETATTR 0x00000004UL\n" - "@@ -492,7 +497,8 @@\n" - " #define SHM__ASSOCIATE 0x00000040UL\n" - " #define SHM__UNIX_READ 0x00000080UL\n" - " #define SHM__UNIX_WRITE 0x00000100UL\n" - "-#define SHM__LOCK 0x00000200UL\n" - "+#define SHM__RESTORE 0x00000200UL\n" - "+#define SHM__LOCK 0x00000400UL\n" - " #define SECURITY__COMPUTE_AV 0x00000001UL\n" - " #define SECURITY__COMPUTE_CREATE 0x00000002UL\n" - " #define SECURITY__COMPUTE_MEMBER 0x00000004UL\n" - "diff --git a/security/selinux/include/common_perm_to_string.h b/security/selinux/include/common_perm_to_string.h\n" - "index ce5b6e2..fb94053 100644\n" - "--- a/security/selinux/include/common_perm_to_string.h\n" - "+++ b/security/selinux/include/common_perm_to_string.h\n" - "@@ -54,5 +54,6 @@ TB_(common_ipc_perm_to_string)\n" - " S_(\"associate\")\n" - " S_(\"unix_read\")\n" - " S_(\"unix_write\")\n" - "+ S_(\"restore\")\n" - " TE_(common_ipc_perm_to_string)\n" - " \n" - "diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c\n" - "index 98b3195..070aeb7 100644\n" - "--- a/security/smack/smack_lsm.c\n" - "+++ b/security/smack/smack_lsm.c\n" - "@@ -1619,6 +1619,33 @@ static void smack_msg_msg_free_security(struct msg_msg *msg)\n" - " }\n" - " \n" - " /**\n" - "+ * smack_msg_msg_getsecid - Extract smack security id\n" - "+ * @msg: the object\n" - "+ * @secid: where result will be saved\n" - "+ */\n" - "+static void smack_msg_msg_getsecid(struct msg_msg *msg, u32 *secid)\n" - "+{\n" - "+\tchar *smack = msg->security;\n" - "+\n" - "+\t*secid = smack_to_secid(smack);\n" - "+}\n" - "+\n" - "+static int smack_msg_msg_restore(struct msg_msg *msg, u32 secid)\n" - "+{\n" - "+\tchar *smack = smack_from_secid(secid);\n" - "+\n" - "+\tif (smack == NULL)\n" - "+\t\treturn -EINVAL;\n" - "+\tif (current_security() != smack) {\n" - "+\t\tif (!capable(CAP_MAC_ADMIN))\n" - "+\t\t\treturn -EPERM;\n" - "+\t\tmsg->security = smack;\n" - "+\t} else\n" - "+\t\tmsg->security = current_security();\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - "+/**\n" - " * smack_of_shm - the smack pointer for the shm\n" - " * @shp: the object\n" - " *\n" - "@@ -1727,6 +1754,21 @@ static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr,\n" - " \treturn smk_curacc(ssp, may);\n" - " }\n" - " \n" - "+static int smack_shm_restore(struct shmid_kernel *shp, u32 secid)\n" - "+{\n" - "+\tchar *smack = smack_from_secid(secid);\n" - "+\n" - "+\tif (smack == NULL)\n" - "+\t\treturn -EINVAL;\n" - "+\tif (current_security() != smack) {\n" - "+\t\tif (!capable(CAP_MAC_ADMIN))\n" - "+\t\t\treturn -EPERM;\n" - "+\t\tshp->shm_perm.security = smack;\n" - "+\t} else\n" - "+\t\tshp->shm_perm.security = current_security();\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - " /**\n" - " * smack_of_sem - the smack pointer for the sem\n" - " * @sma: the object\n" - "@@ -1842,6 +1884,21 @@ static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops,\n" - " \treturn smk_curacc(ssp, MAY_READWRITE);\n" - " }\n" - " \n" - "+static int smack_sem_restore(struct sem_array *sma, u32 secid)\n" - "+{\n" - "+\tchar *smack = smack_from_secid(secid);\n" - "+\n" - "+\tif (smack == NULL)\n" - "+\t\treturn -EINVAL;\n" - "+\tif (current_security() != smack) {\n" - "+\t\tif (!capable(CAP_MAC_ADMIN))\n" - "+\t\t\treturn -EPERM;\n" - "+\t\tsma->sem_perm.security = smack;\n" - "+\t} else\n" - "+\t\tsma->sem_perm.security = current_security();\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - " /**\n" - " * smack_msg_alloc_security - Set the security blob for msg\n" - " * @msq: the object\n" - "@@ -1967,6 +2024,21 @@ static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,\n" - " \treturn smk_curacc(msp, MAY_READWRITE);\n" - " }\n" - " \n" - "+static int smack_msg_queue_restore(struct msg_queue *msq, u32 secid)\n" - "+{\n" - "+\tchar *smack = smack_from_secid(secid);\n" - "+\n" - "+\tif (smack == NULL)\n" - "+\t\treturn -EINVAL;\n" - "+\tif (current_security() != smack) {\n" - "+\t\tif (!capable(CAP_MAC_ADMIN))\n" - "+\t\t\treturn -EPERM;\n" - "+\t\tmsq->q_perm.security = smack;\n" - "+\t} else\n" - "+\t\tmsq->q_perm.security = current_security();\n" - "+\treturn 0;\n" - "+}\n" - "+\n" - " /**\n" - " * smack_ipc_permission - Smack access for ipc_permission()\n" - " * @ipp: the object permissions\n" - "@@ -2903,6 +2975,8 @@ struct security_operations smack_ops = {\n" - " \n" - " \t.msg_msg_alloc_security = \tsmack_msg_msg_alloc_security,\n" - " \t.msg_msg_free_security = \tsmack_msg_msg_free_security,\n" - "+\t.msg_msg_getsecid = \t\tsmack_msg_msg_getsecid,\n" - "+\t.msg_msg_restore = \t\tsmack_msg_msg_restore,\n" - " \n" - " \t.msg_queue_alloc_security = \tsmack_msg_queue_alloc_security,\n" - " \t.msg_queue_free_security = \tsmack_msg_queue_free_security,\n" - "@@ -2910,18 +2984,21 @@ struct security_operations smack_ops = {\n" - " \t.msg_queue_msgctl = \t\tsmack_msg_queue_msgctl,\n" - " \t.msg_queue_msgsnd = \t\tsmack_msg_queue_msgsnd,\n" - " \t.msg_queue_msgrcv = \t\tsmack_msg_queue_msgrcv,\n" - "+\t.msg_queue_restore = \t\tsmack_msg_queue_restore,\n" - " \n" - " \t.shm_alloc_security = \t\tsmack_shm_alloc_security,\n" - " \t.shm_free_security = \t\tsmack_shm_free_security,\n" - " \t.shm_associate = \t\tsmack_shm_associate,\n" - " \t.shm_shmctl = \t\t\tsmack_shm_shmctl,\n" - " \t.shm_shmat = \t\t\tsmack_shm_shmat,\n" - "+\t.shm_restore = \t\t\tsmack_shm_restore,\n" - " \n" - " \t.sem_alloc_security = \t\tsmack_sem_alloc_security,\n" - " \t.sem_free_security = \t\tsmack_sem_free_security,\n" - " \t.sem_associate = \t\tsmack_sem_associate,\n" - " \t.sem_semctl = \t\t\tsmack_sem_semctl,\n" - " \t.sem_semop = \t\t\tsmack_sem_semop,\n" - "+\t.sem_restore = \t\t\tsmack_sem_restore,\n" - " \n" - " \t.netlink_send =\t\t\tcap_netlink_send,\n" - " \t.netlink_recv = \t\tcap_netlink_recv,\n" - "-- \n" - 1.6.1 + to checkpoint, then checkpoint an array of contexts? -e03d298136b992734d1f4403bebb022141ed8d76b9b5a85f018b34bf6268a5e1 +a1627af63705c5ee1bff9494a3c95a0714943380f7ad5d8e0f3a6d99053cc06e
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.