mirror of
https://github.com/flatcar/scripts.git
synced 2025-08-23 07:21:14 +02:00
Add overlayfs selinux fixes
Overlayfs currently has no good support for selinux. Backport some patches being worked on upstream in order to make things work in a more reasonable way.
This commit is contained in:
parent
d6e00b8bb6
commit
0f02032b14
@ -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}/12-efi-Make-EFI_SECURE_BOOT_SIG_ENFORCE-depend-on-EFI.patch \
|
||||||
${PATCH_DIR}/13-efi-Add-EFI_SECURE_BOOT-bit.patch \
|
${PATCH_DIR}/13-efi-Add-EFI_SECURE_BOOT-bit.patch \
|
||||||
${PATCH_DIR}/14-hibernate-Disable-in-a-signed-modules-environment.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"
|
${PATCH_DIR}/net-wireless-wl18xx-Add-missing-MODULE_FIRMWARE.patch"
|
||||||
|
@ -0,0 +1,140 @@
|
|||||||
|
From bf7f29c3ce247f0074b9cec78e948f779d19dab6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Howells <dhowells@redhat.com>
|
||||||
|
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 <dhowells@redhat.com>
|
||||||
|
---
|
||||||
|
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
|
||||||
|
|
@ -0,0 +1,47 @@
|
|||||||
|
From f7232b5105b54e8605810a4a22407625ef626cfd Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Howells <dhowells@redhat.com>
|
||||||
|
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 <dhowells@redhat.com>
|
||||||
|
---
|
||||||
|
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
|
||||||
|
|
@ -0,0 +1,55 @@
|
|||||||
|
From c86855ff554866751bbaf3f710081222448ae2cc Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Howells <dhowells@redhat.com>
|
||||||
|
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 <dhowells@redhat.com>
|
||||||
|
---
|
||||||
|
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
|
||||||
|
|
@ -0,0 +1,133 @@
|
|||||||
|
From 960b4a846a973eab6caf342af7b19e4e1cf7cdd3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Howells <dhowells@redhat.com>
|
||||||
|
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 <dhowells@redhat.com>
|
||||||
|
---
|
||||||
|
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
|
||||||
|
|
@ -0,0 +1,50 @@
|
|||||||
|
From 8801593b646aa444732e4c7431442d453d1b08cf Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Howells <dhowells@redhat.com>
|
||||||
|
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 <dhowells@redhat.com>
|
||||||
|
---
|
||||||
|
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
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user