2024-02-23 17:27:21

by Stefan Berger

[permalink] [raw]
Subject: [PATCH v3 00/10] evm: Support signatures on stacked filesystem

EVM signature verification on stacked filesystem has recently been
completely disabled by declaring some filesystems as unsupported
(only overlayfs). This series now enables copy-up of "portable
and immutable" signatures on those filesystems and enables the
enforcement of "portable and immultable" as well as the "original"
signatures on previously unsupported filesystem when evm is enabled
with EVM_INIT_X509. HMAC verification and generation remains disabled.

"Portable and immutable" signatures can be copied up since they are
not created over file-specific metadata, such as UUID or generation.
Instead, they are only covering file metadata such as mode bits, uid, and
gid, that will all be preserved during a copy-up of the file metadata.

This series is now based on the 'next' branch of Paul Moore's LSM tree and
requires the following two commits from the vfs.misc branch of the vfs git
repo at https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git

commit 2109cc619e73 ("fs: remove the inode argument to ->d_real() method")
commit c6c14f926fbe ("fs: make file_dentry() a simple accessor")

Regards,
Stefan

v3:
- Rebased series on 'next' branch of Paul Moore's LSM tree
- Reworing of commit descriptions
- Reworked patches 5-7

v2:
- Added patch to rename backing_inode to real_inode (1/9)
- Added patches renaming flag and function due to RSA enablement (7,8/9)
- Added patch to record i_version of real_inode for change detection
(9/9)
- Use Amir's function to get inode holding metadata now (4,5/9)


Stefan Berger (10):
ima: Rename backing_inode to real_inode
security: allow finer granularity in permitting copy-up of security
xattrs
evm: Implement per signature type decision in
security_inode_copy_up_xattr
evm: Use the metadata inode to calculate metadata hash
ima: Move file-change detection variables into new structure
evm: Store and detect metadata inode attributes changes
ima: re-evaluate file integrity on file metadata change
evm: Enforce signatures on unsupported filesystem for EVM_INIT_X509
fs: Rename SB_I_EVM_UNSUPPORTED to SB_I_EVM_HMAC_UNSUPPORTED
evm: Rename is_unsupported_fs to is_unsupported_hmac_fs

fs/overlayfs/copy_up.c | 2 +-
fs/overlayfs/super.c | 2 +-
include/linux/evm.h | 8 +++
include/linux/fs.h | 2 +-
include/linux/integrity.h | 34 +++++++++++
include/linux/lsm_hook_defs.h | 3 +-
include/linux/security.h | 4 +-
security/integrity/evm/evm.h | 6 +-
security/integrity/evm/evm_crypto.c | 25 +++++---
security/integrity/evm/evm_main.c | 92 +++++++++++++++++++++++------
security/integrity/ima/ima.h | 4 +-
security/integrity/ima/ima_api.c | 10 ++--
security/integrity/ima/ima_iint.c | 2 +-
security/integrity/ima/ima_main.c | 31 +++++++---
security/security.c | 5 +-
security/selinux/hooks.c | 2 +-
security/smack/smack_lsm.c | 2 +-
17 files changed, 178 insertions(+), 56 deletions(-)


base-commit: f89d47833d28f101fce65c7d08c00a4d6f28c1b1
prerequisite-patch-id: c6c14f926fbe37330af6271d26f98e70d1a07372
prerequisite-patch-id: 2109cc619e733c8709250b62d7f1d43461589f57
--
2.43.0



2024-02-23 17:27:27

by Stefan Berger

[permalink] [raw]
Subject: [PATCH v3 07/10] ima: re-evaluate file integrity on file metadata change

Force a file's integrity to be re-evaluated on file metadata change by
resetting both the IMA and EVM status flags.

Co-developed-by: Mimi Zohar <[email protected]>
Signed-off-by: Stefan Berger <[email protected]>
---
security/integrity/ima/ima_main.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index c15378dd9456..36c92d6c01f6 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -26,6 +26,7 @@
#include <linux/ima.h>
#include <linux/fs.h>
#include <linux/iversion.h>
+#include <linux/evm.h>

#include "ima.h"

@@ -211,6 +212,7 @@ static int process_measurement(struct file *file, const struct cred *cred,
struct inode *real_inode, *inode = file_inode(file);
struct ima_iint_cache *iint = NULL;
struct ima_template_desc *template_desc = NULL;
+ struct inode *metadata_inode;
char *pathbuf = NULL;
char filename[NAME_MAX];
const char *pathname = NULL;
@@ -286,7 +288,8 @@ static int process_measurement(struct file *file, const struct cred *cred,
}

/*
- * On stacked filesystems, detect and re-evaluate file data changes.
+ * On stacked filesystems, detect and re-evaluate file data and
+ * metadata changes.
*/
real_inode = d_real_inode(file_dentry(file));
if (real_inode != inode &&
@@ -297,6 +300,15 @@ static int process_measurement(struct file *file, const struct cred *cred,
iint->flags &= ~IMA_DONE_MASK;
iint->measured_pcrs = 0;
}
+
+ /*
+ * Reset the EVM status when metadata changed.
+ */
+ metadata_inode = d_inode(d_real(file_dentry(file),
+ D_REAL_METADATA));
+ if (evm_metadata_changed(inode, metadata_inode))
+ iint->flags &= ~(IMA_APPRAISED |
+ IMA_APPRAISED_SUBMASK);
}

/* Determine if already appraised/measured based on bitmask
--
2.43.0


2024-02-23 17:27:34

by Stefan Berger

[permalink] [raw]
Subject: [PATCH v3 04/10] evm: Use the metadata inode to calculate metadata hash

Changes to file attributes (mode bits, uid, gid) on the lower layer are
not taken into account when d_backing_inode() is used when a file is
accessed on the overlay layer and this file has not yet been copied up.
This is because d_backing_inode() does not return the real inode of the
lower layer but instead returns the backing inode which in this case
holds wrong file attributes. Further, when CONFIG_OVERLAY_FS_METACOPY is
enabled and a copy-up is triggered due to file metadata changes, then
the metadata are held by the backing inode while the data are still held
by the real inode. Therefore, use d_inode(d_real(dentry, D_REAL_METADATA))
to get to the file's metadata inode and use it to calculate the metadata
hash with.

Co-developed-by: Mimi Zohar <[email protected]>
Signed-off-by: Stefan Berger <[email protected]>
Acked-by: Amir Goldstein <[email protected]>
---
security/integrity/evm/evm_crypto.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index 7552d49d0725..35416f55391c 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -223,7 +223,7 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
size_t req_xattr_value_len,
uint8_t type, struct evm_digest *data)
{
- struct inode *inode = d_backing_inode(dentry);
+ struct inode *inode = d_inode(d_real(dentry, D_REAL_METADATA));
struct xattr_list *xattr;
struct shash_desc *desc;
size_t xattr_size = 0;
--
2.43.0


2024-02-23 17:27:41

by Stefan Berger

[permalink] [raw]
Subject: [PATCH v3 01/10] ima: Rename backing_inode to real_inode

Rename the backing_inode variable to real_inode since it gets its value
from real_inode().

Suggested-by: Amir Goldstein <[email protected]>
Co-developed-by: Mimi Zohar <[email protected]>
Signed-off-by: Stefan Berger <[email protected]>
Acked-by: Amir Goldstein <[email protected]>
---
security/integrity/ima/ima_main.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index c84e8c55333d..a744770d8c43 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -208,7 +208,7 @@ static int process_measurement(struct file *file, const struct cred *cred,
u32 secid, char *buf, loff_t size, int mask,
enum ima_hooks func)
{
- struct inode *backing_inode, *inode = file_inode(file);
+ struct inode *real_inode, *inode = file_inode(file);
struct ima_iint_cache *iint = NULL;
struct ima_template_desc *template_desc = NULL;
char *pathbuf = NULL;
@@ -285,14 +285,16 @@ static int process_measurement(struct file *file, const struct cred *cred,
iint->measured_pcrs = 0;
}

- /* Detect and re-evaluate changes made to the backing file. */
- backing_inode = d_real_inode(file_dentry(file));
- if (backing_inode != inode &&
+ /*
+ * On stacked filesystems, detect and re-evaluate file data changes.
+ */
+ real_inode = d_real_inode(file_dentry(file));
+ if (real_inode != inode &&
(action & IMA_DO_MASK) && (iint->flags & IMA_DONE_MASK)) {
- if (!IS_I_VERSION(backing_inode) ||
- backing_inode->i_sb->s_dev != iint->real_dev ||
- backing_inode->i_ino != iint->real_ino ||
- !inode_eq_iversion(backing_inode, iint->version)) {
+ if (!IS_I_VERSION(real_inode) ||
+ real_inode->i_sb->s_dev != iint->real_dev ||
+ real_inode->i_ino != iint->real_ino ||
+ !inode_eq_iversion(real_inode, iint->version)) {
iint->flags &= ~IMA_DONE_MASK;
iint->measured_pcrs = 0;
}
--
2.43.0


2024-02-23 17:28:12

by Stefan Berger

[permalink] [raw]
Subject: [PATCH v3 05/10] ima: Move file-change detection variables into new structure

Move all the variables used for file change detection into a structure
that can be used by IMA and EVM. Implement an inline function for storing
the identification of an inode and one for detecting changes to an inode
based on this new structure.

Co-developed-by: Mimi Zohar <[email protected]>
Signed-off-by: Stefan Berger <[email protected]>
---
include/linux/integrity.h | 34 +++++++++++++++++++++++++++++++
security/integrity/ima/ima.h | 4 +---
security/integrity/ima/ima_api.c | 10 ++++-----
security/integrity/ima/ima_iint.c | 2 +-
security/integrity/ima/ima_main.c | 7 +++----
5 files changed, 44 insertions(+), 13 deletions(-)

diff --git a/include/linux/integrity.h b/include/linux/integrity.h
index 459b79683783..f5842372359b 100644
--- a/include/linux/integrity.h
+++ b/include/linux/integrity.h
@@ -8,6 +8,7 @@
#define _LINUX_INTEGRITY_H

#include <linux/fs.h>
+#include <linux/iversion.h>

enum integrity_status {
INTEGRITY_PASS = 0,
@@ -28,4 +29,37 @@ static inline void integrity_load_keys(void)
}
#endif /* CONFIG_INTEGRITY */

+/* An inode's attributes for detection of changes */
+struct integrity_inode_attributes {
+ u64 version; /* track inode changes */
+ unsigned long ino;
+ dev_t dev;
+};
+
+/*
+ * On stacked filesystems the i_version alone is not enough to detect file data
+ * or metadata change. Additional metadata is required.
+ */
+static inline void
+integrity_inode_attrs_store(struct integrity_inode_attributes *attrs,
+ u64 i_version, const struct inode *inode)
+{
+ attrs->version = i_version;
+ attrs->dev = inode->i_sb->s_dev;
+ attrs->ino = inode->i_ino;
+}
+
+/*
+ * On stacked filesystems detect whether the inode or its content has changed.
+ */
+static inline bool
+integrity_inode_attrs_changed(const struct integrity_inode_attributes *attrs,
+ const struct inode *inode)
+{
+ return (inode->i_sb->s_dev != attrs->dev ||
+ inode->i_ino != attrs->ino ||
+ !inode_eq_iversion(inode, attrs->version));
+}
+
+
#endif /* _LINUX_INTEGRITY_H */
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 11d7c0332207..9151b5369cdc 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -175,12 +175,10 @@ struct ima_kexec_hdr {
/* IMA integrity metadata associated with an inode */
struct ima_iint_cache {
struct mutex mutex; /* protects: version, flags, digest */
- u64 version; /* track inode changes */
+ struct integrity_inode_attributes real_inode;
unsigned long flags;
unsigned long measured_pcrs;
unsigned long atomic_flags;
- unsigned long real_ino;
- dev_t real_dev;
enum integrity_status ima_file_status:4;
enum integrity_status ima_mmap_status:4;
enum integrity_status ima_bprm_status:4;
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index b37d043d5748..4b2c3448dfda 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -303,11 +303,11 @@ int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file,

iint->ima_hash = tmpbuf;
memcpy(iint->ima_hash, &hash, length);
- iint->version = i_version;
- if (real_inode != inode) {
- iint->real_ino = real_inode->i_ino;
- iint->real_dev = real_inode->i_sb->s_dev;
- }
+ if (real_inode == inode)
+ iint->real_inode.version = i_version;
+ else
+ integrity_inode_attrs_store(&iint->real_inode, i_version,
+ real_inode);

/* Possibly temporary failure due to type of read (eg. O_DIRECT) */
if (!result)
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c
index e7c9c216c1c6..e23412a2c56b 100644
--- a/security/integrity/ima/ima_iint.c
+++ b/security/integrity/ima/ima_iint.c
@@ -59,7 +59,7 @@ static void ima_iint_init_always(struct ima_iint_cache *iint,
struct inode *inode)
{
iint->ima_hash = NULL;
- iint->version = 0;
+ iint->real_inode.version = 0;
iint->flags = 0UL;
iint->atomic_flags = 0UL;
iint->ima_file_status = INTEGRITY_UNKNOWN;
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index a744770d8c43..c15378dd9456 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -173,7 +173,7 @@ static void ima_check_last_writer(struct ima_iint_cache *iint,
STATX_CHANGE_COOKIE,
AT_STATX_SYNC_AS_STAT) ||
!(stat.result_mask & STATX_CHANGE_COOKIE) ||
- stat.change_cookie != iint->version) {
+ stat.change_cookie != iint->real_inode.version) {
iint->flags &= ~(IMA_DONE_MASK | IMA_NEW_FILE);
iint->measured_pcrs = 0;
if (update)
@@ -292,9 +292,8 @@ static int process_measurement(struct file *file, const struct cred *cred,
if (real_inode != inode &&
(action & IMA_DO_MASK) && (iint->flags & IMA_DONE_MASK)) {
if (!IS_I_VERSION(real_inode) ||
- real_inode->i_sb->s_dev != iint->real_dev ||
- real_inode->i_ino != iint->real_ino ||
- !inode_eq_iversion(real_inode, iint->version)) {
+ integrity_inode_attrs_changed(&iint->real_inode,
+ real_inode)) {
iint->flags &= ~IMA_DONE_MASK;
iint->measured_pcrs = 0;
}
--
2.43.0


2024-02-23 17:28:34

by Stefan Berger

[permalink] [raw]
Subject: [PATCH v3 08/10] evm: Enforce signatures on unsupported filesystem for EVM_INIT_X509

Unsupported filesystems currently do not enforce any signatures. Add
support for signature enforcement of the "original" and "portable &
immutable" signatures when EVM_INIT_X509 is enabled.

The "original" signature type contains filesystem specific metadata.
Thus it cannot be copied up and verified. However with EVM_INIT_X509
and EVM_ALLOW_METADATA_WRITES enabled, the "original" file signature
may be written.

When EVM_ALLOW_METADATA_WRITES is not set or once it is removed from
/sys/kernel/security/evm by setting EVM_INIT_HMAC for example, it is not
possible to write or remove xattrs on the overlay filesystem.

This change still prevents EVM from writing HMAC signatures on
unsupported filesystem when EVM_INIT_HMAC is enabled.

Co-developed-by: Mimi Zohar <[email protected]>
Signed-off-by: Stefan Berger <[email protected]>
---
security/integrity/evm/evm_main.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index c1ca0894cd8a..cfb4f9809369 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -192,7 +192,11 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
iint->evm_status == INTEGRITY_PASS_IMMUTABLE))
return iint->evm_status;

- if (is_unsupported_fs(dentry))
+ /*
+ * On unsupported filesystems without EVM_INIT_X509 enabled, skip
+ * signature verification.
+ */
+ if (!(evm_initialized & EVM_INIT_X509) && is_unsupported_fs(dentry))
return INTEGRITY_UNKNOWN;

/* if status is not PASS, try to check again - against -ENOMEM */
@@ -261,7 +265,8 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
evm_status = INTEGRITY_PASS_IMMUTABLE;
} else if (!IS_RDONLY(inode) &&
!(inode->i_sb->s_readonly_remount) &&
- !IS_IMMUTABLE(inode)) {
+ !IS_IMMUTABLE(inode) &&
+ !is_unsupported_fs(dentry)) {
evm_update_evmxattr(dentry, xattr_name,
xattr_value,
xattr_value_len);
@@ -419,9 +424,6 @@ enum integrity_status evm_verifyxattr(struct dentry *dentry,
if (!evm_key_loaded() || !evm_protected_xattr(xattr_name))
return INTEGRITY_UNKNOWN;

- if (is_unsupported_fs(dentry))
- return INTEGRITY_UNKNOWN;
-
return evm_verify_hmac(dentry, xattr_name, xattr_value,
xattr_value_len);
}
--
2.43.0


2024-02-23 17:28:45

by Stefan Berger

[permalink] [raw]
Subject: [PATCH v3 02/10] security: allow finer granularity in permitting copy-up of security xattrs

Copying up xattrs is solely based on the security xattr name. For finer
granularity add a dentry parameter to the security_inode_copy_up_xattr
hook definition, allowing decisions to be based on the xattr content as
well.

Co-developed-by: Mimi Zohar <[email protected]>
Signed-off-by: Stefan Berger <[email protected]>
Acked-by: Amir Goldstein <[email protected]>
---
fs/overlayfs/copy_up.c | 2 +-
include/linux/lsm_hook_defs.h | 3 ++-
include/linux/security.h | 4 ++--
security/integrity/evm/evm_main.c | 2 +-
security/security.c | 5 +++--
security/selinux/hooks.c | 2 +-
security/smack/smack_lsm.c | 2 +-
7 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index b8e25ca51016..bd9ddcefb7a7 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -114,7 +114,7 @@ int ovl_copy_xattr(struct super_block *sb, const struct path *oldpath, struct de
if (ovl_is_private_xattr(sb, name))
continue;

- error = security_inode_copy_up_xattr(name);
+ error = security_inode_copy_up_xattr(old, name);
if (error < 0 && error != -EOPNOTSUPP)
break;
if (error == 1) {
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 7e4683035d34..c538d39dd9a9 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -176,7 +176,8 @@ LSM_HOOK(int, 0, inode_listsecurity, struct inode *inode, char *buffer,
size_t buffer_size)
LSM_HOOK(void, LSM_RET_VOID, inode_getsecid, struct inode *inode, u32 *secid)
LSM_HOOK(int, 0, inode_copy_up, struct dentry *src, struct cred **new)
-LSM_HOOK(int, -EOPNOTSUPP, inode_copy_up_xattr, const char *name)
+LSM_HOOK(int, -EOPNOTSUPP, inode_copy_up_xattr, struct dentry *src,
+ const char *name)
LSM_HOOK(int, 0, kernfs_init_security, struct kernfs_node *kn_dir,
struct kernfs_node *kn)
LSM_HOOK(int, 0, file_permission, struct file *file, int mask)
diff --git a/include/linux/security.h b/include/linux/security.h
index 8436f9abf43d..2553a4f4b726 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -397,7 +397,7 @@ int security_inode_setsecurity(struct inode *inode, const char *name, const void
int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size);
void security_inode_getsecid(struct inode *inode, u32 *secid);
int security_inode_copy_up(struct dentry *src, struct cred **new);
-int security_inode_copy_up_xattr(const char *name);
+int security_inode_copy_up_xattr(struct dentry *src, const char *name);
int security_kernfs_init_security(struct kernfs_node *kn_dir,
struct kernfs_node *kn);
int security_file_permission(struct file *file, int mask);
@@ -1015,7 +1015,7 @@ static inline int security_kernfs_init_security(struct kernfs_node *kn_dir,
return 0;
}

-static inline int security_inode_copy_up_xattr(const char *name)
+static inline int security_inode_copy_up_xattr(struct dentry *src, const char *name)
{
return -EOPNOTSUPP;
}
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 81dbade5b9b3..b0a862bfd74a 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -946,7 +946,7 @@ static void evm_inode_post_setattr(struct mnt_idmap *idmap,
evm_update_evmxattr(dentry, NULL, NULL, 0);
}

-static int evm_inode_copy_up_xattr(const char *name)
+static int evm_inode_copy_up_xattr(struct dentry *src, const char *name)
{
if (strcmp(name, XATTR_NAME_EVM) == 0)
return 1; /* Discard */
diff --git a/security/security.c b/security/security.c
index b95772333d05..8d8b89e6b5d9 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2622,6 +2622,7 @@ EXPORT_SYMBOL(security_inode_copy_up);

/**
* security_inode_copy_up_xattr() - Filter xattrs in an overlayfs copy-up op
+ * @src: union dentry of copy-up file
* @name: xattr name
*
* Filter the xattrs being copied up when a unioned file is copied up from a
@@ -2632,7 +2633,7 @@ EXPORT_SYMBOL(security_inode_copy_up);
* if the security module does not know about attribute, or a negative
* error code to abort the copy up.
*/
-int security_inode_copy_up_xattr(const char *name)
+int security_inode_copy_up_xattr(struct dentry *src, const char *name)
{
int rc;

@@ -2641,7 +2642,7 @@ int security_inode_copy_up_xattr(const char *name)
* xattr), -EOPNOTSUPP if it does not know anything about the xattr or
* any other error code in case of an error.
*/
- rc = call_int_hook(inode_copy_up_xattr, name);
+ rc = call_int_hook(inode_copy_up_xattr, src, name);
if (rc != LSM_RET_DEFAULT(inode_copy_up_xattr))
return rc;

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index cedb4cbf072e..1d2395d8bba7 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3531,7 +3531,7 @@ static int selinux_inode_copy_up(struct dentry *src, struct cred **new)
return 0;
}

-static int selinux_inode_copy_up_xattr(const char *name)
+static int selinux_inode_copy_up_xattr(struct dentry *dentry, const char *name)
{
/* 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
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 1b6abfdf7173..972d50e3f266 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4875,7 +4875,7 @@ static int smack_inode_copy_up(struct dentry *dentry, struct cred **new)
return 0;
}

-static int smack_inode_copy_up_xattr(const char *name)
+static int smack_inode_copy_up_xattr(struct dentry *src, const char *name)
{
/*
* Return 1 if this is the smack access Smack attribute.
--
2.43.0


2024-02-23 17:29:12

by Stefan Berger

[permalink] [raw]
Subject: [PATCH v3 03/10] evm: Implement per signature type decision in security_inode_copy_up_xattr

To support "portable and immutable signatures" on otherwise unsupported
filesystems, determine the EVM signature type by the content of a file's
xattr. If the file has the appropriate signature type then allow it to be
copied up. All other signature types are discarded as before.

"Portable and immutable" EVM signatures can be copied up by stacked file-
system since the metadata their signature covers does not include file-
system-specific data such as a file's inode number, generation, and UUID.

Co-developed-by: Mimi Zohar <[email protected]>
Signed-off-by: Stefan Berger <[email protected]>
---
security/integrity/evm/evm_main.c | 31 ++++++++++++++++++++++++++++---
1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index b0a862bfd74a..c658d2f1494b 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -948,9 +948,34 @@ static void evm_inode_post_setattr(struct mnt_idmap *idmap,

static int evm_inode_copy_up_xattr(struct dentry *src, const char *name)
{
- if (strcmp(name, XATTR_NAME_EVM) == 0)
- return 1; /* Discard */
- return -EOPNOTSUPP;
+ struct evm_ima_xattr_data *xattr_data = NULL;
+ int rc;
+
+ if (strcmp(name, XATTR_NAME_EVM) != 0)
+ return -EOPNOTSUPP;
+
+ /* first need to know the sig type */
+ rc = vfs_getxattr_alloc(&nop_mnt_idmap, src, XATTR_NAME_EVM,
+ (char **)&xattr_data, 0, GFP_NOFS);
+ if (rc <= 0)
+ return -EPERM;
+
+ if (rc < offsetof(struct evm_ima_xattr_data, type) +
+ sizeof(xattr_data->type))
+ return -EPERM;
+
+ switch (xattr_data->type) {
+ case EVM_XATTR_PORTABLE_DIGSIG:
+ rc = 0; /* allow copy-up */
+ break;
+ case EVM_XATTR_HMAC:
+ case EVM_IMA_XATTR_DIGSIG:
+ default:
+ rc = 1; /* discard */
+ }
+
+ kfree(xattr_data);
+ return rc;
}

/*
--
2.43.0


2024-02-23 17:29:48

by Stefan Berger

[permalink] [raw]
Subject: [PATCH v3 09/10] fs: Rename SB_I_EVM_UNSUPPORTED to SB_I_EVM_HMAC_UNSUPPORTED

Now that EVM supports RSA signatures for previously completely
unsupported filesystems rename the flag SB_I_EVM_UNSUPPORTED to
SB_I_EVM_HMAC_UNSUPPORTED to reflect that only HMAC is not supported.

Suggested-by: Amir Goldstein <[email protected]>
Suggested-by: Mimi Zohar <[email protected]>
Signed-off-by: Stefan Berger <[email protected]>
Acked-by: Amir Goldstein <[email protected]>
---
fs/overlayfs/super.c | 2 +-
include/linux/fs.h | 2 +-
security/integrity/evm/evm_main.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 36d4b8b1f784..e05be454ec7a 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -1460,7 +1460,7 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
* lead to unexpected results.
*/
sb->s_iflags |= SB_I_NOUMASK;
- sb->s_iflags |= SB_I_EVM_UNSUPPORTED;
+ sb->s_iflags |= SB_I_EVM_HMAC_UNSUPPORTED;

err = -ENOMEM;
root_dentry = ovl_get_root(sb, ctx->upper.dentry, oe);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index d055582a5efb..3920ab94d84a 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1177,7 +1177,7 @@ extern int send_sigurg(struct fown_struct *fown);
#define SB_I_USERNS_VISIBLE 0x00000010 /* fstype already mounted */
#define SB_I_IMA_UNVERIFIABLE_SIGNATURE 0x00000020
#define SB_I_UNTRUSTED_MOUNTER 0x00000040
-#define SB_I_EVM_UNSUPPORTED 0x00000080
+#define SB_I_EVM_HMAC_UNSUPPORTED 0x00000080

#define SB_I_SKIP_SYNC 0x00000100 /* Skip superblock at global sync */
#define SB_I_PERSB_BDI 0x00000200 /* has a per-sb bdi */
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index cfb4f9809369..c4a6081ce596 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -155,7 +155,7 @@ static int is_unsupported_fs(struct dentry *dentry)
{
struct inode *inode = d_backing_inode(dentry);

- if (inode->i_sb->s_iflags & SB_I_EVM_UNSUPPORTED) {
+ if (inode->i_sb->s_iflags & SB_I_EVM_HMAC_UNSUPPORTED) {
pr_info_once("%s not supported\n", inode->i_sb->s_type->name);
return 1;
}
--
2.43.0


2024-02-23 17:30:14

by Stefan Berger

[permalink] [raw]
Subject: [PATCH v3 10/10] evm: Rename is_unsupported_fs to is_unsupported_hmac_fs

Rename is_unsupported_fs to is_unsupported_hmac_fs since now only HMAC is
unsupported.

Co-developed-by: Mimi Zohar <[email protected]>
Signed-off-by: Stefan Berger <[email protected]>
---
security/integrity/evm/evm_main.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index c4a6081ce596..62fe66dd53ce 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -151,7 +151,7 @@ static int evm_find_protected_xattrs(struct dentry *dentry)
return count;
}

-static int is_unsupported_fs(struct dentry *dentry)
+static int is_unsupported_hmac_fs(struct dentry *dentry)
{
struct inode *inode = d_backing_inode(dentry);

@@ -196,7 +196,8 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
* On unsupported filesystems without EVM_INIT_X509 enabled, skip
* signature verification.
*/
- if (!(evm_initialized & EVM_INIT_X509) && is_unsupported_fs(dentry))
+ if (!(evm_initialized & EVM_INIT_X509) &&
+ is_unsupported_hmac_fs(dentry))
return INTEGRITY_UNKNOWN;

/* if status is not PASS, try to check again - against -ENOMEM */
@@ -266,7 +267,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
} else if (!IS_RDONLY(inode) &&
!(inode->i_sb->s_readonly_remount) &&
!IS_IMMUTABLE(inode) &&
- !is_unsupported_fs(dentry)) {
+ !is_unsupported_hmac_fs(dentry)) {
evm_update_evmxattr(dentry, xattr_name,
xattr_value,
xattr_value_len);
@@ -502,12 +503,12 @@ static int evm_protect_xattr(struct mnt_idmap *idmap,
if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) {
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (is_unsupported_fs(dentry))
+ if (is_unsupported_hmac_fs(dentry))
return -EPERM;
} else if (!evm_protected_xattr(xattr_name)) {
if (!posix_xattr_acl(xattr_name))
return 0;
- if (is_unsupported_fs(dentry))
+ if (is_unsupported_hmac_fs(dentry))
return 0;

evm_status = evm_verify_current_integrity(dentry);
@@ -515,7 +516,7 @@ static int evm_protect_xattr(struct mnt_idmap *idmap,
(evm_status == INTEGRITY_NOXATTRS))
return 0;
goto out;
- } else if (is_unsupported_fs(dentry))
+ } else if (is_unsupported_hmac_fs(dentry))
return 0;

evm_status = evm_verify_current_integrity(dentry);
@@ -817,7 +818,7 @@ static void evm_inode_post_setxattr(struct dentry *dentry,
if (!(evm_initialized & EVM_INIT_HMAC))
return;

- if (is_unsupported_fs(dentry))
+ if (is_unsupported_hmac_fs(dentry))
return;

evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len);
@@ -916,7 +917,7 @@ static int evm_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
if (evm_initialized & EVM_ALLOW_METADATA_WRITES)
return 0;

- if (is_unsupported_fs(dentry))
+ if (is_unsupported_hmac_fs(dentry))
return 0;

if (!(ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)))
@@ -967,7 +968,7 @@ static void evm_inode_post_setattr(struct mnt_idmap *idmap,
if (!(evm_initialized & EVM_INIT_HMAC))
return;

- if (is_unsupported_fs(dentry))
+ if (is_unsupported_hmac_fs(dentry))
return;

if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
--
2.43.0


2024-02-23 17:41:01

by Stefan Berger

[permalink] [raw]
Subject: [PATCH v3 06/10] evm: Store and detect metadata inode attributes changes

On stacked filesystem the metadata inode may be different than the one
file data inode and therefore changes to it need to be detected
independently. Therefore, store the i_version, device number, and inode
number associated with the file metadata inode.

Implement a function to detect changes to the inode and if a change is
detected reset the evm_status. This function will be called by IMA when
IMA detects that the metadata inode is different from the file's inode.

Co-developed-by: Mimi Zohar <[email protected]>
Signed-off-by: Stefan Berger <[email protected]>
---
include/linux/evm.h | 8 ++++++++
security/integrity/evm/evm.h | 6 ++++--
security/integrity/evm/evm_crypto.c | 23 ++++++++++++++++------
security/integrity/evm/evm_main.c | 30 +++++++++++++++++++++++++++--
4 files changed, 57 insertions(+), 10 deletions(-)

diff --git a/include/linux/evm.h b/include/linux/evm.h
index d48d6da32315..ddece4a6b25d 100644
--- a/include/linux/evm.h
+++ b/include/linux/evm.h
@@ -26,6 +26,8 @@ extern int evm_protected_xattr_if_enabled(const char *req_xattr_name);
extern int evm_read_protected_xattrs(struct dentry *dentry, u8 *buffer,
int buffer_size, char type,
bool canonical_fmt);
+extern bool evm_metadata_changed(struct inode *inode,
+ struct inode *metadata_inode);
#ifdef CONFIG_FS_POSIX_ACL
extern int posix_xattr_acl(const char *xattrname);
#else
@@ -76,5 +78,11 @@ static inline int evm_read_protected_xattrs(struct dentry *dentry, u8 *buffer,
return -EOPNOTSUPP;
}

+static inline bool evm_metadata_changed(struct inode *inode,
+ struct inode *metadata_inode)
+{
+ return false;
+}
+
#endif /* CONFIG_EVM */
#endif /* LINUX_EVM_H */
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
index eb1a2c343bd7..b357c0ca8d23 100644
--- a/security/integrity/evm/evm.h
+++ b/security/integrity/evm/evm.h
@@ -39,6 +39,7 @@ struct xattr_list {
struct evm_iint_cache {
unsigned long flags;
enum integrity_status evm_status:4;
+ struct integrity_inode_attributes metadata_inode;
};

extern struct lsm_blob_sizes evm_blob_sizes;
@@ -74,11 +75,12 @@ int evm_update_evmxattr(struct dentry *dentry,
size_t req_xattr_value_len);
int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
const char *req_xattr_value,
- size_t req_xattr_value_len, struct evm_digest *data);
+ size_t req_xattr_value_len, struct evm_digest *data,
+ struct evm_iint_cache *iint);
int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
const char *req_xattr_value,
size_t req_xattr_value_len, char type,
- struct evm_digest *data);
+ struct evm_digest *data, struct evm_iint_cache *iint);
int evm_init_hmac(struct inode *inode, const struct xattr *xattrs,
char *hmac_val);
int evm_init_secfs(void);
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index 35416f55391c..7c06ffd633d2 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -221,7 +221,8 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
const char *req_xattr_name,
const char *req_xattr_value,
size_t req_xattr_value_len,
- uint8_t type, struct evm_digest *data)
+ uint8_t type, struct evm_digest *data,
+ struct evm_iint_cache *iint)
{
struct inode *inode = d_inode(d_real(dentry, D_REAL_METADATA));
struct xattr_list *xattr;
@@ -231,6 +232,7 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
int error;
int size, user_space_size;
bool ima_present = false;
+ u64 i_version = 0;

if (!(inode->i_opflags & IOP_XATTR) ||
inode->i_sb->s_user_ns != &init_user_ns)
@@ -294,6 +296,13 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,
}
hmac_add_misc(desc, inode, type, data->digest);

+ if (inode != d_backing_inode(dentry) && iint) {
+ if (IS_I_VERSION(inode))
+ i_version = inode_query_iversion(inode);
+ integrity_inode_attrs_store(&iint->metadata_inode, i_version,
+ inode);
+ }
+
/* Portable EVM signatures must include an IMA hash */
if (type == EVM_XATTR_PORTABLE_DIGSIG && !ima_present)
error = -EPERM;
@@ -305,18 +314,19 @@ static int evm_calc_hmac_or_hash(struct dentry *dentry,

int evm_calc_hmac(struct dentry *dentry, const char *req_xattr_name,
const char *req_xattr_value, size_t req_xattr_value_len,
- struct evm_digest *data)
+ struct evm_digest *data, struct evm_iint_cache *iint)
{
return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value,
- req_xattr_value_len, EVM_XATTR_HMAC, data);
+ req_xattr_value_len, EVM_XATTR_HMAC, data,
+ iint);
}

int evm_calc_hash(struct dentry *dentry, const char *req_xattr_name,
const char *req_xattr_value, size_t req_xattr_value_len,
- char type, struct evm_digest *data)
+ char type, struct evm_digest *data, struct evm_iint_cache *iint)
{
return evm_calc_hmac_or_hash(dentry, req_xattr_name, req_xattr_value,
- req_xattr_value_len, type, data);
+ req_xattr_value_len, type, data, iint);
}

static int evm_is_immutable(struct dentry *dentry, struct inode *inode)
@@ -357,6 +367,7 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
const char *xattr_value, size_t xattr_value_len)
{
struct inode *inode = d_backing_inode(dentry);
+ struct evm_iint_cache *iint = evm_iint_inode(inode);
struct evm_digest data;
int rc = 0;

@@ -372,7 +383,7 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,

data.hdr.algo = HASH_ALGO_SHA1;
rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
- xattr_value_len, &data);
+ xattr_value_len, &data, iint);
if (rc == 0) {
data.hdr.xattr.sha1.type = EVM_XATTR_HMAC;
rc = __vfs_setxattr_noperm(&nop_mnt_idmap, dentry,
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index c658d2f1494b..c1ca0894cd8a 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -226,7 +226,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,

digest.hdr.algo = HASH_ALGO_SHA1;
rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
- xattr_value_len, &digest);
+ xattr_value_len, &digest, iint);
if (rc)
break;
rc = crypto_memneq(xattr_data->data, digest.digest,
@@ -247,7 +247,8 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
hdr = (struct signature_v2_hdr *)xattr_data;
digest.hdr.algo = hdr->hash_algo;
rc = evm_calc_hash(dentry, xattr_name, xattr_value,
- xattr_value_len, xattr_data->type, &digest);
+ xattr_value_len, xattr_data->type, &digest,
+ iint);
if (rc)
break;
rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM,
@@ -733,6 +734,31 @@ static void evm_reset_status(struct inode *inode)
iint->evm_status = INTEGRITY_UNKNOWN;
}

+/**
+ * evm_metadata_changed: Detect changes to the metadata
+ * @inode: a file's inode
+ * @metadata_inode: metadata inode
+ *
+ * On a stacked filesystem detect whether the metadata has changed. If this is
+ * the case reset the evm_status associated with the inode that represents the
+ * file.
+ */
+bool evm_metadata_changed(struct inode *inode, struct inode *metadata_inode)
+{
+ struct evm_iint_cache *iint = evm_iint_inode(inode);
+ bool ret = false;
+
+ if (iint) {
+ ret = (!IS_I_VERSION(metadata_inode) ||
+ integrity_inode_attrs_changed(&iint->metadata_inode,
+ metadata_inode));
+ if (ret)
+ iint->evm_status = INTEGRITY_UNKNOWN;
+ }
+
+ return ret;
+}
+
/**
* evm_revalidate_status - report whether EVM status re-validation is necessary
* @xattr_name: pointer to the affected extended attribute name
--
2.43.0


2024-03-19 22:52:53

by Mimi Zohar

[permalink] [raw]
Subject: Re: [PATCH v3 03/10] evm: Implement per signature type decision in security_inode_copy_up_xattr

On Fri, 2024-02-23 at 12:25 -0500, Stefan Berger wrote:
> To support "portable and immutable signatures" on otherwise unsupported
> filesystems, determine the EVM signature type by the content of a file's
> xattr. If the file has the appropriate signature type then allow it to be
> copied up. All other signature types are discarded as before.
>
> "Portable and immutable" EVM signatures can be copied up by stacked file-
> system since the metadata their signature covers does not include file-
> system-specific data such as a file's inode number, generation, and UUID.
>
> Co-developed-by: Mimi Zohar <[email protected]>
> Signed-off-by: Stefan Berger <[email protected]>

Signed-off-by: Mimi Zohar <[email protected]>


2024-03-19 22:54:24

by Mimi Zohar

[permalink] [raw]
Subject: Re: [PATCH v3 07/10] ima: re-evaluate file integrity on file metadata change

> @@ -286,7 +288,8 @@ static int process_measurement(struct file *file, const
> struct cred *cred,
> }
>
> /*
> - * On stacked filesystems, detect and re-evaluate file data changes.
> + * On stacked filesystems, detect and re-evaluate file data and
> + * metadata changes.
> */
> real_inode = d_real_inode(file_dentry(file));
> if (real_inode != inode &&
> @@ -297,6 +300,15 @@ static int process_measurement(struct file *file, const
> struct cred *cred,
> iint->flags &= ~IMA_DONE_MASK;
> iint->measured_pcrs = 0;
> }
> +
> + /*
> + * Reset the EVM status when metadata changed.
> + */

-> To force re-validation, reset both the EVM and IMA status when the metadata
changes.

Mimi

> + metadata_inode = d_inode(d_real(file_dentry(file),
> + D_REAL_METADATA));
> + if (evm_metadata_changed(inode, metadata_inode))
> + iint->flags &= ~(IMA_APPRAISED |
> + IMA_APPRAISED_SUBMASK);
> }
>
> /* Determine if already appraised/measured based on bitmask


2024-03-19 22:54:42

by Mimi Zohar

[permalink] [raw]
Subject: Re: [PATCH v3 09/10] fs: Rename SB_I_EVM_UNSUPPORTED to SB_I_EVM_HMAC_UNSUPPORTED

On Fri, 2024-02-23 at 12:25 -0500, Stefan Berger wrote:
> Now that EVM supports RSA signatures for previously completely
> unsupported filesystems rename the flag SB_I_EVM_UNSUPPORTED to
> SB_I_EVM_HMAC_UNSUPPORTED to reflect that only HMAC is not supported.
>
> Suggested-by: Amir Goldstein <[email protected]>
> Suggested-by: Mimi Zohar <[email protected]>
> Signed-off-by: Stefan Berger <[email protected]>
> Acked-by: Amir Goldstein <[email protected]>

Signed-off-by: Mimi Zohar <[email protected]>


2024-03-19 22:54:47

by Mimi Zohar

[permalink] [raw]
Subject: Re: [PATCH v3 10/10] evm: Rename is_unsupported_fs to is_unsupported_hmac_fs

On Fri, 2024-02-23 at 12:25 -0500, Stefan Berger wrote:
> Rename is_unsupported_fs to is_unsupported_hmac_fs since now only HMAC is
> unsupported.
>
> Co-developed-by: Mimi Zohar <[email protected]>
> Signed-off-by: Stefan Berger <[email protected]>

Signed-off-by: Mimi Zohar <[email protected]>


2024-03-19 22:55:11

by Mimi Zohar

[permalink] [raw]
Subject: Re: [PATCH v3 04/10] evm: Use the metadata inode to calculate metadata hash

On Fri, 2024-02-23 at 12:25 -0500, Stefan Berger wrote:
> Changes to file attributes (mode bits, uid, gid) on the lower layer are
> not taken into account when d_backing_inode() is used when a file is
> accessed on the overlay layer and this file has not yet been copied up.
> This is because d_backing_inode() does not return the real inode of the
> lower layer but instead returns the backing inode which in this case
> holds wrong file attributes. Further, when CONFIG_OVERLAY_FS_METACOPY is
> enabled and a copy-up is triggered due to file metadata changes, then
> the metadata are held by the backing inode while the data are still held
> by the real inode. Therefore, use d_inode(d_real(dentry, D_REAL_METADATA))
> to get to the file's metadata inode and use it to calculate the metadata
> hash with.
>
> Co-developed-by: Mimi Zohar <[email protected]>
> Signed-off-by: Stefan Berger <[email protected]>
> Acked-by: Amir Goldstein <[email protected]>

Signed-off-by: Mimi Zohar <[email protected]>


2024-03-19 22:55:21

by Mimi Zohar

[permalink] [raw]
Subject: Re: [PATCH v3 02/10] security: allow finer granularity in permitting copy-up of security xattrs

On Fri, 2024-02-23 at 12:25 -0500, Stefan Berger wrote:
> Copying up xattrs is solely based on the security xattr name. For finer
> granularity add a dentry parameter to the security_inode_copy_up_xattr
> hook definition, allowing decisions to be based on the xattr content as
> well.
>
> Co-developed-by: Mimi Zohar <[email protected]>
> Signed-off-by: Stefan Berger <[email protected]>
> Acked-by: Amir Goldstein <[email protected]>

Signed-off-by: Mimi Zohar <[email protected]>


2024-03-19 22:58:52

by Mimi Zohar

[permalink] [raw]
Subject: Re: [PATCH v3 01/10] ima: Rename backing_inode to real_inode

Hi Stefan,

On Fri, 2024-02-23 at 12:25 -0500, Stefan Berger wrote:
> Rename the backing_inode variable to real_inode since it gets its value
> from real_inode().
>
> Suggested-by: Amir Goldstein <[email protected]>
> Co-developed-by: Mimi Zohar <[email protected]>
> Signed-off-by: Stefan Berger <[email protected]>
> Acked-by: Amir Goldstein <[email protected]>

Thanks for adding me as a co-developer. The "Co-developed-by" tag needs to be
followed immediately by their "Signed-off-by" tag. I'll need to move it
immediately before my "Signed-off-by" tag.

Signed-off-by: Mimi Zohar <[email protected]>

Mimi


2024-03-19 23:27:26

by Mimi Zohar

[permalink] [raw]
Subject: Re: [PATCH v3 08/10] evm: Enforce signatures on unsupported filesystem for EVM_INIT_X509

On Fri, 2024-02-23 at 12:25 -0500, Stefan Berger wrote:
> Unsupported filesystems currently do not enforce any signatures. Add
> support for signature enforcement of the "original" and "portable &
> immutable" signatures when EVM_INIT_X509 is enabled.
>
> The "original" signature type contains filesystem specific metadata.
> Thus it cannot be copied up and verified. However with EVM_INIT_X509
> and EVM_ALLOW_METADATA_WRITES enabled, the "original" file signature
> may be written.
>
> When EVM_ALLOW_METADATA_WRITES is not set or once it is removed from
> /sys/kernel/security/evm by setting EVM_INIT_HMAC for example, it is not
> possible to write or remove xattrs on the overlay filesystem.

This paragraph is currently correct, but at some point EVM_ALLOW_METADATA_WRITES
will be deprecated. Refer to commit 1434c6a1d32a ("evm: Deprecate
EVM_ALLOW_METADATA_WRITES").

Mimi

>
> This change still prevents EVM from writing HMAC signatures on
> unsupported filesystem when EVM_INIT_HMAC is enabled.
>
> Co-developed-by: Mimi Zohar <[email protected]>
> Signed-off-by: Stefan Berger <[email protected]>

Signed-off-by: Mimi Zohar <[email protected]>



2024-04-09 21:30:35

by Mimi Zohar

[permalink] [raw]
Subject: Re: [PATCH v3 00/10] evm: Support signatures on stacked filesystem

On Fri, 2024-02-23 at 12:25 -0500, Stefan Berger wrote:
> EVM signature verification on stacked filesystem has recently been
> completely disabled by declaring some filesystems as unsupported
> (only overlayfs). This series now enables copy-up of "portable
> and immutable" signatures on those filesystems and enables the
> enforcement of "portable and immultable" as well as the "original"
> signatures on previously unsupported filesystem when evm is enabled
> with EVM_INIT_X509. HMAC verification and generation remains disabled.
>
> "Portable and immutable" signatures can be copied up since they are
> not created over file-specific metadata, such as UUID or generation.
> Instead, they are only covering file metadata such as mode bits, uid, and
> gid, that will all be preserved during a copy-up of the file metadata.
>
> This series is now based on the 'next' branch of Paul Moore's LSM tree and
> requires the following two commits from the vfs.misc branch of the vfs git
> repo at https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
>
> commit 2109cc619e73 ("fs: remove the inode argument to ->d_real() method")
> commit c6c14f926fbe ("fs: make file_dentry() a simple accessor")

Thanks, Stefan. The patch set is now queued in the next-integrity branch.
https://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git/

Mimi