diff --git a/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/coreos-sources-4.2.0-r1.ebuild b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/coreos-sources-4.2.0-r1.ebuild index eb649b2632..376b3300f0 100644 --- a/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/coreos-sources-4.2.0-r1.ebuild +++ b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/coreos-sources-4.2.0-r1.ebuild @@ -27,4 +27,9 @@ ${PATCH_DIR}/10-Add-option-to-automatically-enforce-module-signature.patch \ ${PATCH_DIR}/12-efi-Make-EFI_SECURE_BOOT_SIG_ENFORCE-depend-on-EFI.patch \ ${PATCH_DIR}/13-efi-Add-EFI_SECURE_BOOT-bit.patch \ ${PATCH_DIR}/14-hibernate-Disable-in-a-signed-modules-environment.patch \ +${PATCH_DIR}/overlayfs/0001-Security-Provide-copy-up-security-hooks-for-unioned-.patch \ +${PATCH_DIR}/overlayfs/0002-Overlayfs-Use-copy-up-security-hooks.patch \ +${PATCH_DIR}/overlayfs/0003-SELinux-Stub-in-copy-up-handling.patch \ +${PATCH_DIR}/overlayfs/0004-SELinux-Handle-opening-of-a-unioned-file.patch \ +${PATCH_DIR}/overlayfs/0005-SELinux-Check-against-union-label-for-file-operation.patch \ ${PATCH_DIR}/net-wireless-wl18xx-Add-missing-MODULE_FIRMWARE.patch" diff --git a/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/4.2/overlayfs/0001-Security-Provide-copy-up-security-hooks-for-unioned-.patch b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/4.2/overlayfs/0001-Security-Provide-copy-up-security-hooks-for-unioned-.patch new file mode 100644 index 0000000000..c9739de4f5 --- /dev/null +++ b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/4.2/overlayfs/0001-Security-Provide-copy-up-security-hooks-for-unioned-.patch @@ -0,0 +1,140 @@ +From bf7f29c3ce247f0074b9cec78e948f779d19dab6 Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Tue, 16 Jun 2015 14:14:31 +0100 +Subject: [PATCH 1/5] Security: Provide copy-up security hooks for unioned + files + +Provide two new security hooks for use with security files that are used when +a file is copied up between layers: + + (1) security_inode_copy_up(). This is called so that the security label on + the destination file can be set appropriately. + + (2) security_inode_copy_up_xattr(). This is called so that each xattr being + copied up can be vetted - including modification and discard. + +Signed-off-by: David Howells +--- + include/linux/lsm_hooks.h | 23 +++++++++++++++++++++++ + include/linux/security.h | 14 ++++++++++++++ + security/security.c | 17 +++++++++++++++++ + 3 files changed, 54 insertions(+) + +diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h +index 9429f05..1c38ceb 100644 +--- a/include/linux/lsm_hooks.h ++++ b/include/linux/lsm_hooks.h +@@ -401,6 +401,24 @@ + * @inode contains a pointer to the inode. + * @secid contains a pointer to the location where result will be saved. + * In case of failure, @secid will be set to zero. ++ * @inode_copy_up: ++ * Appropriately label the destination inode when a unioned file is copied ++ * up from a lower layer to the union/overlay layer. ++ * @src indicates the file that is being copied up. ++ * @dst indicates the file that has being created by the copy up. ++ * Returns 0 on success or a negative error code on error. ++ * @inode_copy_up_xattr: ++ * Filter/modify the xattrs being copied up when a unioned file is copied ++ * up from a lower layer to the union/overlay layer. ++ * @src indicates the file that is being copied up. ++ * @dst indicates the file that has being created by the copy up. ++ * @name indicates the name of the xattr. ++ * @value, *@size indicate the payload of the xattr. ++ * Returns 0 to accept the xattr, 1 to discard the xattr or a negative ++ * error code to abort the copy up. The xattr buffer must be at least ++ * XATTR_SIZE_MAX in capacity and the contents may be modified and *@size ++ * changed appropriately. Note that the caller is responsible for reading ++ * and writing the xattrs as this hook is merely a filter. + * + * Security hooks for file operations + * +@@ -1421,6 +1439,9 @@ union security_list_options { + int (*inode_listsecurity)(struct inode *inode, char *buffer, + size_t buffer_size); + void (*inode_getsecid)(const struct inode *inode, u32 *secid); ++ int (*inode_copy_up) (struct dentry *src, struct dentry *dst); ++ int (*inode_copy_up_xattr) (struct dentry *src, struct dentry *dst, ++ const char *name, void *value, size_t *size); + + int (*file_permission)(struct file *file, int mask); + int (*file_alloc_security)(struct file *file); +@@ -1689,6 +1710,8 @@ struct security_hook_heads { + struct list_head inode_setsecurity; + struct list_head inode_listsecurity; + struct list_head inode_getsecid; ++ struct list_head inode_copy_up; ++ struct list_head inode_copy_up_xattr; + struct list_head file_permission; + struct list_head file_alloc_security; + struct list_head file_free_security; +diff --git a/include/linux/security.h b/include/linux/security.h +index 79d85dd..10d3211 100644 +--- a/include/linux/security.h ++++ b/include/linux/security.h +@@ -274,6 +274,10 @@ int security_inode_getsecurity(const struct inode *inode, const char *name, void + int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags); + int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size); + void security_inode_getsecid(const struct inode *inode, u32 *secid); ++int security_inode_copy_up(struct dentry *src, struct dentry *dst); ++int security_inode_copy_up_xattr(struct dentry *src, struct dentry *dst, ++ const char *name, void *value, size_t *size); ++ + int security_file_permission(struct file *file, int mask); + int security_file_alloc(struct file *file); + void security_file_free(struct file *file); +@@ -739,6 +743,16 @@ static inline void security_inode_getsecid(const struct inode *inode, u32 *secid + *secid = 0; + } + ++static inline int security_inode_copy_up(struct dentry *src, struct dentry *dst) ++{ ++ return 0; ++} ++static inline int security_inode_copy_up_xattr(struct dentry *src, struct dentry *dst, ++ const char *name, const void *value, size_t *size) ++{ ++ return 0; ++} ++ + static inline int security_file_permission(struct file *file, int mask) + { + return 0; +diff --git a/security/security.c b/security/security.c +index 9942836..976e7114 100644 +--- a/security/security.c ++++ b/security/security.c +@@ -731,6 +731,19 @@ void security_inode_getsecid(const struct inode *inode, u32 *secid) + call_void_hook(inode_getsecid, inode, secid); + } + ++int security_inode_copy_up(struct dentry *src, struct dentry *dst) ++{ ++ return call_int_hook(inode_copy_up, 0, src, dst); ++} ++EXPORT_SYMBOL(security_inode_copy_up); ++ ++int security_inode_copy_up_xattr(struct dentry *src, struct dentry *dst, ++ const char *name, void *value, size_t *size) ++{ ++ return call_int_hook(inode_copy_up_xattr, 0, src, dst, name, value, size); ++} ++EXPORT_SYMBOL(security_inode_copy_up_xattr); ++ + int security_file_permission(struct file *file, int mask) + { + int ret; +@@ -1659,6 +1672,10 @@ struct security_hook_heads security_hook_heads = { + LIST_HEAD_INIT(security_hook_heads.inode_listsecurity), + .inode_getsecid = + LIST_HEAD_INIT(security_hook_heads.inode_getsecid), ++ .inode_copy_up = ++ LIST_HEAD_INIT(security_hook_heads.inode_copy_up), ++ .inode_copy_up_xattr = ++ LIST_HEAD_INIT(security_hook_heads.inode_copy_up_xattr), + .file_permission = + LIST_HEAD_INIT(security_hook_heads.file_permission), + .file_alloc_security = +-- +2.4.3 + diff --git a/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/4.2/overlayfs/0002-Overlayfs-Use-copy-up-security-hooks.patch b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/4.2/overlayfs/0002-Overlayfs-Use-copy-up-security-hooks.patch new file mode 100644 index 0000000000..92fb6eceba --- /dev/null +++ b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/4.2/overlayfs/0002-Overlayfs-Use-copy-up-security-hooks.patch @@ -0,0 +1,47 @@ +From f7232b5105b54e8605810a4a22407625ef626cfd Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Tue, 16 Jun 2015 14:14:31 +0100 +Subject: [PATCH 2/5] Overlayfs: Use copy-up security hooks + +Use the copy-up security hooks previously provided to allow an LSM to adjust +the security on a newly created copy and to filter the xattrs copied to that +file copy. + +Signed-off-by: David Howells +--- + fs/overlayfs/copy_up.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c +index 84d693d..8f66b39 100644 +--- a/fs/overlayfs/copy_up.c ++++ b/fs/overlayfs/copy_up.c +@@ -58,6 +58,14 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new) + error = size; + goto out_free_value; + } ++ error = security_inode_copy_up_xattr(old, new, ++ name, value, &size); ++ if (error < 0) ++ goto out_free_value; ++ if (error == 1) { ++ error = 0; ++ continue; /* Discard */ ++ } + error = vfs_setxattr(new, name, value, size, 0); + if (error) + goto out_free_value; +@@ -223,6 +231,10 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, + if (err) + goto out2; + ++ err = security_inode_copy_up(lowerpath->dentry, newdentry); ++ if (err < 0) ++ goto out_cleanup; ++ + if (S_ISREG(stat->mode)) { + struct path upperpath; + ovl_path_upper(dentry, &upperpath); +-- +2.4.3 + diff --git a/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/4.2/overlayfs/0003-SELinux-Stub-in-copy-up-handling.patch b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/4.2/overlayfs/0003-SELinux-Stub-in-copy-up-handling.patch new file mode 100644 index 0000000000..0d61ef5dea --- /dev/null +++ b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/4.2/overlayfs/0003-SELinux-Stub-in-copy-up-handling.patch @@ -0,0 +1,55 @@ +From c86855ff554866751bbaf3f710081222448ae2cc Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Tue, 16 Jun 2015 14:14:32 +0100 +Subject: [PATCH 3/5] SELinux: Stub in copy-up handling + +Provide stubs for union/overlay copy-up handling. The xattr copy up stub +discards lower SELinux xattrs rather than letting them be copied up so that +the security label on the copy doesn't get corrupted. + +Signed-off-by: David Howells +--- + security/selinux/hooks.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c +index 564079c..5b5864f 100644 +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -3184,6 +3184,24 @@ static void selinux_inode_getsecid(const struct inode *inode, u32 *secid) + *secid = isec->sid; + } + ++static int selinux_inode_copy_up(struct dentry *src, struct dentry *dst) ++{ ++ return 0; ++} ++ ++static int selinux_inode_copy_up_xattr(struct dentry *src, struct dentry *dst, ++ const char *name, void *value, ++ size_t *size) ++{ ++ /* The copy_up hook above sets the initial context on an inode, but we ++ * don't then want to overwrite it by blindly copying all the lower ++ * xattrs up. Instead, we have to filter out SELinux-related xattrs. ++ */ ++ if (strcmp(name, XATTR_NAME_SELINUX) == 0) ++ return 1; /* Discard */ ++ return 0; ++} ++ + /* file security operations */ + + static int selinux_revalidate_file_permission(struct file *file, int mask) +@@ -5872,6 +5890,8 @@ static struct security_hook_list selinux_hooks[] = { + LSM_HOOK_INIT(inode_setsecurity, selinux_inode_setsecurity), + LSM_HOOK_INIT(inode_listsecurity, selinux_inode_listsecurity), + LSM_HOOK_INIT(inode_getsecid, selinux_inode_getsecid), ++ LSM_HOOK_INIT(inode_copy_up, selinux_inode_copy_up), ++ LSM_HOOK_INIT(inode_copy_up_xattr, selinux_inode_copy_up_xattr), + + LSM_HOOK_INIT(file_permission, selinux_file_permission), + LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security), +-- +2.4.3 + diff --git a/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/4.2/overlayfs/0004-SELinux-Handle-opening-of-a-unioned-file.patch b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/4.2/overlayfs/0004-SELinux-Handle-opening-of-a-unioned-file.patch new file mode 100644 index 0000000000..ca828467d9 --- /dev/null +++ b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/4.2/overlayfs/0004-SELinux-Handle-opening-of-a-unioned-file.patch @@ -0,0 +1,133 @@ +From 960b4a846a973eab6caf342af7b19e4e1cf7cdd3 Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Tue, 16 Jun 2015 14:14:32 +0100 +Subject: [PATCH 4/5] SELinux: Handle opening of a unioned file + +Handle the opening of a unioned file by trying to derive the label that would +be attached to the union-layer inode if it doesn't exist. + +If the union-layer inode does exist (as it necessarily does in overlayfs, but +not in unionmount), we assume that it has the right label and use that. +Otherwise we try to get it from the superblock. + +If the superblock has a globally-applied label, we use that, otherwise we try +to transition to an appropriate label. This union label is then stored in the +file_security_struct. + +We then perform an additional check to make sure that the calling task is +granted permission by the union-layer inode label to open the file in addition +to a check to make sure that the task is granted permission to open the lower +file with the lower inode label. + +Signed-off-by: David Howells +--- + security/selinux/hooks.c | 69 +++++++++++++++++++++++++++++++++++++++ + security/selinux/include/objsec.h | 1 + + 2 files changed, 70 insertions(+) + +diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c +index 5b5864f..1b5a338 100644 +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -3474,10 +3474,72 @@ static int selinux_file_receive(struct file *file) + return file_has_perm(cred, file, file_to_av(file)); + } + ++/* ++ * We have a file opened on a unioned file system that falls through to a file ++ * on a lower layer. If there is a union inode, we try to get the label from ++ * that, otherwise we need to get it from the superblock. ++ * ++ * file->f_path points to the union layer and file->f_inode points to the lower ++ * layer. ++ */ ++static int selinux_file_open_union(struct file *file, ++ struct file_security_struct *fsec, ++ const struct cred *cred) ++{ ++ const struct superblock_security_struct *sbsec; ++ const struct inode_security_struct *isec, *dsec, *fisec; ++ const struct task_security_struct *tsec = current_security(); ++ struct common_audit_data ad; ++ struct dentry *union_dentry = file->f_path.dentry; ++ const struct inode *union_inode = d_inode(union_dentry); ++ const struct inode *lower_inode = file_inode(file); ++ struct dentry *dir; ++ int rc; ++ ++ sbsec = union_dentry->d_sb->s_security; ++ ++ if (union_inode) { ++ isec = union_inode->i_security; ++ fsec->union_isid = isec->sid; ++ } else if ((sbsec->flags & SE_SBINITIALIZED) && ++ (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) { ++ fsec->union_isid = sbsec->mntpoint_sid; ++ } else { ++ dir = dget_parent(union_dentry); ++ dsec = d_inode(dir)->i_security; ++ ++ rc = security_transition_sid( ++ tsec->sid, dsec->sid, ++ inode_mode_to_security_class(lower_inode->i_mode), ++ &union_dentry->d_name, ++ &fsec->union_isid); ++ dput(dir); ++ if (rc) { ++ pr_warn("%s: security_transition_sid failed, rc=%d (name=%pD)\n", ++ __func__, -rc, file); ++ return rc; ++ } ++ } ++ ++ /* We need to check that the union file is allowed to be opened as well ++ * as checking that the lower file is allowed to be opened. ++ */ ++ if (unlikely(IS_PRIVATE(lower_inode))) ++ return 0; ++ ++ ad.type = LSM_AUDIT_DATA_PATH; ++ ad.u.path = file->f_path; ++ ++ fisec = lower_inode->i_security; ++ return avc_has_perm(cred_sid(cred), fsec->union_isid, fisec->sclass, ++ open_file_to_av(file), &ad); ++} ++ + static int selinux_file_open(struct file *file, const struct cred *cred) + { + struct file_security_struct *fsec; + struct inode_security_struct *isec; ++ int rc; + + fsec = file->f_security; + isec = file_inode(file)->i_security; +@@ -3498,6 +3560,13 @@ static int selinux_file_open(struct file *file, const struct cred *cred) + * new inode label or new policy. + * This check is not redundant - do not remove. + */ ++ ++ if (d_inode(file->f_path.dentry) != file->f_inode) { ++ rc = selinux_file_open_union(file, fsec, cred); ++ if (rc < 0) ++ return rc; ++ } ++ + return file_path_has_perm(cred, file, open_file_to_av(file)); + } + +diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h +index 81fa718..f088c08 100644 +--- a/security/selinux/include/objsec.h ++++ b/security/selinux/include/objsec.h +@@ -54,6 +54,7 @@ struct file_security_struct { + u32 sid; /* SID of open file description */ + u32 fown_sid; /* SID of file owner (for SIGIO) */ + u32 isid; /* SID of inode at the time of file open */ ++ u32 union_isid; /* SID of would-be inodes in union top (or 0) */ + u32 pseqno; /* Policy seqno at the time of file open */ + }; + +-- +2.4.3 + diff --git a/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/4.2/overlayfs/0005-SELinux-Check-against-union-label-for-file-operation.patch b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/4.2/overlayfs/0005-SELinux-Check-against-union-label-for-file-operation.patch new file mode 100644 index 0000000000..9755d1db20 --- /dev/null +++ b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-sources/files/4.2/overlayfs/0005-SELinux-Check-against-union-label-for-file-operation.patch @@ -0,0 +1,50 @@ +From 8801593b646aa444732e4c7431442d453d1b08cf Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Tue, 16 Jun 2015 14:14:32 +0100 +Subject: [PATCH 5/5] SELinux: Check against union label for file operations + +File operations (eg. read, write) issued against a file that is attached to +the lower layer of a union file needs to be checked against the union-layer +label not the lower layer label. + +The union label is stored in the file_security_struct rather than being +retrieved from one of the inodes. + +Signed-off-by: David Howells +--- + security/selinux/hooks.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c +index 1b5a338..b33cbbb 100644 +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -1671,6 +1671,7 @@ static int file_has_perm(const struct cred *cred, + struct file *file, + u32 av) + { ++ struct inode_security_struct *isec; + struct file_security_struct *fsec = file->f_security; + struct inode *inode = file_inode(file); + struct common_audit_data ad; +@@ -1691,8 +1692,15 @@ static int file_has_perm(const struct cred *cred, + + /* av is zero if only checking access to the descriptor. */ + rc = 0; +- if (av) +- rc = inode_has_perm(cred, inode, av, &ad); ++ if (av && likely(!IS_PRIVATE(inode))) { ++ if (fsec->union_isid) { ++ isec = inode->i_security; ++ rc = avc_has_perm(sid, fsec->union_isid, isec->sclass, ++ av, &ad); ++ } ++ if (!rc) ++ rc = inode_has_perm(cred, inode, av, &ad); ++ } + + out: + return rc; +-- +2.4.3 +