Kernel
  Threads by month 
                
            - ----- 2025 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- 58 participants
- 20947 discussions
 
                        
                    
                        
                            
                                
                            
                            [PATCH v2 OLK-5.10 0/4] arm64: support batched/deferred tlb shootdown during page reclamation/migration
                        
                        
by Jinjiang Tu 18 Aug '23
                    by Jinjiang Tu 18 Aug '23
18 Aug '23
                    
                        Support batched/deferred tlb shootdown during page reclamation/migration
for arm64.
Anshuman Khandual (1):
  mm/tlbbatch: introduce arch_tlbbatch_should_defer()
Barry Song (2):
  mm/tlbbatch: rename and extend some functions
  arm64: support batched/deferred tlb shootdown during page
    reclamation/migration
Yicong Yang (1):
  mm/tlbbatch: introduce arch_flush_tlb_batched_pending()
 .../features/vm/TLB/arch-support.txt          |  2 +-
 arch/arm64/Kconfig                            |  1 +
 arch/arm64/include/asm/tlbbatch.h             | 12 +++++
 arch/arm64/include/asm/tlbflush.h             | 44 +++++++++++++++++--
 arch/x86/include/asm/tlbflush.h               | 22 +++++++++-
 include/linux/mm_types.h                      |  4 +-
 include/linux/mm_types_task.h                 |  4 +-
 mm/rmap.c                                     | 21 ++++-----
 8 files changed, 88 insertions(+), 22 deletions(-)
 create mode 100644 arch/arm64/include/asm/tlbbatch.h
-- 
2.25.1
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            5
                            
                          
                          
                            
    
                          
                        
                     
                        
                    
                        
                            
                                
                            
                            [PATCH openEuler-1.0-LTS] net: vmxnet3: fix possible use-after-free bugs in vmxnet3_rq_alloc_rx_buf()
                        
                        
by Lu Wei 18 Aug '23
                    by Lu Wei 18 Aug '23
18 Aug '23
                    
                        From: Zixuan Fu <r33s3n6(a)gmail.com>
stable inclusion
from stable-v4.19.245
commit 3adaaf3472e8ea410cb1330e5dd8372b0483dc78
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I7TTDS
CVE: CVE-2023-4387
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
--------------------------------
[ Upstream commit 9e7fef9521e73ca8afd7da9e58c14654b02dfad8 ]
In vmxnet3_rq_alloc_rx_buf(), when dma_map_single() fails, rbi->skb is
freed immediately. Similarly, in another branch, when dma_map_page() fails,
rbi->page is also freed. In the two cases, vmxnet3_rq_alloc_rx_buf()
returns an error to its callers vmxnet3_rq_init() -> vmxnet3_rq_init_all()
-> vmxnet3_activate_dev(). Then vmxnet3_activate_dev() calls
vmxnet3_rq_cleanup_all() in error handling code, and rbi->skb or rbi->page
are freed again in vmxnet3_rq_cleanup_all(), causing use-after-free bugs.
To fix these possible bugs, rbi->skb and rbi->page should be cleared after
they are freed.
The error log in our fault-injection testing is shown as follows:
[   14.319016] BUG: KASAN: use-after-free in consume_skb+0x2f/0x150
...
[   14.321586] Call Trace:
...
[   14.325357]  consume_skb+0x2f/0x150
[   14.325671]  vmxnet3_rq_cleanup_all+0x33a/0x4e0 [vmxnet3]
[   14.326150]  vmxnet3_activate_dev+0xb9d/0x2ca0 [vmxnet3]
[   14.326616]  vmxnet3_open+0x387/0x470 [vmxnet3]
...
[   14.361675] Allocated by task 351:
...
[   14.362688]  __netdev_alloc_skb+0x1b3/0x6f0
[   14.362960]  vmxnet3_rq_alloc_rx_buf+0x1b0/0x8d0 [vmxnet3]
[   14.363317]  vmxnet3_activate_dev+0x3e3/0x2ca0 [vmxnet3]
[   14.363661]  vmxnet3_open+0x387/0x470 [vmxnet3]
...
[   14.367309]
[   14.367412] Freed by task 351:
...
[   14.368932]  __dev_kfree_skb_any+0xd2/0xe0
[   14.369193]  vmxnet3_rq_alloc_rx_buf+0x71e/0x8d0 [vmxnet3]
[   14.369544]  vmxnet3_activate_dev+0x3e3/0x2ca0 [vmxnet3]
[   14.369883]  vmxnet3_open+0x387/0x470 [vmxnet3]
[   14.370174]  __dev_open+0x28a/0x420
[   14.370399]  __dev_change_flags+0x192/0x590
[   14.370667]  dev_change_flags+0x7a/0x180
[   14.370919]  do_setlink+0xb28/0x3570
[   14.371150]  rtnl_newlink+0x1160/0x1740
[   14.371399]  rtnetlink_rcv_msg+0x5bf/0xa50
[   14.371661]  netlink_rcv_skb+0x1cd/0x3e0
[   14.371913]  netlink_unicast+0x5dc/0x840
[   14.372169]  netlink_sendmsg+0x856/0xc40
[   14.372420]  ____sys_sendmsg+0x8a7/0x8d0
[   14.372673]  __sys_sendmsg+0x1c2/0x270
[   14.372914]  do_syscall_64+0x41/0x90
[   14.373145]  entry_SYSCALL_64_after_hwframe+0x44/0xae
...
Fixes: 5738a09d58d5a ("vmxnet3: fix checks for dma mapping errors")
Reported-by: TOTE Robot <oslab(a)tsinghua.edu.cn>
Signed-off-by: Zixuan Fu <r33s3n6(a)gmail.com>
Link: https://lore.kernel.org/r/20220514050656.2636588-1-r33s3n6@gmail.com
Signed-off-by: Paolo Abeni <pabeni(a)redhat.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: Lu Wei <luwei32(a)huawei.com>
---
 drivers/net/vmxnet3/vmxnet3_drv.c | 2 ++
 1 file changed, 2 insertions(+)
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index e454dfc9ad8f..925f8e8ade1c 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -595,6 +595,7 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx,
 				if (dma_mapping_error(&adapter->pdev->dev,
 						      rbi->dma_addr)) {
 					dev_kfree_skb_any(rbi->skb);
+					rbi->skb = NULL;
 					rq->stats.rx_buf_alloc_failure++;
 					break;
 				}
@@ -619,6 +620,7 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx,
 				if (dma_mapping_error(&adapter->pdev->dev,
 						      rbi->dma_addr)) {
 					put_page(rbi->page);
+					rbi->page = NULL;
 					rq->stats.rx_buf_alloc_failure++;
 					break;
 				}
-- 
2.34.1
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            1
                            
                          
                          
                            
    
                          
                        
                     
                        
                    18 Aug '23
                    
                        Support multiple compression streams for zram.
Alexey Romanov (1):
  zram: add size class equals check into recompression
Andy Shevchenko (1):
  lib/cmdline: Export next_arg() for being used in modules
Ming Lei (1):
  zram: fix race between zram_reset_device() and disksize_store()
Sergey Senozhatsky (11):
  zram: preparation for multi-zcomp support
  zram: add recompression algorithm sysfs knob
  zram: factor out WB and non-WB zram read functions
  zram: introduce recompress sysfs knob
  zram: add recompress flag to read_block_state()
  zram: clarify writeback_store() comment
  zram: remove redundant checks from zram_recompress()
  zram: add algo parameter support to zram_recompress()
  documentation: add zram recompression documentation
  zram: add incompressible writeback
  zram: add incompressible flag to read_block_state()
 Documentation/admin-guide/blockdev/zram.rst |  98 +++-
 drivers/block/zram/Kconfig                  |   9 +
 drivers/block/zram/zcomp.c                  |   6 +-
 drivers/block/zram/zcomp.h                  |   2 +-
 drivers/block/zram/zram_drv.c               | 594 +++++++++++++++++---
 drivers/block/zram/zram_drv.h               |  22 +-
 include/linux/zsmalloc.h                    |   2 +
 lib/cmdline.c                               |   1 +
 mm/zsmalloc.c                               |  21 +
 9 files changed, 682 insertions(+), 73 deletions(-)
-- 
2.25.1
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            15
                            
                          
                          
                            
    
                          
                        
                     
                        
                    
                        
                            
                                
                            
                            [PATCH OLK-5.10 0/4] arm64: support batched/deferred tlb shootdown during page reclamation/migration
                        
                        
by Jinjiang Tu 18 Aug '23
                    by Jinjiang Tu 18 Aug '23
18 Aug '23
                    
                        Support  batched/deferred tlb shootdown during page reclamation/migration
for arm64.
Anshuman Khandual (1):
  mm/tlbbatch: introduce arch_tlbbatch_should_defer()
Barry Song (2):
  mm/tlbbatch: rename and extend some functions
  arm64: support batched/deferred tlb shootdown during page
    reclamation/migration
Yicong Yang (1):
  mm/tlbbatch: introduce arch_flush_tlb_batched_pending()
 .../features/vm/TLB/arch-support.txt          |  2 +-
 arch/arm64/Kconfig                            |  1 +
 arch/arm64/include/asm/tlbbatch.h             | 12 +++++
 arch/arm64/include/asm/tlbflush.h             | 44 +++++++++++++++++--
 arch/x86/include/asm/tlbflush.h               | 22 +++++++++-
 include/linux/mm_types_task.h                 |  4 +-
 mm/rmap.c                                     | 21 ++++-----
 7 files changed, 85 insertions(+), 21 deletions(-)
 create mode 100644 arch/arm64/include/asm/tlbbatch.h
-- 
2.25.1
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            5
                            
                          
                          
                            
    
                          
                        
                     
                        
                    18 Aug '23
                    
                        Isolate the IMA digest list code by using macros.
v2:
	Exclude some macros for code that has already been merged into upstream kernel.
Signed-off-by: Zhou Shuiqing <zhoushuiqing2(a)huawei.com>
---
 fs/xattr.c                             |   4 +
 include/linux/evm.h                    |   4 +-
 include/linux/ima.h                    |   8 +
 security/integrity/digsig_asymmetric.c |   4 +
 security/integrity/evm/evm.h           |   2 +
 security/integrity/evm/evm_crypto.c    |  38 +++-
 security/integrity/evm/evm_main.c      |  79 +++++++-
 security/integrity/iint.c              |   2 +
 security/integrity/ima/ima.h           |  80 +++++++-
 security/integrity/ima/ima_api.c       |  39 ++++
 security/integrity/ima/ima_appraise.c  | 154 ++++++++++++++-
 security/integrity/ima/ima_fs.c        | 247 ++++++++++++++++++++++++-
 security/integrity/ima/ima_init.c      |   6 +
 security/integrity/ima/ima_main.c      |  36 ++++
 security/integrity/ima/ima_policy.c    |  80 ++++++++
 security/integrity/integrity.h         |  15 +-
 security/security.c                    |   2 +
 17 files changed, 779 insertions(+), 21 deletions(-)
diff --git a/fs/xattr.c b/fs/xattr.c
index 149b8cf5f99f..c31266a83391 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -16,7 +16,9 @@
 #include <linux/namei.h>
 #include <linux/security.h>
 #include <linux/evm.h>
+#ifdef CONFIG_IMA_DIGEST_LIST
 #include <linux/ima.h>
+#endif
 #include <linux/syscalls.h>
 #include <linux/export.h>
 #include <linux/fsnotify.h>
@@ -475,7 +477,9 @@ __vfs_removexattr_locked(struct dentry *dentry, const char *name,
 
 	if (!error) {
 		fsnotify_xattr(dentry);
+#ifdef CONFIG_IMA_DIGEST_LIST
 		ima_inode_post_removexattr(dentry, name);
+#endif
 		evm_inode_post_removexattr(dentry, name);
 	}
 
diff --git a/include/linux/evm.h b/include/linux/evm.h
index e5b7bcb152b9..39bb17a8236b 100644
--- a/include/linux/evm.h
+++ b/include/linux/evm.h
@@ -35,7 +35,7 @@ extern void evm_inode_post_removexattr(struct dentry *dentry,
 extern int evm_inode_init_security(struct inode *inode,
 				   const struct xattr *xattr_array,
 				   struct xattr *evm);
-extern bool evm_status_revalidate(const char *xattr_name);
+extern bool evm_revalidate_status(const char *xattr_name);
 #ifdef CONFIG_FS_POSIX_ACL
 extern int posix_xattr_acl(const char *xattrname);
 #else
@@ -105,7 +105,7 @@ static inline int evm_inode_init_security(struct inode *inode,
 	return 0;
 }
 
-static inline bool evm_status_revalidate(const char *xattr_name)
+static inline bool evm_revalidate_status(const char *xattr_name)
 {
 	return false;
 }
diff --git a/include/linux/ima.h b/include/linux/ima.h
index f7a088b2579e..713c6f9696cb 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -144,13 +144,17 @@ extern bool is_ima_appraise_enabled(void);
 extern void ima_inode_post_setattr(struct dentry *dentry);
 extern int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
 		       const void *xattr_value, size_t xattr_value_len);
+#ifdef CONFIG_IMA_DIGEST_LIST
 extern void ima_inode_post_setxattr(struct dentry *dentry,
 				    const char *xattr_name,
 				    const void *xattr_value,
 				    size_t xattr_value_len);
+#endif
 extern int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name);
+#ifdef CONFIG_IMA_DIGEST_LIST
 extern void ima_inode_post_removexattr(struct dentry *dentry,
 				       const char *xattr_name);
+#endif
 #else
 static inline bool is_ima_appraise_enabled(void)
 {
@@ -170,12 +174,14 @@ static inline int ima_inode_setxattr(struct dentry *dentry,
 	return 0;
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static inline void ima_inode_post_setxattr(struct dentry *dentry,
 					   const char *xattr_name,
 					   const void *xattr_value,
 					   size_t xattr_value_len)
 {
 }
+#endif
 
 static inline int ima_inode_removexattr(struct dentry *dentry,
 					const char *xattr_name)
@@ -183,10 +189,12 @@ static inline int ima_inode_removexattr(struct dentry *dentry,
 	return 0;
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static inline void ima_inode_post_removexattr(struct dentry *dentry,
 					      const char *xattr_name)
 {
 }
+#endif
 #endif /* CONFIG_IMA_APPRAISE */
 
 #if defined(CONFIG_IMA_APPRAISE) && defined(CONFIG_INTEGRITY_TRUSTED_KEYRING)
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
index 92dc64755e53..72941f9b1b99 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -9,7 +9,9 @@
 #include <linux/err.h>
 #include <linux/ratelimit.h>
 #include <linux/key-type.h>
+#ifdef CONFIG_IMA_DIGEST_LIST
 #include <linux/verification.h>
+#endif
 #include <crypto/public_key.h>
 #include <crypto/hash_info.h>
 #include <keys/asymmetric-type.h>
@@ -55,6 +57,7 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
 		key = request_key(&key_type_asymmetric, name, NULL);
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (IS_ERR(key)) {
 #ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
 		keyring = VERIFY_USE_SECONDARY_KEYRING;
@@ -63,6 +66,7 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
 #endif
 		key = search_trusted_key(keyring, &key_type_asymmetric, name);
 	}
+#endif
 
 	if (IS_ERR(key)) {
 		if (keyring)
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
index ca7ed2e532dc..f8b1627708a1 100644
--- a/security/integrity/evm/evm.h
+++ b/security/integrity/evm/evm.h
@@ -32,7 +32,9 @@ struct xattr_list {
 };
 
 extern int evm_initialized;
+#ifdef CONFIG_IMA_DIGEST_LIST
 extern enum hash_algo evm_hash_algo;
+#endif
 
 #define EVM_ATTR_FSUUID		0x0001
 
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index 7c36dbb96d24..fa8147c2294e 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -33,7 +33,11 @@ static DEFINE_MUTEX(mutex);
 
 static unsigned long evm_set_key_flags;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 enum hash_algo evm_hash_algo __ro_after_init = HASH_ALGO_SHA1;
+#else
+static const char evm_hmac[] = "hmac(sha1)";
+#endif
 
 /**
  * evm_set_key() - set EVM HMAC key from the kernel
@@ -74,11 +78,13 @@ static struct shash_desc *init_desc(char type, uint8_t hash_algo)
 	long rc;
 	const char *algo;
 	struct crypto_shash **tfm, *tmp_tfm;
-	char evm_hmac[CRYPTO_MAX_ALG_NAME];
 	struct shash_desc *desc;
+#ifdef CONFIG_IMA_DIGEST_LIST
+	char evm_hmac[CRYPTO_MAX_ALG_NAME];
 
 	snprintf(evm_hmac, sizeof(evm_hmac), "hmac(%s)",
 		 CONFIG_EVM_DEFAULT_HASH);
+#endif
 
 	if (type == EVM_XATTR_HMAC) {
 		if (!(evm_initialized & EVM_INIT_HMAC)) {
@@ -156,8 +162,12 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
 	/* Don't include the inode or generation number in portable
 	 * signatures
 	 */
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (type != EVM_XATTR_PORTABLE_DIGSIG &&
 	    type != EVM_IMA_XATTR_DIGEST_LIST) {
+#else
+	if (type != EVM_XATTR_PORTABLE_DIGSIG) {
+#endif
 		hmac_misc.ino = inode->i_ino;
 		hmac_misc.generation = inode->i_generation;
 	}
@@ -174,8 +184,12 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
 	hmac_misc.mode = inode->i_mode;
 	crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof(hmac_misc));
 	if ((evm_hmac_attrs & EVM_ATTR_FSUUID) &&
+#ifdef CONFIG_IMA_DIGEST_LIST
 	    type != EVM_XATTR_PORTABLE_DIGSIG &&
 	    type != EVM_IMA_XATTR_DIGEST_LIST)
+#else
+		type != EVM_XATTR_PORTABLE_DIGSIG)
+#endif
 		crypto_shash_update(desc, (u8 *)&inode->i_sb->s_uuid, UUID_SIZE);
 	crypto_shash_final(desc, digest);
 }
@@ -288,8 +302,12 @@ static int evm_is_immutable(struct dentry *dentry, struct inode *inode)
 			return 0;
 		return rc;
 	}
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (xattr_data->type == EVM_XATTR_PORTABLE_DIGSIG ||
 	    xattr_data->type == EVM_IMA_XATTR_DIGEST_LIST)
+#else
+	if (xattr_data->type == EVM_XATTR_PORTABLE_DIGSIG)
+#endif
 		rc = 1;
 	else
 		rc = 0;
@@ -321,15 +339,23 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
 	if (rc)
 		return -EPERM;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	data.hdr.algo = evm_hash_algo;
+#else
+	data.hdr.algo = HASH_ALGO_SHA1;
+#endif
 	rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
 			   xattr_value_len, &data);
 	if (rc == 0) {
 		data.hdr.xattr.sha1.type = EVM_XATTR_HMAC;
 		rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM,
 					   &data.hdr.xattr.data[1],
+#ifdef CONFIG_IMA_DIGEST_LIST
 					   hash_digest_size[evm_hash_algo] + 1,
 					   0);
+#else
+					   SHA1_DIGEST_SIZE + 1, 0);
+#endif
 	} else if (rc == -ENODATA && (inode->i_opflags & IOP_XATTR)) {
 		rc = __vfs_removexattr(dentry, XATTR_NAME_EVM);
 	}
@@ -341,7 +367,11 @@ int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
 {
 	struct shash_desc *desc;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	desc = init_desc(EVM_XATTR_HMAC, evm_hash_algo);
+#else
+	desc = init_desc(EVM_XATTR_HMAC, HASH_ALGO_SHA1);
+#endif
 	if (IS_ERR(desc)) {
 		pr_info("init_desc failed\n");
 		return PTR_ERR(desc);
@@ -353,9 +383,15 @@ int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
 	return 0;
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 /*
  * Get the key from the TPM for the HMAC
  */
+#else
+/*
+ * Get the key from the TPM for the SHA1-HMAC
+ */
+#endif
 int evm_init_key(void)
 {
 	struct key *evm_key;
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index cddfc0e43a80..46d90da6169d 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -57,6 +57,7 @@ static struct xattr_list evm_config_default_xattrnames[] = {
 LIST_HEAD(evm_config_xattrnames);
 
 static int evm_fixmode __ro_after_init;
+#ifdef CONFIG_IMA_DIGEST_LIST
 static int __init evm_set_param(char *str)
 {
 	if (strncmp(str, "fix", 3) == 0)
@@ -73,6 +74,18 @@ static int __init evm_set_param(char *str)
 	return 1;
 }
 __setup("evm=", evm_set_param);
+#else
+static int __init evm_set_fixmode(char *str)
+{
+	if (strncmp(str, "fix", 3) == 0)
+		evm_fixmode = 1;
+	else
+		pr_err("invalid \"%s\" mode", str);
+
+	return 0;
+}
+__setup("evm=", evm_set_fixmode);
+#endif
 
 static void __init evm_init_config(void)
 {
@@ -98,6 +111,7 @@ static bool evm_key_loaded(void)
 	return (bool)(evm_initialized & EVM_KEY_MASK);
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 /*
  * Ignoring INTEGRITY_NOLABEL/INTEGRITY_NOXATTRS is safe if no HMAC key
  * is loaded and the EVM_SETUP_COMPLETE initialization flag is set.
@@ -115,8 +129,13 @@ static bool evm_ignore_error_safe(enum integrity_status evm_status)
 
 	return true;
 }
+#endif
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static int evm_find_protected_xattrs(struct dentry *dentry, int *ima_present)
+#else
+static int evm_find_protected_xattrs(struct dentry *dentry)
+#endif
 {
 	struct inode *inode = d_backing_inode(dentry);
 	struct xattr_list *xattr;
@@ -133,8 +152,10 @@ static int evm_find_protected_xattrs(struct dentry *dentry, int *ima_present)
 				continue;
 			return error;
 		}
+#ifdef CONFIG_IMA_DIGEST_LIST
 		if (!strcmp(xattr->name, XATTR_NAME_IMA))
 			*ima_present = 1;
+#endif
 		count++;
 	}
 
@@ -163,6 +184,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 	struct evm_ima_xattr_data *xattr_data = NULL;
 	struct signature_v2_hdr *hdr;
 	enum integrity_status evm_status = INTEGRITY_PASS;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	enum integrity_status saved_evm_status = INTEGRITY_UNKNOWN;
 	struct evm_digest digest;
 	struct ima_digest *found_digest;
@@ -172,6 +194,12 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 				.version = 2, .hash_algo = HASH_ALGO_SHA256 };
 	int rc, xattr_len, evm_immutable = 0, ima_present = 0;
 
+#else
+	struct evm_digest digest;
+	struct inode *inode;
+	int rc, xattr_len, evm_immutable = 0;;
+#endif
+
 	if (iint && (iint->evm_status == INTEGRITY_PASS ||
 		     iint->evm_status == INTEGRITY_PASS_IMMUTABLE))
 		return iint->evm_status;
@@ -184,7 +212,11 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 	if (rc <= 0) {
 		evm_status = INTEGRITY_FAIL;
 		if (rc == -ENODATA) {
+#ifdef CONFIG_IMA_DIGEST_LIST
 			rc = evm_find_protected_xattrs(dentry, &ima_present);
+#else
+			rc = evm_find_protected_xattrs(dentry);
+#endif
 			if (rc > 0)
 				evm_status = INTEGRITY_NOLABEL;
 			else if (rc == 0)
@@ -192,6 +224,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 		} else if (rc == -EOPNOTSUPP) {
 			evm_status = INTEGRITY_UNKNOWN;
 		}
+#ifdef CONFIG_IMA_DIGEST_LIST
 		/* IMA added a fake xattr, set also EVM fake xattr */
 		if (!ima_present && xattr_name &&
 		    !strcmp(xattr_name, XATTR_NAME_IMA) &&
@@ -206,6 +239,9 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 			goto out;
 
 		saved_evm_status = evm_status;
+#else
+		goto out;
+#endif
 	}
 
 	xattr_len = rc;
@@ -262,6 +298,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 			}
 		}
 		break;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	case EVM_IMA_XATTR_DIGEST_LIST:
 		/* At this point, we cannot determine whether metadata are
 		 * immutable or not. However, it is safe to return the
@@ -302,11 +339,13 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 			evm_status = INTEGRITY_PASS;
 		}
 		break;
+#endif
 	default:
 		rc = -EINVAL;
 		break;
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (rc && xattr_data == (struct evm_ima_xattr_data *)&evm_fake_xattr) {
 		evm_status = saved_evm_status;
 	} else if (rc) {
@@ -315,10 +354,22 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 			evm_status = evm_immutable ?
 				     INTEGRITY_FAIL_IMMUTABLE : INTEGRITY_FAIL;
 	}
+#else
+	if (rc) {
+		if (rc == -ENODATA)
+			evm_status = INTEGRITY_NOXATTRS;
+		else if (evm_immutable)
+			evm_status = INTEGRITY_FAIL_IMMUTABLE;
+		else
+			evm_status = INTEGRITY_FAIL;
+	}
+#endif
 out:
 	if (iint)
 		iint->evm_status = evm_status;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (xattr_data != (struct evm_ima_xattr_data *)&evm_fake_xattr)
+#endif
 		kfree(xattr_data);
 	return evm_status;
 }
@@ -569,8 +620,12 @@ int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name,
 		if (!xattr_value_len)
 			return -EINVAL;
 		if (xattr_data->type != EVM_IMA_XATTR_DIGSIG &&
+#ifdef CONFIG_IMA_DIGEST_LIST
 		    xattr_data->type != EVM_XATTR_PORTABLE_DIGSIG &&
 		    xattr_data->type != EVM_IMA_XATTR_DIGEST_LIST)
+#else
+		    xattr_data->type != EVM_XATTR_PORTABLE_DIGSIG)
+#endif
 			return -EPERM;
 	}
 	return evm_protect_xattr(dentry, xattr_name, xattr_value,
@@ -606,7 +661,7 @@ static void evm_reset_status(struct inode *inode)
 }
 
 /**
- * evm_status_revalidate - report whether EVM status re-validation is necessary
+ * evm_revalidate_status - report whether EVM status re-validation is necessary
  * @xattr_name: pointer to the affected extended attribute name
  *
  * Report whether callers of evm_verifyxattr() should re-validate the
@@ -614,7 +669,7 @@ static void evm_reset_status(struct inode *inode)
  *
  * Return true if re-validation is necessary, false otherwise.
  */
-bool evm_status_revalidate(const char *xattr_name)
+bool evm_revalidate_status(const char *xattr_name)
 {
 	if (!evm_key_loaded())
 		return false;
@@ -646,7 +701,7 @@ bool evm_status_revalidate(const char *xattr_name)
 void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
 			     const void *xattr_value, size_t xattr_value_len)
 {
-	if (!evm_status_revalidate(xattr_name))
+	if (!evm_revalidate_status(xattr_name))
 		return;
 
 	evm_reset_status(dentry->d_inode);
@@ -669,7 +724,7 @@ void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
  */
 void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
 {
-	if (!evm_status_revalidate(xattr_name))
+	if (!evm_revalidate_status(xattr_name))
 		return;
 
 	evm_reset_status(dentry->d_inode);
@@ -714,6 +769,7 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
 	if (!(ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)))
 		return 0;
 	evm_status = evm_verify_current_integrity(dentry);
+#ifdef CONFIG_IMA_DIGEST_LIST
 	/*
 	 * Writing attrs is safe for portable signatures, as portable signatures
 	 * are immutable and can never be updated.
@@ -723,6 +779,12 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
 	    (evm_status == INTEGRITY_FAIL_IMMUTABLE) ||
 	    (evm_ignore_error_safe(evm_status)))
 		return 0;
+#else
+	if ((evm_status == INTEGRITY_PASS) ||
+	    (evm_status == INTEGRITY_NOXATTRS) ||
+		(evm_status == INTEGRITY_FAIL_IMMUTABLE))
+		return 0;
+#endif
 
 	if (evm_status == INTEGRITY_PASS_IMMUTABLE &&
 	    !evm_attr_change(dentry, attr))
@@ -747,7 +809,7 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
  */
 void evm_inode_post_setattr(struct dentry *dentry, int ia_valid)
 {
-	if (!evm_status_revalidate(NULL))
+	if (!evm_revalidate_status(NULL))
 		return;
 
 	evm_reset_status(dentry->d_inode);
@@ -780,7 +842,9 @@ int evm_inode_init_security(struct inode *inode,
 		goto out;
 
 	evm_xattr->value = xattr_data;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	evm_xattr->value_len = hash_digest_size[evm_hash_algo] + 1;
+#endif
 	evm_xattr->name = XATTR_EVM_SUFFIX;
 	return 0;
 out:
@@ -802,6 +866,7 @@ void __init evm_load_x509(void)
 
 static int __init init_evm(void)
 {
+#ifdef CONFIG_IMA_DIGEST_LIST
 	int error, i;
 	struct list_head *pos, *q;
 
@@ -809,6 +874,10 @@ static int __init init_evm(void)
 			 CONFIG_EVM_DEFAULT_HASH);
 	if (i >= 0)
 		evm_hash_algo = i;
+#else
+	int error;
+	struct list_head *pos, *q;
+#endif
 
 	evm_init_config();
 
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index 8953ac6412c3..22dc1eb63f78 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -212,7 +212,9 @@ void __init integrity_load_keys(void)
 	if (!IS_ENABLED(CONFIG_IMA_LOAD_X509))
 		evm_load_x509();
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	ima_load_digest_lists();
+#endif
 }
 
 static int __init integrity_fs_init(void)
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 46afb6bef45b..e512a17b09dd 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -53,11 +53,11 @@ extern int ima_hash_algo_idx __ro_after_init;
 extern int ima_extra_slots __ro_after_init;
 extern int ima_appraise;
 extern struct tpm_chip *ima_tpm_chip;
+extern const char boot_aggregate_name[];
+#ifdef CONFIG_IMA_DIGEST_LIST
 extern int ima_digest_list_pcr;
 extern bool ima_plus_standard_pcr;
-extern const char boot_aggregate_name[];
 extern int ima_digest_list_actions;
-#ifdef CONFIG_IMA_DIGEST_LIST
 extern int ima_digest_db_max_size __ro_after_init;
 extern int ima_digest_db_size;
 #endif
@@ -189,6 +189,7 @@ static inline unsigned int ima_hash_key(u8 *digest)
 	return (digest[0] | digest[1] << 8) % IMA_MEASURE_HTABLE_SIZE;
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 #define __ima_hooks(hook)				\
 	hook(NONE, none)				\
 	hook(FILE_CHECK, file)				\
@@ -205,6 +206,23 @@ static inline unsigned int ima_hash_key(u8 *digest)
 	hook(KEY_CHECK, key)				\
 	hook(DIGEST_LIST_CHECK, digest_list)		\
 	hook(MAX_CHECK, none)
+#else
+#define __ima_hooks(hook)				\
+	hook(NONE, none)				\
+	hook(FILE_CHECK, file)				\
+	hook(MMAP_CHECK, mmap)				\
+	hook(BPRM_CHECK, bprm)				\
+	hook(CREDS_CHECK, creds)			\
+	hook(POST_SETATTR, post_setattr)		\
+	hook(MODULE_CHECK, module)			\
+	hook(FIRMWARE_CHECK, firmware)			\
+	hook(KEXEC_KERNEL_CHECK, kexec_kernel)		\
+	hook(KEXEC_INITRAMFS_CHECK, kexec_initramfs)	\
+	hook(POLICY_CHECK, policy)			\
+	hook(KEXEC_CMDLINE, kexec_cmdline)		\
+	hook(KEY_CHECK, key)				\
+	hook(MAX_CHECK, none)
+#endif
 
 #define __ima_hook_enumify(ENUM, str)	ENUM,
 #define __ima_stringify(arg) (#arg)
@@ -264,12 +282,20 @@ int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func);
 int ima_collect_measurement(struct integrity_iint_cache *iint,
 			    struct file *file, void *buf, loff_t size,
 			    enum hash_algo algo, struct modsig *modsig);
+#ifdef CONFIG_IMA_DIGEST_LIST
 void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
 			   const unsigned char *filename,
 			   struct evm_ima_xattr_data *xattr_value,
 			   int xattr_len, const struct modsig *modsig, int pcr,
 			   struct ima_template_desc *template_desc,
 			   struct ima_digest *digest);
+#else
+void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
+			   const unsigned char *filename,
+			   struct evm_ima_xattr_data *xattr_value,
+			   int xattr_len, const struct modsig *modsig, int pcr,
+			   struct ima_template_desc *template_desc);
+#endif
 void process_buffer_measurement(struct inode *inode, const void *buf, int size,
 				const char *eventname, enum ima_hooks func,
 				int pcr, const char *keyring);
@@ -278,9 +304,15 @@ void ima_audit_measurement(struct integrity_iint_cache *iint,
 int ima_alloc_init_template(struct ima_event_data *event_data,
 			    struct ima_template_entry **entry,
 			    struct ima_template_desc *template_desc);
+#ifdef CONFIG_IMA_DIGEST_LIST
 int ima_store_template(struct ima_template_entry *entry, int violation,
 		       struct inode *inode, const unsigned char *filename,
 		       int pcr, struct ima_digest *digest);
+#else
+int ima_store_template(struct ima_template_entry *entry, int violation,
+		       struct inode *inode,
+		       const unsigned char *filename, int pcr);
+#endif
 void ima_free_template_entry(struct ima_template_entry *entry);
 const char *ima_d_path(const struct path *path, char **pathbuf, char *filename);
 
@@ -308,21 +340,41 @@ int ima_policy_show(struct seq_file *m, void *v);
 #define IMA_APPRAISE_FIRMWARE	0x10
 #define IMA_APPRAISE_POLICY	0x20
 #define IMA_APPRAISE_KEXEC	0x40
+#ifdef CONFIG_IMA_DIGEST_LIST
 #define IMA_APPRAISE_DIGEST_LIST	0x80
+#endif
 
 #ifdef CONFIG_IMA_APPRAISE
 int ima_check_blacklist(struct integrity_iint_cache *iint,
 			const struct modsig *modsig, int pcr);
+
+#ifdef CONFIG_IMA_DIGEST_LIST
 int ima_appraise_measurement(enum ima_hooks func,
 			     struct integrity_iint_cache *iint,
 			     struct file *file, const unsigned char *filename,
 			     struct evm_ima_xattr_data *xattr_value,
 			     int xattr_len, const struct modsig *modsig,
 			     struct ima_digest *found_digest);
+#else
+int ima_appraise_measurement(enum ima_hooks func,
+			     struct integrity_iint_cache *iint,
+			     struct file *file, const unsigned char *filename,
+			     struct evm_ima_xattr_data *xattr_value,
+			     int xattr_len, const struct modsig *modsig);
+#endif
+
 int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func);
 void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
 enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
 					   enum ima_hooks func);
+
+#ifndef CONFIG_IMA_DIGEST_LIST
+enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
+				 int xattr_len);
+int ima_read_xattr(struct dentry *dentry,
+		   struct evm_ima_xattr_data **xattr_value);
+#endif
+
 #else
 static inline int ima_check_blacklist(struct integrity_iint_cache *iint,
 				      const struct modsig *modsig, int pcr)
@@ -330,6 +382,7 @@ static inline int ima_check_blacklist(struct integrity_iint_cache *iint,
 	return 0;
 }
 
+#ifndef CONFIG_IMA_DIGEST_LIST
 static inline int ima_appraise_measurement(enum ima_hooks func,
 					   struct integrity_iint_cache *iint,
 					   struct file *file,
@@ -338,6 +391,15 @@ static inline int ima_appraise_measurement(enum ima_hooks func,
 					   int xattr_len,
 					   const struct modsig *modsig,
 					   struct ima_digest *found_digest)
+#else
+static inline int ima_appraise_measurement(enum ima_hooks func,
+					   struct integrity_iint_cache *iint,
+					   struct file *file,
+					   const unsigned char *filename,
+					   struct evm_ima_xattr_data *xattr_value,
+					   int xattr_len,
+					   const struct modsig *modsig)
+#endif
 {
 	return INTEGRITY_UNKNOWN;
 }
@@ -360,6 +422,20 @@ static inline enum integrity_status ima_get_cache_status(struct integrity_iint_c
 	return INTEGRITY_UNKNOWN;
 }
 
+#ifndef CONFIG_IMA_DIGEST_LIST
+static inline enum hash_algo
+ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len)
+{
+	return ima_hash_algo;
+}
+
+static inline int ima_read_xattr(struct dentry *dentry,
+				 struct evm_ima_xattr_data **xattr_value)
+{
+	return 0;
+}
+#endif
+
 #endif /* CONFIG_IMA_APPRAISE */
 
 #ifdef CONFIG_IMA_APPRAISE_MODSIG
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 6ecaf6834844..1b8d3696d873 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -99,15 +99,23 @@ int ima_alloc_init_template(struct ima_event_data *event_data,
  *
  * Returns 0 on success, error code otherwise
  */
+#ifdef CONFIG_IMA_DIGEST_LIST
 int ima_store_template(struct ima_template_entry *entry,
 		       int violation, struct inode *inode,
 		       const unsigned char *filename, int pcr,
 		       struct ima_digest *digest)
+#else
+int ima_store_template(struct ima_template_entry *entry,
+		       int violation, struct inode *inode,
+		       const unsigned char *filename, int pcr)
+#endif
 {
 	static const char op[] = "add_template_measure";
 	static const char audit_cause[] = "hashing_error";
 	char *template_name = entry->template_desc->name;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	struct ima_template_entry *duplicated_entry = NULL;
+#endif
 	int result;
 
 	if (!violation) {
@@ -121,6 +129,7 @@ int ima_store_template(struct ima_template_entry *entry,
 		}
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (ima_plus_standard_pcr && !digest) {
 		duplicated_entry = kmemdup(entry,
 			sizeof(*entry) + entry->template_desc->num_fields *
@@ -130,9 +139,11 @@ int ima_store_template(struct ima_template_entry *entry,
 	} else if (!ima_plus_standard_pcr && ima_digest_list_pcr >= 0) {
 		pcr = ima_digest_list_pcr;
 	}
+#endif
 
 	entry->pcr = pcr;
 	result = ima_add_template_entry(entry, violation, op, inode, filename);
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (result) {
 		kfree(duplicated_entry);
 	} else if (duplicated_entry) {
@@ -141,6 +152,7 @@ int ima_store_template(struct ima_template_entry *entry,
 		if (result < 0)
 			kfree(duplicated_entry);
 	}
+#endif
 
 	return result;
 }
@@ -173,8 +185,13 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
 		result = -ENOMEM;
 		goto err_out;
 	}
+#ifdef CONFIG_IMA_DIGEST_LIST
 	result = ima_store_template(entry, violation, inode, filename,
 				    CONFIG_IMA_MEASURE_PCR_IDX, NULL);
+#else
+	result = ima_store_template(entry, violation, inode,
+				    filename, CONFIG_IMA_MEASURE_PCR_IDX);
+#endif
 	if (result < 0)
 		ima_free_template_entry(entry);
 err_out:
@@ -315,18 +332,30 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
  *
  * Must be called with iint->mutex held.
  */
+#ifdef CONFIG_IMA_DIGEST_LIST
 void ima_store_measurement(struct integrity_iint_cache *iint,
 			   struct file *file, const unsigned char *filename,
 			   struct evm_ima_xattr_data *xattr_value,
 			   int xattr_len, const struct modsig *modsig, int pcr,
 			   struct ima_template_desc *template_desc,
 			   struct ima_digest *digest)
+#else
+void ima_store_measurement(struct integrity_iint_cache *iint,
+			   struct file *file, const unsigned char *filename,
+			   struct evm_ima_xattr_data *xattr_value,
+			   int xattr_len, const struct modsig *modsig, int pcr,
+			   struct ima_template_desc *template_desc)
+#endif
 {
 	static const char op[] = "add_template_measure";
 	static const char audit_cause[] = "ENOMEM";
 	int result = -ENOMEM;
 	struct inode *inode = file_inode(file);
+#ifdef CONFIG_IMA_DIGEST_LIST
 	struct ima_template_entry *entry = NULL;
+#else
+	struct ima_template_entry *entry;
+#endif
 	struct ima_event_data event_data = { .iint = iint,
 					     .file = file,
 					     .filename = filename,
@@ -344,10 +373,12 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
 	if (iint->measured_pcrs & (0x1 << pcr) && !modsig)
 		return;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (digest && !ima_plus_standard_pcr && ima_digest_list_pcr >= 0) {
 		result = -EEXIST;
 		goto out;
 	}
+#endif
 
 	result = ima_alloc_init_template(&event_data, &entry, template_desc);
 	if (result < 0) {
@@ -356,14 +387,22 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
 		return;
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	result = ima_store_template(entry, violation, inode, filename, pcr,
 				    digest);
 out:
+#else
+	result = ima_store_template(entry, violation, inode, filename, pcr);
+#endif
 	if ((!result || result == -EEXIST) && !(file->f_flags & O_DIRECT)) {
 		iint->flags |= IMA_MEASURED;
 		iint->measured_pcrs |= (0x1 << pcr);
 	}
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (result < 0 && entry)
+#else
+	if (result < 0)
+#endif
 		ima_free_template_entry(entry);
 }
 
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 956fb0f4c006..000b4c338ba4 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -15,9 +15,11 @@
 #include <keys/system_keyring.h>
 
 #include "ima.h"
+#ifdef CONFIG_IMA_DIGEST_LIST
 #include "ima_digest_list.h"
 
 static bool ima_appraise_req_evm __ro_after_init;
+#endif
 static int __init default_appraise_setup(char *str)
 {
 #ifdef CONFIG_IMA_APPRAISE_BOOTPARAM
@@ -45,16 +47,18 @@ static int __init default_appraise_setup(char *str)
 		ima_appraise = appraisal_state;
 	}
 #endif
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (strcmp(str, "enforce-evm") == 0 ||
 	    strcmp(str, "log-evm") == 0)
 		ima_appraise_req_evm = true;
+#endif
 	return 1;
 }
 
 __setup("ima_appraise=", default_appraise_setup);
 
-static bool ima_appraise_no_metadata __ro_after_init;
 #ifdef CONFIG_IMA_DIGEST_LIST
+static bool ima_appraise_no_metadata __ro_after_init;
 static int __init appraise_digest_list_setup(char *str)
 {
 	if (!strncmp(str, "digest", 6)) {
@@ -108,9 +112,11 @@ static int ima_fix_xattr(struct dentry *dentry,
 	} else {
 		offset = 0;
 		iint->ima_hash->xattr.ng.type = IMA_XATTR_DIGEST_NG;
+#ifdef CONFIG_IMA_DIGEST_LIST
 		if (test_bit(IMA_DIGEST_LIST, &iint->atomic_flags))
 			iint->ima_hash->xattr.ng.type =
 						EVM_IMA_XATTR_DIGEST_LIST;
+#endif
 		iint->ima_hash->xattr.ng.algo = algo;
 	}
 	rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA,
@@ -189,6 +195,60 @@ static void ima_cache_flags(struct integrity_iint_cache *iint,
 	}
 }
 
+#ifndef CONFIG_IMA_DIGEST_LIST
+enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
+				 int xattr_len)
+{
+	struct signature_v2_hdr *sig;
+	enum hash_algo ret;
+
+	if (!xattr_value || xattr_len < 2)
+		/* return default hash algo */
+		return ima_hash_algo;
+
+	switch (xattr_value->type) {
+	case EVM_IMA_XATTR_DIGSIG:
+		sig = (typeof(sig))xattr_value;
+		if (sig->version != 2 || xattr_len <= sizeof(*sig))
+			return ima_hash_algo;
+		return sig->hash_algo;
+		break;
+	case IMA_XATTR_DIGEST_NG:
+		/* first byte contains algorithm id */
+		ret = xattr_value->data[0];
+		if (ret < HASH_ALGO__LAST)
+			return ret;
+		break;
+	case IMA_XATTR_DIGEST:
+		/* this is for backward compatibility */
+		if (xattr_len == 21) {
+			unsigned int zero = 0;
+			if (!memcmp(&xattr_value->data[16], &zero, 4))
+				return HASH_ALGO_MD5;
+			else
+				return HASH_ALGO_SHA1;
+		} else if (xattr_len == 17)
+			return HASH_ALGO_MD5;
+		break;
+	}
+
+	/* return default hash algo */
+	return ima_hash_algo;
+}
+
+int ima_read_xattr(struct dentry *dentry,
+		   struct evm_ima_xattr_data **xattr_value)
+{
+	ssize_t ret;
+
+	ret = vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)xattr_value,
+				 0, GFP_NOFS);
+	if (ret == -EOPNOTSUPP)
+		ret = 0;
+	return ret;
+}
+#endif
+
 /*
  * xattr_verify - verify xattr digest or signature
  *
@@ -196,18 +256,27 @@ static void ima_cache_flags(struct integrity_iint_cache *iint,
  *
  * Return 0 on success, error code otherwise.
  */
+#ifdef CONFIG_IMA_DIGEST_LIST
 static int xattr_verify(enum ima_hooks func, struct integrity_iint_cache *iint,
 			struct evm_ima_xattr_data *xattr_value, int xattr_len,
 			enum integrity_status *status, const char **cause,
 			struct ima_digest *found_digest)
+#else
+static int xattr_verify(enum ima_hooks func, struct integrity_iint_cache *iint,
+			struct evm_ima_xattr_data *xattr_value, int xattr_len,
+			enum integrity_status *status, const char **cause)
+#endif
 {
 	int rc = -EINVAL, hash_start = 0;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (found_digest && *status != INTEGRITY_PASS &&
 	    *status != INTEGRITY_PASS_IMMUTABLE)
 		set_bit(IMA_DIGEST_LIST, &iint->atomic_flags);
+#endif
 
 	switch (xattr_value->type) {
+#ifdef CONFIG_IMA_DIGEST_LIST
 	case EVM_IMA_XATTR_DIGEST_LIST:
 		set_bit(IMA_DIGEST_LIST, &iint->atomic_flags);
 
@@ -217,13 +286,18 @@ static int xattr_verify(enum ima_hooks func, struct integrity_iint_cache *iint,
 			break;
 		}
 		fallthrough;
+#endif
 	case IMA_XATTR_DIGEST_NG:
 		/* first byte contains algorithm id */
 		hash_start = 1;
 		fallthrough;
 	case IMA_XATTR_DIGEST:
+#ifdef CONFIG_IMA_DIGEST_LIST
 		if (*status != INTEGRITY_PASS_IMMUTABLE &&
 		    (!found_digest || !ima_digest_is_immutable(found_digest))) {
+#else
+		if (*status != INTEGRITY_PASS_IMMUTABLE) {
+#endif
 			if (iint->flags & IMA_DIGSIG_REQUIRED) {
 				*cause = "IMA-signature-required";
 				*status = INTEGRITY_FAIL;
@@ -352,26 +426,39 @@ int ima_check_blacklist(struct integrity_iint_cache *iint,
  *
  * Return 0 on success, error code otherwise
  */
+#ifdef CONFIG_IMA_DIGEST_LIST
 int ima_appraise_measurement(enum ima_hooks func,
 			     struct integrity_iint_cache *iint,
 			     struct file *file, const unsigned char *filename,
 			     struct evm_ima_xattr_data *xattr_value,
 			     int xattr_len, const struct modsig *modsig,
 			     struct ima_digest *found_digest)
+#else
+int ima_appraise_measurement(enum ima_hooks func,
+			     struct integrity_iint_cache *iint,
+			     struct file *file, const unsigned char *filename,
+			     struct evm_ima_xattr_data *xattr_value,
+			     int xattr_len, const struct modsig *modsig)
+#endif
 {
 	static const char op[] = "appraise_data";
 	const char *cause = "unknown";
 	struct dentry *dentry = file_dentry(file);
 	struct inode *inode = d_backing_inode(dentry);
 	enum integrity_status status = INTEGRITY_UNKNOWN;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	int rc = xattr_len, rc_evm;
 	char _buf[sizeof(struct evm_ima_xattr_data) + 1 + SHA512_DIGEST_SIZE];
+#else
+	int rc = xattr_len;
+#endif
 	bool try_modsig = iint->flags & IMA_MODSIG_ALLOWED && modsig;
 
 	/* If not appraising a modsig, we need an xattr. */
 	if (!(inode->i_opflags & IOP_XATTR) && !try_modsig)
 		return INTEGRITY_UNKNOWN;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (xattr_value && xattr_value->type == EVM_IMA_XATTR_DIGSIG &&
 	    xattr_len == sizeof(struct signature_v2_hdr))
 		rc = -ENODATA;
@@ -394,6 +481,7 @@ int ima_appraise_measurement(enum ima_hooks func,
 			rc = xattr_len;
 		}
 	}
+#endif
 
 	/* If reading the xattr failed and there's no modsig, error out. */
 	if (rc <= 0 && !try_modsig) {
@@ -417,11 +505,15 @@ int ima_appraise_measurement(enum ima_hooks func,
 	switch (status) {
 	case INTEGRITY_PASS:
 	case INTEGRITY_PASS_IMMUTABLE:
+#ifdef CONFIG_IMA_DIGEST_LIST
 		break;
 	case INTEGRITY_UNKNOWN:
 		if (ima_appraise_req_evm &&
 		    xattr_value->type != EVM_IMA_XATTR_DIGSIG && !found_digest)
 			goto out;
+#else
+	case INTEGRITY_UNKNOWN:
+#endif
 		break;
 	case INTEGRITY_NOXATTRS:	/* No EVM protected xattrs. */
 		/* It's fine not to have xattrs when using a modsig. */
@@ -429,6 +521,7 @@ int ima_appraise_measurement(enum ima_hooks func,
 			break;
 		fallthrough;
 	case INTEGRITY_NOLABEL:		/* No security.evm xattr. */
+#ifdef CONFIG_IMA_DIGEST_LIST
 		/*
 		 * If the digest-nometadata mode is selected, allow access
 		 * without metadata check. EVM will eventually create an HMAC
@@ -446,6 +539,7 @@ int ima_appraise_measurement(enum ima_hooks func,
 			    ima_digest_is_immutable(found_digest))
 				break;
 		}
+#endif
 		cause = "missing-HMAC";
 		goto out;
 	case INTEGRITY_FAIL_IMMUTABLE:
@@ -458,6 +552,7 @@ int ima_appraise_measurement(enum ima_hooks func,
 		WARN_ONCE(true, "Unexpected integrity status %d\n", status);
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if ((iint->flags & IMA_META_IMMUTABLE_REQUIRED) &&
 	    status != INTEGRITY_PASS_IMMUTABLE) {
 		status = INTEGRITY_FAIL;
@@ -466,10 +561,16 @@ int ima_appraise_measurement(enum ima_hooks func,
 				    filename, op, cause, rc, 0);
 		goto out;
 	}
+#endif
 
 	if (xattr_value)
+#ifdef CONFIG_IMA_DIGEST_LIST
 		rc = xattr_verify(func, iint, xattr_value, xattr_len, &status,
 				  &cause, found_digest);
+#else
+		rc = xattr_verify(func, iint, xattr_value, xattr_len, &status,
+				  &cause);
+#endif
 
 	/*
 	 * If we have a modsig and either no imasig or the imasig's key isn't
@@ -609,6 +710,7 @@ static void ima_reset_appraise_flags(struct inode *inode, int digsig)
 		clear_bit(IMA_DIGSIG, &iint->atomic_flags);
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
 		       const void *xattr_value, size_t xattr_value_len)
 {
@@ -624,7 +726,35 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
 	}
 	return result;
 }
+#else
+int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
+		       const void *xattr_value, size_t xattr_value_len)
+{
+	const struct evm_ima_xattr_data *xvalue = xattr_value;
+	int digsig = 0;
+	int result;
 
+	result = ima_protect_xattr(dentry, xattr_name, xattr_value,
+				   xattr_value_len);
+	if (result == 1) {
+		if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST))
+			return -EINVAL;
+		digsig = (xvalue->type == EVM_IMA_XATTR_DIGSIG);
+#ifndef CONFIG_IMA_DIGEST_LIST
+	} else if (!strcmp(xattr_name, XATTR_NAME_EVM) && xattr_value_len > 0) {
+		digsig = (xvalue->type == EVM_XATTR_PORTABLE_DIGSIG);
+#endif
+	}
+	if (result == 1 || evm_revalidate_status(xattr_name)) {
+		ima_reset_appraise_flags(d_backing_inode(dentry), digsig);
+		if (result == 1)
+			result = 0;
+	}
+	return result;
+}
+#endif
+
+#ifdef CONFIG_IMA_DIGEST_LIST
 void ima_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
 			     const void *xattr_value, size_t xattr_value_len)
 {
@@ -638,10 +768,12 @@ void ima_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
 		digsig = (xvalue->type == EVM_IMA_XATTR_DIGSIG);
 	if (!strcmp(xattr_name, XATTR_NAME_EVM) && xattr_value_len > 0)
 		digsig = (xvalue->type == EVM_XATTR_PORTABLE_DIGSIG);
-	if (result == 1 || evm_status_revalidate(xattr_name))
+	if (result == 1 || evm_revalidate_status(xattr_name))
 		ima_reset_appraise_flags(d_backing_inode(dentry), digsig);
 }
+#endif
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name)
 {
 	int result;
@@ -652,12 +784,28 @@ int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name)
 	}
 	return result;
 }
+#else
+int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name)
+{
+	int result;
 
+	result = ima_protect_xattr(dentry, xattr_name, NULL, 0);
+	if (result == 1 || evm_revalidate_status(xattr_name)) {
+		ima_reset_appraise_flags(d_backing_inode(dentry), 0);
+		if (result == 1)
+			result = 0;
+	}
+	return result;
+}
+#endif
+
+#ifdef CONFIG_IMA_DIGEST_LIST
 void ima_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
 {
 	int result;
 
 	result = ima_protect_xattr(dentry, xattr_name, NULL, 0);
-	if (result == 1 || evm_status_revalidate(xattr_name))
+	if (result == 1 || evm_revalidate_status(xattr_name))
 		ima_reset_appraise_flags(d_backing_inode(dentry), 0);
 }
+#endif
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index f1bc3e201bd8..4ceee381d58b 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -21,11 +21,15 @@
 #include <linux/rcupdate.h>
 #include <linux/parser.h>
 #include <linux/vmalloc.h>
+#ifdef CONFIG_IMA_DIGEST_LIST
 #include <linux/file.h>
+#endif
 #include <linux/ctype.h>
 
 #include "ima.h"
+#ifdef CONFIG_IMA_DIGEST_LIST
 #include "ima_digest_list.h"
+#endif
 
 static DEFINE_MUTEX(ima_write_mutex);
 
@@ -36,9 +40,11 @@ static struct dentry *ascii_runtime_measurements;
 static struct dentry *runtime_measurements_count;
 static struct dentry *violations;
 static struct dentry *ima_policy;
+#ifdef CONFIG_IMA_DIGEST_LIST
 static struct dentry *digests_count;
 static struct dentry *digest_list_data;
 static struct dentry *digest_list_data_del;
+#endif
 
 bool ima_canonical_fmt;
 static int __init default_canonical_fmt_setup(char *str)
@@ -52,6 +58,7 @@ __setup("ima_canonical_fmt", default_canonical_fmt_setup);
 
 static int valid_policy = 1;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static ssize_t ima_show_htable_value(struct file *filp, char __user *buf,
 				     size_t count, loff_t *ppos)
 {
@@ -63,19 +70,54 @@ static ssize_t ima_show_htable_value(struct file *filp, char __user *buf,
 		val = &ima_htable.violations;
 	else if (filp->f_path.dentry == runtime_measurements_count)
 		val = &ima_htable.len;
-#ifdef CONFIG_IMA_DIGEST_LIST
 	else if (filp->f_path.dentry == digests_count)
 		val = &ima_digests_htable.len;
-#endif
 
 	len = scnprintf(tmpbuf, sizeof(tmpbuf), "%li\n", atomic_long_read(val));
 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, len);
 }
+#else
+static ssize_t ima_show_htable_value(char __user *buf, size_t count,
+				     loff_t *ppos, atomic_long_t *val)
+{
+	char tmpbuf[32];	/* greater than largest 'long' string value */
+	ssize_t len;
+	len = scnprintf(tmpbuf, sizeof(tmpbuf), "%li\n", atomic_long_read(val));
+	return simple_read_from_buffer(buf, count, ppos, tmpbuf, len);
+}
+#endif
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static const struct file_operations ima_htable_value_ops = {
 	.read = ima_show_htable_value,
 	.llseek = generic_file_llseek,
 };
+#else
+static ssize_t ima_show_htable_violations(struct file *filp,
+					  char __user *buf,
+					  size_t count, loff_t *ppos)
+{
+	return ima_show_htable_value(buf, count, ppos, &ima_htable.violations);
+}
+
+static const struct file_operations ima_htable_violations_ops = {
+	.read = ima_show_htable_violations,
+	.llseek = generic_file_llseek,
+};
+
+static ssize_t ima_show_measurements_count(struct file *filp,
+					   char __user *buf,
+					   size_t count, loff_t *ppos)
+{
+	return ima_show_htable_value(buf, count, ppos, &ima_htable.len);
+
+}
+
+static const struct file_operations ima_measurements_count_ops = {
+	.read = ima_show_measurements_count,
+	.llseek = generic_file_llseek,
+};
+#endif
 
 /* returns pointer to hlist_node */
 static void *ima_measurements_start(struct seq_file *m, loff_t *pos)
@@ -275,6 +317,7 @@ static const struct file_operations ima_ascii_measurements_ops = {
 	.release = seq_release,
 };
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static ssize_t ima_read_file(char *path, struct dentry *dentry)
 {
 	void *data = NULL;
@@ -320,7 +363,6 @@ static ssize_t ima_read_file(char *path, struct dentry *dentry)
 			rc = ima_parse_add_rule(p);
 		} else if (dentry == digest_list_data ||
 			   dentry == digest_list_data_del) {
-#ifdef CONFIG_IMA_DIGEST_LIST
 			/* Only check size when adding digest lists */
 			if (dentry == digest_list_data &&
 			    size > ima_digest_db_max_size - ima_digest_db_size) {
@@ -328,7 +370,6 @@ static ssize_t ima_read_file(char *path, struct dentry *dentry)
 				rc = -ENOMEM;
 				break;
 			}
-#endif
 			/*
 			 * Disable usage of digest lists if not measured
 			 * or appraised.
@@ -343,12 +384,10 @@ static ssize_t ima_read_file(char *path, struct dentry *dentry)
 
 		if (rc < 0)
 			break;
-#ifdef CONFIG_IMA_DIGEST_LIST
 		else if (dentry == digest_list_data)
 			pr_debug("digest imported, current DB size: %d\n", ima_digest_db_size);
 		else if (dentry == digest_list_data_del)
 			pr_debug("digest deleted, current DB size: %d\n", ima_digest_db_size);
-#endif
 		size -= rc;
 	}
 
@@ -461,6 +500,104 @@ static enum ima_fs_flags ima_get_dentry_flag(struct dentry *dentry)
 
 	return flag;
 }
+#else
+static ssize_t ima_read_policy(char *path)
+{
+	void *data = NULL;
+	char *datap;
+	size_t size;
+	int rc, pathlen = strlen(path);
+
+	char *p;
+
+	/* remove \n */
+	datap = path;
+	strsep(&datap, "\n");
+
+	rc = kernel_read_file_from_path(path, 0, &data, INT_MAX, NULL,
+					READING_POLICY);
+	if (rc < 0) {
+		pr_err("Unable to open file: %s (%d)", path, rc);
+		return rc;
+	}
+	size = rc;
+	rc = 0;
+
+	datap = data;
+	while (size > 0 && (p = strsep(&datap, "\n"))) {
+		pr_debug("rule: %s\n", p);
+		rc = ima_parse_add_rule(p);
+		if (rc < 0)
+			break;
+		size -= rc;
+	}
+
+	vfree(data);
+	if (rc < 0)
+		return rc;
+	else if (size)
+		return -EINVAL;
+	else
+		return pathlen;
+}
+
+static ssize_t ima_write_policy(struct file *file, const char __user *buf,
+				size_t datalen, loff_t *ppos)
+{
+	char *data;
+	ssize_t result;
+
+	if (datalen >= PAGE_SIZE)
+		datalen = PAGE_SIZE - 1;
+
+	/* No partial writes. */
+	result = -EINVAL;
+	if (*ppos != 0)
+		goto out;
+
+	data = memdup_user_nul(buf, datalen);
+	if (IS_ERR(data)) {
+		result = PTR_ERR(data);
+		goto out;
+	}
+
+	result = mutex_lock_interruptible(&ima_write_mutex);
+	if (result < 0)
+		goto out_free;
+
+	if (data[0] == '/') {
+		result = ima_read_policy(data);
+	} else if (ima_appraise & IMA_APPRAISE_POLICY) {
+		pr_err("signed policy file (specified as an absolute pathname) required\n");
+		integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
+				    "policy_update", "signed policy required",
+				    1, 0);
+		result = -EACCES;
+	} else {
+		result = ima_parse_add_rule(data);
+	}
+	mutex_unlock(&ima_write_mutex);
+out_free:
+	kfree(data);
+out:
+	if (result < 0)
+		valid_policy = 0;
+
+	return result;
+}
+
+static struct dentry *ima_dir;
+static struct dentry *ima_symlink;
+static struct dentry *binary_runtime_measurements;
+static struct dentry *ascii_runtime_measurements;
+static struct dentry *runtime_measurements_count;
+static struct dentry *violations;
+static struct dentry *ima_policy;
+
+enum ima_fs_flags {
+	IMA_FS_BUSY,
+};
+#endif
 
 static unsigned long ima_fs_flags;
 
@@ -473,6 +610,7 @@ static const struct seq_operations ima_policy_seqops = {
 };
 #endif
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 /*
  * ima_open_data_upload: sequentialize access to the data upload interface
  */
@@ -568,6 +706,79 @@ static const struct file_operations ima_data_upload_ops = {
 	.release = ima_release_data_upload,
 	.llseek = generic_file_llseek,
 };
+#else
+/*
+ * ima_open_policy: sequentialize access to the policy file
+ */
+static int ima_open_policy(struct inode *inode, struct file *filp)
+{
+	if (!(filp->f_flags & O_WRONLY)) {
+#ifndef	CONFIG_IMA_READ_POLICY
+		return -EACCES;
+#else
+		if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
+			return -EACCES;
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+		return seq_open(filp, &ima_policy_seqops);
+#endif
+	}
+	if (test_and_set_bit(IMA_FS_BUSY, &ima_fs_flags))
+		return -EBUSY;
+	return 0;
+}
+
+/*
+ * ima_release_policy - start using the new measure policy rules.
+ *
+ * Initially, ima_measure points to the default policy rules, now
+ * point to the new policy rules, and remove the securityfs policy file,
+ * assuming a valid policy.
+ */
+static int ima_release_policy(struct inode *inode, struct file *file)
+{
+	const char *cause = valid_policy ? "completed" : "failed";
+
+	if ((file->f_flags & O_ACCMODE) == O_RDONLY)
+		return seq_release(inode, file);
+
+	if (valid_policy && ima_check_policy() < 0) {
+		cause = "failed";
+		valid_policy = 0;
+	}
+
+	pr_info("policy update %s\n", cause);
+	integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
+			    "policy_update", cause, !valid_policy, 0);
+
+	if (!valid_policy) {
+		ima_delete_rules();
+		valid_policy = 1;
+		clear_bit(IMA_FS_BUSY, &ima_fs_flags);
+		return 0;
+	}
+
+	ima_update_policy();
+#if !defined(CONFIG_IMA_WRITE_POLICY) && !defined(CONFIG_IMA_READ_POLICY)
+	securityfs_remove(ima_policy);
+	ima_policy = NULL;
+#elif defined(CONFIG_IMA_WRITE_POLICY)
+	clear_bit(IMA_FS_BUSY, &ima_fs_flags);
+#elif defined(CONFIG_IMA_READ_POLICY)
+	inode->i_mode &= ~S_IWUSR;
+#endif
+	return 0;
+}
+
+static const struct file_operations ima_measure_policy_ops = {
+	.open = ima_open_policy,
+	.write = ima_write_policy,
+	.read = seq_read,
+	.release = ima_release_policy,
+	.llseek = generic_file_llseek,
+};
+
+#endif
 
 int __init ima_fs_init(void)
 {
@@ -594,6 +805,7 @@ int __init ima_fs_init(void)
 	if (IS_ERR(ascii_runtime_measurements))
 		goto out;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	runtime_measurements_count =
 	    securityfs_create_file("runtime_measurements_count",
 				   S_IRUSR | S_IRGRP, ima_dir, NULL,
@@ -613,7 +825,6 @@ int __init ima_fs_init(void)
 	if (IS_ERR(ima_policy))
 		goto out;
 
-#ifdef CONFIG_IMA_DIGEST_LIST
 	digests_count = securityfs_create_file("digests_count",
 					       S_IRUSR | S_IRGRP, ima_dir,
 					       NULL, &ima_htable_value_ops);
@@ -631,12 +842,34 @@ int __init ima_fs_init(void)
 						      &ima_data_upload_ops);
 	if (IS_ERR(digest_list_data_del))
 		goto out;
+#else
+	runtime_measurements_count =
+	    securityfs_create_file("runtime_measurements_count",
+				   S_IRUSR | S_IRGRP, ima_dir, NULL,
+				   &ima_measurements_count_ops);
+	if (IS_ERR(runtime_measurements_count))
+		goto out;
+
+	violations =
+	    securityfs_create_file("violations", S_IRUSR | S_IRGRP,
+				   ima_dir, NULL, &ima_htable_violations_ops);
+	if (IS_ERR(violations))
+		goto out;
+
+	ima_policy = securityfs_create_file("policy", POLICY_FILE_FLAGS,
+					    ima_dir, NULL,
+					    &ima_measure_policy_ops);
+	if (IS_ERR(ima_policy))
+		goto out;
+
 #endif
 	return 0;
 out:
+#ifdef CONFIG_IMA_DIGEST_LIST
 	securityfs_remove(digest_list_data_del);
 	securityfs_remove(digest_list_data);
 	securityfs_remove(digests_count);
+#endif
 	securityfs_remove(ima_policy);
 	securityfs_remove(violations);
 	securityfs_remove(runtime_measurements_count);
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index 913d6b879b0b..da47d366a98c 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -84,9 +84,15 @@ static int __init ima_add_boot_aggregate(void)
 		goto err_out;
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	result = ima_store_template(entry, violation, NULL,
 				    boot_aggregate_name,
 				    CONFIG_IMA_MEASURE_PCR_IDX, NULL);
+#else
+	result = ima_store_template(entry, violation, NULL,
+				    boot_aggregate_name,
+				    CONFIG_IMA_MEASURE_PCR_IDX);
+#endif
 	if (result < 0) {
 		ima_free_template_entry(entry);
 		audit_cause = "store_entry";
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 999d5904cce0..fc1af21b3ad8 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -28,7 +28,9 @@
 #include <linux/fs.h>
 
 #include "ima.h"
+#ifdef CONFIG_IMA_DIGEST_LIST
 #include "ima_digest_list.h"
+#endif
 
 #ifdef CONFIG_IMA_APPRAISE
 int ima_appraise = IMA_APPRAISE_ENFORCE;
@@ -38,12 +40,14 @@ int ima_appraise;
 
 int ima_hash_algo = HASH_ALGO_SHA1;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 /* Actions (measure/appraisal) for which digest lists can be used */
 int ima_digest_list_actions;
 /* PCR used for digest list measurements */
 int ima_digest_list_pcr = -1;
 /* Flag to include standard measurement if digest list PCR is specified */
 bool ima_plus_standard_pcr;
+#endif
 
 static int hash_setup_done;
 
@@ -156,6 +160,7 @@ static void ima_rdwr_violation_check(struct file *file,
 				  "invalid_pcr", "open_writers");
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
 					int xattr_len)
 {
@@ -209,6 +214,7 @@ static int ima_read_xattr(struct dentry *dentry,
 		ret = 0;
 	return ret;
 }
+#endif
 
 static void ima_check_last_writer(struct integrity_iint_cache *iint,
 				  struct inode *inode, struct file *file)
@@ -268,7 +274,9 @@ static int process_measurement(struct file *file, const struct cred *cred,
 	const char *pathname = NULL;
 	int rc = 0, action, must_appraise = 0;
 	int pcr = CONFIG_IMA_MEASURE_PCR_IDX;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	struct ima_digest *found_digest;
+#endif
 	struct evm_ima_xattr_data *xattr_value = NULL;
 	struct modsig *modsig = NULL;
 	int xattr_len = 0;
@@ -398,28 +406,42 @@ static int process_measurement(struct file *file, const struct cred *cred,
 	if (!pathbuf)	/* ima_rdwr_violation possibly pre-fetched */
 		pathname = ima_d_path(&file->f_path, &pathbuf, filename);
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (!pathname || strlen(pathname) > IMA_EVENT_NAME_LEN_MAX)
 		pathname = file->f_path.dentry->d_name.name;
 
 	found_digest = ima_lookup_digest(iint->ima_hash->digest, hash_algo,
 					 COMPACT_FILE);
+#endif
 
 	if (action & IMA_MEASURE)
+#ifdef CONFIG_IMA_DIGEST_LIST
 		ima_store_measurement(iint, file, pathname,
 				      xattr_value, xattr_len, modsig, pcr,
 				      template_desc,
 				      ima_digest_allow(found_digest,
 						       IMA_MEASURE));
+#else
+		ima_store_measurement(iint, file, pathname,
+				      xattr_value, xattr_len, modsig, pcr,
+				      template_desc);
+#endif
 
 	if (rc == 0 && (action & IMA_APPRAISE_SUBMASK)) {
 		rc = ima_check_blacklist(iint, modsig, pcr);
 		if (rc != -EPERM) {
 			inode_lock(inode);
+#ifdef CONFIG_IMA_DIGEST_LIST
 			rc = ima_appraise_measurement(func, iint, file,
 					      pathname, xattr_value,
 					      xattr_len, modsig,
 					      ima_digest_allow(found_digest,
 							       IMA_APPRAISE));
+#else
+			rc = ima_appraise_measurement(func, iint, file,
+					      pathname, xattr_value,
+					      xattr_len, modsig);
+#endif
 			inode_unlock(inode);
 		}
 		if (!rc)
@@ -568,15 +590,23 @@ int ima_bprm_check(struct linux_binprm *bprm)
 int ima_file_check(struct file *file, int mask)
 {
 	u32 secid;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	int rc;
+#endif
 
 	security_task_getsecid(current, &secid);
+#ifdef CONFIG_IMA_DIGEST_LIST
 	rc = process_measurement(file, current_cred(), secid, NULL, 0,
 				 mask & (MAY_READ | MAY_WRITE | MAY_EXEC |
 					 MAY_APPEND), FILE_CHECK);
 	if (ima_current_is_parser() && !rc)
 		ima_check_measured_appraised(file);
 	return rc;
+#else
+	return process_measurement(file, current_cred(), secid, NULL, 0,
+				 mask & (MAY_READ | MAY_WRITE | MAY_EXEC |
+					 MAY_APPEND), FILE_CHECK);
+#endif
 }
 EXPORT_SYMBOL_GPL(ima_file_check);
 
@@ -739,7 +769,9 @@ const int read_idmap[READING_MAX_ID] = {
 	[READING_KEXEC_IMAGE] = KEXEC_KERNEL_CHECK,
 	[READING_KEXEC_INITRAMFS] = KEXEC_INITRAMFS_CHECK,
 	[READING_POLICY] = POLICY_CHECK,
+#ifdef CONFIG_IMA_DIGEST_LIST
 	[READING_DIGEST_LIST] = DIGEST_LIST_CHECK
+#endif
 };
 
 /**
@@ -941,7 +973,11 @@ void process_buffer_measurement(struct inode *inode, const void *buf, int size,
 		goto out;
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	ret = ima_store_template(entry, violation, NULL, buf, pcr, NULL);
+#else
+	ret = ima_store_template(entry, violation, NULL, buf, pcr);
+#endif
 	if (ret < 0) {
 		audit_cause = "store_entry";
 		ima_free_template_entry(entry);
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 274f4c7c99f4..3e14b55ecf0f 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -21,7 +21,9 @@
 #include <linux/ima.h>
 
 #include "ima.h"
+#ifdef CONFIG_IMA_DIGEST_LIST
 #include "ima_digest_list.h"
+#endif
 
 /* flags definitions */
 #define IMA_FUNC	0x0001
@@ -35,7 +37,9 @@
 #define IMA_PCR		0x0100
 #define IMA_FSNAME	0x0200
 #define IMA_KEYRINGS	0x0400
+#ifdef CONFIG_IMA_DIGEST_LIST
 #define IMA_PARSER	0x0800
+#endif
 
 #define UNKNOWN		0
 #define MEASURE		0x0001	/* same as IMA_MEASURE */
@@ -58,7 +62,11 @@ enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE,
 	LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE
 };
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 enum policy_types { ORIGINAL_TCB = 1, DEFAULT_TCB, EXEC_TCB };
+#else
+enum policy_types { ORIGINAL_TCB = 1, DEFAULT_TCB };
+#endif
 
 enum policy_rule_list { IMA_DEFAULT_POLICY = 1, IMA_CUSTOM_POLICY };
 
@@ -145,11 +153,13 @@ static struct ima_rule_entry default_measurement_rules[] __ro_after_init = {
 	{.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC},
 	{.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC},
 	{.action = MEASURE, .func = POLICY_CHECK, .flags = IMA_FUNC},
+#ifdef CONFIG_IMA_DIGEST_LIST
 	{.action = MEASURE, .func = DIGEST_LIST_CHECK, .flags = IMA_FUNC},
 };
 
 static struct ima_rule_entry ima_parser_measure_rule __ro_after_init = {
 	.action = MEASURE, .flags = IMA_PARSER
+#endif
 };
 
 static struct ima_rule_entry default_appraise_rules[] __ro_after_init = {
@@ -181,12 +191,14 @@ static struct ima_rule_entry default_appraise_rules[] __ro_after_init = {
 #endif
 };
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static struct ima_rule_entry appraise_exec_rules[] __ro_after_init = {
 	{.action = APPRAISE, .func = BPRM_CHECK,
 	 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
 	{.action = APPRAISE, .func = MMAP_CHECK,
 	 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
 };
+#endif
 
 static struct ima_rule_entry build_appraise_rules[] __ro_after_init = {
 #ifdef CONFIG_IMA_APPRAISE_REQUIRE_MODULE_SIGS
@@ -216,6 +228,7 @@ static struct ima_rule_entry secure_boot_rules[] __ro_after_init = {
 	 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
 	{.action = APPRAISE, .func = POLICY_CHECK,
 	 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
+#ifdef CONFIG_IMA_DIGEST_LIST
 	{.action = APPRAISE, .func = DIGEST_LIST_CHECK,
 	 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
 };
@@ -223,6 +236,7 @@ static struct ima_rule_entry secure_boot_rules[] __ro_after_init = {
 static struct ima_rule_entry ima_parser_appraise_rule __ro_after_init = {
 	.action = APPRAISE,
 	.flags = IMA_PARSER | IMA_DIGSIG_REQUIRED
+#endif
 };
 
 /* An array of architecture specific rules */
@@ -246,8 +260,10 @@ static int __init default_measure_policy_setup(char *str)
 __setup("ima_tcb", default_measure_policy_setup);
 
 static bool ima_use_appraise_tcb __initdata;
+#ifdef CONFIG_IMA_DIGEST_LIST
 static bool ima_use_appraise_exec_tcb __initdata;
 static bool ima_use_appraise_exec_immutable __initdata;
+#endif
 static bool ima_use_secure_boot __initdata;
 static bool ima_fail_unverifiable_sigs __ro_after_init;
 static int __init policy_setup(char *str)
@@ -259,14 +275,18 @@ static int __init policy_setup(char *str)
 			continue;
 		if ((strcmp(p, "tcb") == 0) && !ima_policy)
 			ima_policy = DEFAULT_TCB;
+#ifdef CONFIG_IMA_DIGEST_LIST
 		else if ((strcmp(p, "exec_tcb") == 0) && !ima_policy)
 			ima_policy = EXEC_TCB;
+#endif
 		else if (strcmp(p, "appraise_tcb") == 0)
 			ima_use_appraise_tcb = true;
+#ifdef CONFIG_IMA_DIGEST_LIST
 		else if (strcmp(p, "appraise_exec_tcb") == 0)
 			ima_use_appraise_exec_tcb = true;
 		else if (strcmp(p, "appraise_exec_immutable") == 0)
 			ima_use_appraise_exec_immutable = true;
+#endif
 		else if (strcmp(p, "secure_boot") == 0)
 			ima_use_secure_boot = true;
 		else if (strcmp(p, "fail_securely") == 0)
@@ -569,9 +589,11 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
 	if ((rule->flags & IMA_FOWNER) &&
 	    !rule->fowner_op(inode->i_uid, rule->fowner))
 		return false;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if ((rule->flags & IMA_PARSER) &&
 	    !ima_current_is_parser())
 		return false;
+#endif
 	for (i = 0; i < MAX_LSM_RULES; i++) {
 		int rc = 0;
 		u32 osid;
@@ -752,19 +774,27 @@ static int ima_appraise_flag(enum ima_hooks func)
 		return IMA_APPRAISE_POLICY;
 	else if (func == KEXEC_KERNEL_CHECK)
 		return IMA_APPRAISE_KEXEC;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	else if (func == DIGEST_LIST_CHECK)
 		return IMA_APPRAISE_DIGEST_LIST;
+#endif
 	return 0;
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static void __init add_rules(struct ima_rule_entry *entries, int count,
 			     enum policy_rule_list policy_rule)
+#else
+static void add_rules(struct ima_rule_entry *entries, int count,
+			     enum policy_rule_list policy_rule)
+#endif
 {
 	int i = 0;
 
 	for (i = 0; i < count; i++) {
 		struct ima_rule_entry *entry;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 		if (ima_policy == EXEC_TCB) {
 			if (entries == dont_measure_rules)
 				if ((entries[i].flags & IMA_FSMAGIC) &&
@@ -792,6 +822,7 @@ static void __init add_rules(struct ima_rule_entry *entries, int count,
 			    (entries[i].flags & IMA_FUNC) &&
 			    entries[i].func == BPRM_CHECK)
 				entries[i].flags |= IMA_META_IMMUTABLE_REQUIRED;
+#endif
 
 		if (policy_rule & IMA_DEFAULT_POLICY)
 			list_add_tail(&entries[i].list, &ima_default_rules);
@@ -879,8 +910,10 @@ void __init ima_init_policy(void)
 			  ARRAY_SIZE(original_measurement_rules),
 			  IMA_DEFAULT_POLICY);
 		break;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	case EXEC_TCB:
 		fallthrough;
+#endif
 	case DEFAULT_TCB:
 		add_rules(default_measurement_rules,
 			  ARRAY_SIZE(default_measurement_rules),
@@ -889,8 +922,10 @@ void __init ima_init_policy(void)
 		break;
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (ima_policy)
 		add_rules(&ima_parser_measure_rule, 1, IMA_DEFAULT_POLICY);
+#endif
 
 	/*
 	 * Based on runtime secure boot flags, insert arch specific measurement
@@ -909,7 +944,11 @@ void __init ima_init_policy(void)
 	 * Insert the builtin "secure_boot" policy rules requiring file
 	 * signatures, prior to other appraise rules.
 	 */
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (ima_use_secure_boot || ima_use_appraise_exec_tcb)
+#else
+	if (ima_use_secure_boot)
+#endif
 		add_rules(secure_boot_rules, ARRAY_SIZE(secure_boot_rules),
 			  IMA_DEFAULT_POLICY);
 
@@ -929,11 +968,16 @@ void __init ima_init_policy(void)
 				  IMA_DEFAULT_POLICY | IMA_CUSTOM_POLICY);
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (ima_use_appraise_tcb || ima_use_appraise_exec_tcb)
+#else
+	if (ima_use_appraise_tcb)
+#endif
 		add_rules(default_appraise_rules,
 			  ARRAY_SIZE(default_appraise_rules),
 			  IMA_DEFAULT_POLICY);
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (ima_use_appraise_exec_tcb)
 		add_rules(appraise_exec_rules,
 			  ARRAY_SIZE(appraise_exec_rules),
@@ -942,6 +986,7 @@ void __init ima_init_policy(void)
 	if (ima_use_secure_boot || ima_use_appraise_tcb ||
 	    ima_use_appraise_exec_tcb)
 		add_rules(&ima_parser_appraise_rule, 1, IMA_DEFAULT_POLICY);
+#endif
 
 	ima_update_policy_flag();
 }
@@ -1002,7 +1047,11 @@ enum {
 	Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt,
 	Opt_appraise_type, Opt_appraise_flag,
 	Opt_permit_directio, Opt_pcr, Opt_template, Opt_keyrings,
+#ifdef CONFIG_IMA_DIGEST_LIST
 	Opt_parser, Opt_err
+#else
+	Opt_err
+#endif
 };
 
 static const match_table_t policy_tokens = {
@@ -1039,7 +1088,9 @@ static const match_table_t policy_tokens = {
 	{Opt_pcr, "pcr=%s"},
 	{Opt_template, "template=%s"},
 	{Opt_keyrings, "keyrings=%s"},
+#ifdef CONFIG_IMA_DIGEST_LIST
 	{Opt_parser, "parser"},
+#endif
 	{Opt_err, NULL}
 };
 
@@ -1134,9 +1185,14 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
 	if (entry->action != MEASURE && entry->flags & IMA_PCR)
 		return false;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (entry->action != APPRAISE &&
 	    entry->flags & (IMA_DIGSIG_REQUIRED | IMA_MODSIG_ALLOWED |
 			    IMA_CHECK_BLACKLIST | IMA_META_IMMUTABLE_REQUIRED))
+#else
+	if (entry->action != APPRAISE &&
+	    entry->flags & (IMA_DIGSIG_REQUIRED | IMA_MODSIG_ALLOWED | IMA_CHECK_BLACKLIST))
+#endif
 		return false;
 
 	/*
@@ -1162,13 +1218,19 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
 	case POST_SETATTR:
 	case FIRMWARE_CHECK:
 	case POLICY_CHECK:
+#ifdef CONFIG_IMA_DIGEST_LIST
 	case DIGEST_LIST_CHECK:
+#endif
 		if (entry->flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC |
 				     IMA_UID | IMA_FOWNER | IMA_FSUUID |
 				     IMA_INMASK | IMA_EUID | IMA_PCR |
 				     IMA_FSNAME | IMA_DIGSIG_REQUIRED |
+#ifdef CONFIG_IMA_DIGEST_LIST
 				     IMA_PERMIT_DIRECTIO |
 				     IMA_META_IMMUTABLE_REQUIRED | IMA_PARSER))
+#else
+					 IMA_PERMIT_DIRECTIO))
+#endif
 			return false;
 
 		break;
@@ -1180,8 +1242,12 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
 				     IMA_INMASK | IMA_EUID | IMA_PCR |
 				     IMA_FSNAME | IMA_DIGSIG_REQUIRED |
 				     IMA_PERMIT_DIRECTIO | IMA_MODSIG_ALLOWED |
+#ifdef CONFIG_IMA_DIGEST_LIST
 				     IMA_CHECK_BLACKLIST |
 				     IMA_META_IMMUTABLE_REQUIRED))
+#else
+				     IMA_CHECK_BLACKLIST))
+#endif
 			return false;
 
 		break;
@@ -1338,8 +1404,10 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 			else if (IS_ENABLED(CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS) &&
 				 strcmp(args[0].from, "KEY_CHECK") == 0)
 				entry->func = KEY_CHECK;
+#ifdef CONFIG_IMA_DIGEST_LIST
 			else if (strcmp(args[0].from, "DIGEST_LIST_CHECK") == 0)
 				entry->func = DIGEST_LIST_CHECK;
+#endif
 			else
 				result = -EINVAL;
 			if (!result)
@@ -1526,8 +1594,10 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 				 strcmp(args[0].from, "imasig|modsig") == 0)
 				entry->flags |= IMA_DIGSIG_REQUIRED |
 						IMA_MODSIG_ALLOWED;
+#ifdef CONFIG_IMA_DIGEST_LIST
 			else if (strcmp(args[0].from, "meta_immutable") == 0)
 				entry->flags |= IMA_META_IMMUTABLE_REQUIRED;
+#endif
 			else
 				result = -EINVAL;
 			break;
@@ -1546,8 +1616,12 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 			ima_log_string(ab, "pcr", args[0].from);
 
 			result = kstrtoint(args[0].from, 10, &entry->pcr);
+#ifdef CONFIG_IMA_DIGEST_LIST
 			if (result || INVALID_PCR(entry->pcr) ||
 			    entry->pcr == ima_digest_list_pcr)
+#else
+			if (result || INVALID_PCR(entry->pcr))
+#endif
 				result = -EINVAL;
 			else
 				entry->flags |= IMA_PCR;
@@ -1574,10 +1648,12 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 						 &(template_desc->fields),
 						 &(template_desc->num_fields));
 			entry->template = template_desc;
+#ifdef CONFIG_IMA_DIGEST_LIST
 			break;
 		case Opt_parser:
 			audit_log_format(ab, "parser ");
 			entry->flags |= IMA_PARSER;
+#endif
 			break;
 		case Opt_err:
 			ima_log_string(ab, "UNKNOWN", p);
@@ -1849,8 +1925,10 @@ int ima_policy_show(struct seq_file *m, void *v)
 		seq_puts(m, " ");
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (entry->flags & IMA_PARSER)
 		seq_puts(m, "parser ");
+#endif
 
 	for (i = 0; i < MAX_LSM_RULES; i++) {
 		if (entry->lsm[i].rule) {
@@ -1893,8 +1971,10 @@ int ima_policy_show(struct seq_file *m, void *v)
 	}
 	if (entry->flags & IMA_CHECK_BLACKLIST)
 		seq_puts(m, "appraise_flag=check_blacklist ");
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (entry->flags & IMA_META_IMMUTABLE_REQUIRED)
 		seq_puts(m, "appraise_type=meta_immutable ");
+#endif
 	if (entry->flags & IMA_PERMIT_DIRECTIO)
 		seq_puts(m, "permit_directio ");
 	rcu_read_unlock();
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 77e6819e8db8..d9cf29e286a9 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -14,10 +14,13 @@
 
 #include <linux/types.h>
 #include <linux/integrity.h>
+#include <crypto/sha1.h>
 #include <crypto/sha2.h>
 #include <linux/key.h>
 #include <linux/audit.h>
+#ifdef CONFIG_IMA_DIGEST_LIST
 #include <linux/hash_info.h>
+#endif
 
 /* iint action cache flags */
 #define IMA_MEASURE		0x00000001
@@ -40,7 +43,9 @@
 #define IMA_FAIL_UNVERIFIABLE_SIGS	0x10000000
 #define IMA_MODSIG_ALLOWED	0x20000000
 #define IMA_CHECK_BLACKLIST	0x40000000
+#ifdef CONFIG_IMA_DIGEST_LIST
 #define IMA_META_IMMUTABLE_REQUIRED	0x80000000
+#endif
 
 #define IMA_DO_MASK		(IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
 				 IMA_HASH | IMA_APPRAISE_SUBMASK)
@@ -72,7 +77,9 @@
 #define IMA_CHANGE_ATTR		2
 #define IMA_DIGSIG		3
 #define IMA_MUST_MEASURE	4
+#ifdef CONFIG_IMA_DIGEST_LIST
 #define IMA_DIGEST_LIST		5
+#endif
 
 enum evm_ima_xattr_type {
 	IMA_XATTR_DIGEST = 0x01,
@@ -80,7 +87,9 @@ enum evm_ima_xattr_type {
 	EVM_IMA_XATTR_DIGSIG,
 	IMA_XATTR_DIGEST_NG,
 	EVM_XATTR_PORTABLE_DIGSIG,
+#ifdef CONFIG_IMA_DIGEST_LIST
 	EVM_IMA_XATTR_DIGEST_LIST,
+#endif
 	IMA_XATTR_LAST
 };
 
@@ -92,7 +101,11 @@ struct evm_ima_xattr_data {
 /* Only used in the EVM HMAC code. */
 struct evm_xattr {
 	struct evm_ima_xattr_data data;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	u8 digest[SHA512_DIGEST_SIZE];
+#else
+	u8 digest[SHA1_DIGEST_SIZE];
+#endif
 } __packed;
 
 #define IMA_MAX_DIGEST_SIZE	64
@@ -144,6 +157,7 @@ struct integrity_iint_cache {
 	struct ima_digest_data *ima_hash;
 };
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 enum compact_types { COMPACT_KEY, COMPACT_PARSER, COMPACT_FILE,
 		     COMPACT_METADATA, COMPACT__LAST };
 enum compact_modifiers { COMPACT_MOD_IMMUTABLE, COMPACT_MOD__LAST };
@@ -162,7 +176,6 @@ static inline bool ima_digest_is_immutable(struct ima_digest *digest)
 	return (digest->modifiers & (1 << COMPACT_MOD_IMMUTABLE));
 }
 
-#ifdef CONFIG_IMA_DIGEST_LIST
 struct ima_digest *ima_lookup_digest(u8 *digest, enum hash_algo algo,
 				     enum compact_types type);
 struct ima_digest *ima_digest_allow(struct ima_digest *digest, int action);
diff --git a/security/security.c b/security/security.c
index 5678d4e334fb..11c859a9b8ed 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1362,7 +1362,9 @@ void security_inode_post_setxattr(struct dentry *dentry, const char *name,
 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
 		return;
 	call_void_hook(inode_post_setxattr, dentry, name, value, size, flags);
+#ifdef CONFIG_IMA_DIGEST_LIST
 	ima_inode_post_setxattr(dentry, name, value, size);
+#endif
 	evm_inode_post_setxattr(dentry, name, value, size);
 }
 
-- 
2.33.0
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            1
                            
                          
                          
                            
    
                          
                        
                     
                        
                    17 Aug '23
                    
                        Support multiple compression streams.
Alexey Romanov (1):
  zram: add size class equals check into recompression
Andy Shevchenko (1):
  lib/cmdline: Export next_arg() for being used in modules
Ming Lei (1):
  zram: fix race between zram_reset_device() and disksize_store()
Sergey Senozhatsky (11):
  zram: preparation for multi-zcomp support
  zram: add recompression algorithm sysfs knob
  zram: factor out WB and non-WB zram read functions
  zram: introduce recompress sysfs knob
  zram: add recompress flag to read_block_state()
  zram: clarify writeback_store() comment
  zram: remove redundant checks from zram_recompress()
  zram: add algo parameter support to zram_recompress()
  documentation: add zram recompression documentation
  zram: add incompressible writeback
  zram: add incompressible flag to read_block_state()
 Documentation/admin-guide/blockdev/zram.rst |  98 +++-
 drivers/block/zram/Kconfig                  |   9 +
 drivers/block/zram/zcomp.c                  |   6 +-
 drivers/block/zram/zcomp.h                  |   2 +-
 drivers/block/zram/zram_drv.c               | 594 +++++++++++++++++---
 drivers/block/zram/zram_drv.h               |  22 +-
 include/linux/zsmalloc.h                    |   2 +
 lib/cmdline.c                               |   1 +
 mm/zsmalloc.c                               |  21 +
 9 files changed, 682 insertions(+), 73 deletions(-)
-- 
2.25.1
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            15
                            
                          
                          
                            
    
                          
                        
                    
                    
                        From: Barry Song <v-songbaohua(a)oppo.com>
mainline inclusion
from mainline-v6.0-rc1
commit d0637c505f8a1d8c4088642f1f3e9e3b22da14f6
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I7TVRF
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
-------------------------------------------
THP_SWAP has been proven to improve the swap throughput significantly
on x86_64 according to commit bd4c82c22c367e ("mm, THP, swap: delay
splitting THP after swapped out").
As long as arm64 uses 4K page size, it is quite similar with x86_64
by having 2MB PMD THP. THP_SWAP is architecture-independent, thus,
enabling it on arm64 will benefit arm64 as well.
A corner case is that MTE has an assumption that only base pages
can be swapped. We won't enable THP_SWAP for ARM64 hardware with
MTE support until MTE is reworked to coexist with THP_SWAP.
A micro-benchmark is written to measure thp swapout throughput as
below,
 unsigned long long tv_to_ms(struct timeval tv)
 {
 	return tv.tv_sec * 1000 + tv.tv_usec / 1000;
 }
 main()
 {
 	struct timeval tv_b, tv_e;;
 #define SIZE 400*1024*1024
 	volatile void *p = mmap(NULL, SIZE, PROT_READ | PROT_WRITE,
 				MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 	if (!p) {
 		perror("fail to get memory");
 		exit(-1);
 	}
 	madvise(p, SIZE, MADV_HUGEPAGE);
 	memset(p, 0x11, SIZE); /* write to get mem */
 	gettimeofday(&tv_b, NULL);
 	madvise(p, SIZE, MADV_PAGEOUT);
 	gettimeofday(&tv_e, NULL);
 	printf("swp out bandwidth: %ld bytes/ms\n",
 			SIZE/(tv_to_ms(tv_e) - tv_to_ms(tv_b)));
 }
Testing is done on rk3568 64bit Quad Core Cortex-A55 platform -
ROCK 3A.
thp swp throughput w/o patch: 2734bytes/ms (mean of 10 tests)
thp swp throughput w/  patch: 3331bytes/ms (mean of 10 tests)
Cc: "Huang, Ying" <ying.huang(a)intel.com>
Cc: Minchan Kim <minchan(a)kernel.org>
Cc: Johannes Weiner <hannes(a)cmpxchg.org>
Cc: Hugh Dickins <hughd(a)google.com>
Cc: Andrea Arcangeli <aarcange(a)redhat.com>
Cc: Steven Price <steven.price(a)arm.com>
Cc: Yang Shi <shy828301(a)gmail.com>
Reviewed-by: Anshuman Khandual <anshuman.khandual(a)arm.com>
Signed-off-by: Barry Song <v-songbaohua(a)oppo.com>
Link: https://lore.kernel.org/r/20220720093737.133375-1-21cnbao@gmail.com
Signed-off-by: Will Deacon <will(a)kernel.org>
Conflicts:
	arch/arm64/Kconfig
	include/linux/huge_mm.h
	mm/swap_slots.c
Signed-off-by: Jinjiang Tu <tujinjiang(a)huawei.com>
---
 arch/arm64/Kconfig               |  1 +
 arch/arm64/include/asm/pgtable.h |  6 ++++++
 include/linux/huge_mm.h          | 12 ++++++++++++
 mm/swap_slots.c                  |  2 +-
 4 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 16620146c49a..05302e1d8e19 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -86,6 +86,7 @@ config ARM64
 	select ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
 	select ARCH_WANT_LD_ORPHAN_WARN
 	select ARCH_WANT_RESERVE_CRASH_KERNEL if KEXEC_CORE
+	select ARCH_WANTS_THP_SWAP if ARM64_4K_PAGES
 	select ARCH_HAS_UBSAN_SANITIZE_ALL
 	select ARM_AMBA
 	select ARM_ARCH_TIMER
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index ab2443900f4e..f2843785f2ec 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -46,6 +46,12 @@
 	__flush_tlb_range(vma, addr, end, PUD_SIZE, false, 1)
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
+static inline bool arch_thp_swp_supported(void)
+{
+	return !system_supports_mte();
+}
+#define arch_thp_swp_supported arch_thp_swp_supported
+
 /*
  * Outside of a few very special situations (e.g. hibernation), we always
  * use broadcast TLB invalidation instructions, therefore a spurious page
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index 176457145bcf..b993ae44111c 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -499,4 +499,16 @@ static inline unsigned long thp_size(struct page *page)
 	return PAGE_SIZE << thp_order(page);
 }
 
+/*
+ * archs that select ARCH_WANTS_THP_SWAP but don't support THP_SWP due to
+ * limitations in the implementation like arm64 MTE can override this to
+ * false
+ */
+#ifndef arch_thp_swp_supported
+static inline bool arch_thp_swp_supported(void)
+{
+	return true;
+}
+#endif
+
 #endif /* _LINUX_HUGE_MM_H */
diff --git a/mm/swap_slots.c b/mm/swap_slots.c
index fbb9888a0469..b7958ca276c2 100644
--- a/mm/swap_slots.c
+++ b/mm/swap_slots.c
@@ -436,7 +436,7 @@ swp_entry_t get_swap_page(struct page *page)
 		goto out;
 
 	if (PageTransHuge(page)) {
-		if (IS_ENABLED(CONFIG_THP_SWAP))
+		if (IS_ENABLED(CONFIG_THP_SWAP) && arch_thp_swp_supported())
 			get_swap_pages(1, &entry, HPAGE_PMD_NR, type);
 		goto out;
 	}
-- 
2.25.1
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            1
                            
                          
                          
                            
    
                          
                        
                    
                    
                        Isolate the IMA digest list code by using macros.
Signed-off-by: Zhou Shuiqing <zhoushuiqing2(a)huawei.com>
---
 fs/xattr.c                                |   4 +
 include/linux/ima.h                       |   8 +
 security/integrity/digsig_asymmetric.c    |   4 +
 security/integrity/evm/evm.h              |   2 +
 security/integrity/evm/evm_crypto.c       |  38 +++-
 security/integrity/evm/evm_main.c         | 146 +++++++++++++
 security/integrity/iint.c                 |   4 +
 security/integrity/ima/ima.h              |  80 ++++++-
 security/integrity/ima/ima_api.c          |  39 ++++
 security/integrity/ima/ima_appraise.c     | 128 ++++++++++-
 security/integrity/ima/ima_fs.c           | 247 +++++++++++++++++++++-
 security/integrity/ima/ima_init.c         |   8 +
 security/integrity/ima/ima_main.c         |  36 +++-
 security/integrity/ima/ima_policy.c       |  80 +++++++
 security/integrity/ima/ima_template.c     |   2 +
 security/integrity/ima/ima_template_lib.c |   8 +
 security/integrity/ima/ima_template_lib.h |   2 +
 security/integrity/integrity.h            |  15 +-
 security/security.c                       |   2 +
 19 files changed, 840 insertions(+), 13 deletions(-)
diff --git a/fs/xattr.c b/fs/xattr.c
index 149b8cf5f99f..c31266a83391 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -16,7 +16,9 @@
 #include <linux/namei.h>
 #include <linux/security.h>
 #include <linux/evm.h>
+#ifdef CONFIG_IMA_DIGEST_LIST
 #include <linux/ima.h>
+#endif
 #include <linux/syscalls.h>
 #include <linux/export.h>
 #include <linux/fsnotify.h>
@@ -475,7 +477,9 @@ __vfs_removexattr_locked(struct dentry *dentry, const char *name,
 
 	if (!error) {
 		fsnotify_xattr(dentry);
+#ifdef CONFIG_IMA_DIGEST_LIST
 		ima_inode_post_removexattr(dentry, name);
+#endif
 		evm_inode_post_removexattr(dentry, name);
 	}
 
diff --git a/include/linux/ima.h b/include/linux/ima.h
index f7a088b2579e..713c6f9696cb 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -144,13 +144,17 @@ extern bool is_ima_appraise_enabled(void);
 extern void ima_inode_post_setattr(struct dentry *dentry);
 extern int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
 		       const void *xattr_value, size_t xattr_value_len);
+#ifdef CONFIG_IMA_DIGEST_LIST
 extern void ima_inode_post_setxattr(struct dentry *dentry,
 				    const char *xattr_name,
 				    const void *xattr_value,
 				    size_t xattr_value_len);
+#endif
 extern int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name);
+#ifdef CONFIG_IMA_DIGEST_LIST
 extern void ima_inode_post_removexattr(struct dentry *dentry,
 				       const char *xattr_name);
+#endif
 #else
 static inline bool is_ima_appraise_enabled(void)
 {
@@ -170,12 +174,14 @@ static inline int ima_inode_setxattr(struct dentry *dentry,
 	return 0;
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static inline void ima_inode_post_setxattr(struct dentry *dentry,
 					   const char *xattr_name,
 					   const void *xattr_value,
 					   size_t xattr_value_len)
 {
 }
+#endif
 
 static inline int ima_inode_removexattr(struct dentry *dentry,
 					const char *xattr_name)
@@ -183,10 +189,12 @@ static inline int ima_inode_removexattr(struct dentry *dentry,
 	return 0;
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static inline void ima_inode_post_removexattr(struct dentry *dentry,
 					      const char *xattr_name)
 {
 }
+#endif
 #endif /* CONFIG_IMA_APPRAISE */
 
 #if defined(CONFIG_IMA_APPRAISE) && defined(CONFIG_INTEGRITY_TRUSTED_KEYRING)
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
index 92dc64755e53..72941f9b1b99 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -9,7 +9,9 @@
 #include <linux/err.h>
 #include <linux/ratelimit.h>
 #include <linux/key-type.h>
+#ifdef CONFIG_IMA_DIGEST_LIST
 #include <linux/verification.h>
+#endif
 #include <crypto/public_key.h>
 #include <crypto/hash_info.h>
 #include <keys/asymmetric-type.h>
@@ -55,6 +57,7 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
 		key = request_key(&key_type_asymmetric, name, NULL);
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (IS_ERR(key)) {
 #ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
 		keyring = VERIFY_USE_SECONDARY_KEYRING;
@@ -63,6 +66,7 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
 #endif
 		key = search_trusted_key(keyring, &key_type_asymmetric, name);
 	}
+#endif
 
 	if (IS_ERR(key)) {
 		if (keyring)
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
index ca7ed2e532dc..f8b1627708a1 100644
--- a/security/integrity/evm/evm.h
+++ b/security/integrity/evm/evm.h
@@ -32,7 +32,9 @@ struct xattr_list {
 };
 
 extern int evm_initialized;
+#ifdef CONFIG_IMA_DIGEST_LIST
 extern enum hash_algo evm_hash_algo;
+#endif
 
 #define EVM_ATTR_FSUUID		0x0001
 
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index 7c36dbb96d24..fa8147c2294e 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -33,7 +33,11 @@ static DEFINE_MUTEX(mutex);
 
 static unsigned long evm_set_key_flags;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 enum hash_algo evm_hash_algo __ro_after_init = HASH_ALGO_SHA1;
+#else
+static const char evm_hmac[] = "hmac(sha1)";
+#endif
 
 /**
  * evm_set_key() - set EVM HMAC key from the kernel
@@ -74,11 +78,13 @@ static struct shash_desc *init_desc(char type, uint8_t hash_algo)
 	long rc;
 	const char *algo;
 	struct crypto_shash **tfm, *tmp_tfm;
-	char evm_hmac[CRYPTO_MAX_ALG_NAME];
 	struct shash_desc *desc;
+#ifdef CONFIG_IMA_DIGEST_LIST
+	char evm_hmac[CRYPTO_MAX_ALG_NAME];
 
 	snprintf(evm_hmac, sizeof(evm_hmac), "hmac(%s)",
 		 CONFIG_EVM_DEFAULT_HASH);
+#endif
 
 	if (type == EVM_XATTR_HMAC) {
 		if (!(evm_initialized & EVM_INIT_HMAC)) {
@@ -156,8 +162,12 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
 	/* Don't include the inode or generation number in portable
 	 * signatures
 	 */
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (type != EVM_XATTR_PORTABLE_DIGSIG &&
 	    type != EVM_IMA_XATTR_DIGEST_LIST) {
+#else
+	if (type != EVM_XATTR_PORTABLE_DIGSIG) {
+#endif
 		hmac_misc.ino = inode->i_ino;
 		hmac_misc.generation = inode->i_generation;
 	}
@@ -174,8 +184,12 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
 	hmac_misc.mode = inode->i_mode;
 	crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof(hmac_misc));
 	if ((evm_hmac_attrs & EVM_ATTR_FSUUID) &&
+#ifdef CONFIG_IMA_DIGEST_LIST
 	    type != EVM_XATTR_PORTABLE_DIGSIG &&
 	    type != EVM_IMA_XATTR_DIGEST_LIST)
+#else
+		type != EVM_XATTR_PORTABLE_DIGSIG)
+#endif
 		crypto_shash_update(desc, (u8 *)&inode->i_sb->s_uuid, UUID_SIZE);
 	crypto_shash_final(desc, digest);
 }
@@ -288,8 +302,12 @@ static int evm_is_immutable(struct dentry *dentry, struct inode *inode)
 			return 0;
 		return rc;
 	}
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (xattr_data->type == EVM_XATTR_PORTABLE_DIGSIG ||
 	    xattr_data->type == EVM_IMA_XATTR_DIGEST_LIST)
+#else
+	if (xattr_data->type == EVM_XATTR_PORTABLE_DIGSIG)
+#endif
 		rc = 1;
 	else
 		rc = 0;
@@ -321,15 +339,23 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
 	if (rc)
 		return -EPERM;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	data.hdr.algo = evm_hash_algo;
+#else
+	data.hdr.algo = HASH_ALGO_SHA1;
+#endif
 	rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
 			   xattr_value_len, &data);
 	if (rc == 0) {
 		data.hdr.xattr.sha1.type = EVM_XATTR_HMAC;
 		rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM,
 					   &data.hdr.xattr.data[1],
+#ifdef CONFIG_IMA_DIGEST_LIST
 					   hash_digest_size[evm_hash_algo] + 1,
 					   0);
+#else
+					   SHA1_DIGEST_SIZE + 1, 0);
+#endif
 	} else if (rc == -ENODATA && (inode->i_opflags & IOP_XATTR)) {
 		rc = __vfs_removexattr(dentry, XATTR_NAME_EVM);
 	}
@@ -341,7 +367,11 @@ int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
 {
 	struct shash_desc *desc;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	desc = init_desc(EVM_XATTR_HMAC, evm_hash_algo);
+#else
+	desc = init_desc(EVM_XATTR_HMAC, HASH_ALGO_SHA1);
+#endif
 	if (IS_ERR(desc)) {
 		pr_info("init_desc failed\n");
 		return PTR_ERR(desc);
@@ -353,9 +383,15 @@ int evm_init_hmac(struct inode *inode, const struct xattr *lsm_xattr,
 	return 0;
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 /*
  * Get the key from the TPM for the HMAC
  */
+#else
+/*
+ * Get the key from the TPM for the SHA1-HMAC
+ */
+#endif
 int evm_init_key(void)
 {
 	struct key *evm_key;
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index cddfc0e43a80..fe767feb722d 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -18,7 +18,9 @@
 #include <linux/integrity.h>
 #include <linux/evm.h>
 #include <linux/magic.h>
+#ifdef CONFIG_IMA_DIGEST_LIST
 #include <linux/posix_acl_xattr.h>
+#endif
 
 #include <crypto/hash.h>
 #include <crypto/hash_info.h>
@@ -28,8 +30,12 @@
 int evm_initialized;
 
 static const char * const integrity_status_msg[] = {
+#ifdef CONFIG_IMA_DIGEST_LIST
 	"pass", "pass_immutable", "fail", "fail_immutable", "no_label",
 	"no_xattrs", "unknown"
+#else
+	"pass", "pass_immutable", "fail", "no_label", "no_xattrs", "unknown"
+#endif
 };
 int evm_hmac_attrs;
 
@@ -57,6 +63,7 @@ static struct xattr_list evm_config_default_xattrnames[] = {
 LIST_HEAD(evm_config_xattrnames);
 
 static int evm_fixmode __ro_after_init;
+#ifdef CONFIG_IMA_DIGEST_LIST
 static int __init evm_set_param(char *str)
 {
 	if (strncmp(str, "fix", 3) == 0)
@@ -73,6 +80,18 @@ static int __init evm_set_param(char *str)
 	return 1;
 }
 __setup("evm=", evm_set_param);
+#else
+static int __init evm_set_fixmode(char *str)
+{
+	if (strncmp(str, "fix", 3) == 0)
+		evm_fixmode = 1;
+	else
+		pr_err("invalid \"%s\" mode", str);
+
+	return 0;
+}
+__setup("evm=", evm_set_fixmode);
+#endif
 
 static void __init evm_init_config(void)
 {
@@ -98,6 +117,7 @@ static bool evm_key_loaded(void)
 	return (bool)(evm_initialized & EVM_KEY_MASK);
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 /*
  * Ignoring INTEGRITY_NOLABEL/INTEGRITY_NOXATTRS is safe if no HMAC key
  * is loaded and the EVM_SETUP_COMPLETE initialization flag is set.
@@ -115,8 +135,13 @@ static bool evm_ignore_error_safe(enum integrity_status evm_status)
 
 	return true;
 }
+#endif
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static int evm_find_protected_xattrs(struct dentry *dentry, int *ima_present)
+#else
+static int evm_find_protected_xattrs(struct dentry *dentry)
+#endif
 {
 	struct inode *inode = d_backing_inode(dentry);
 	struct xattr_list *xattr;
@@ -133,8 +158,10 @@ static int evm_find_protected_xattrs(struct dentry *dentry, int *ima_present)
 				continue;
 			return error;
 		}
+#ifdef CONFIG_IMA_DIGEST_LIST
 		if (!strcmp(xattr->name, XATTR_NAME_IMA))
 			*ima_present = 1;
+#endif
 		count++;
 	}
 
@@ -163,6 +190,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 	struct evm_ima_xattr_data *xattr_data = NULL;
 	struct signature_v2_hdr *hdr;
 	enum integrity_status evm_status = INTEGRITY_PASS;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	enum integrity_status saved_evm_status = INTEGRITY_UNKNOWN;
 	struct evm_digest digest;
 	struct ima_digest *found_digest;
@@ -172,6 +200,12 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 				.version = 2, .hash_algo = HASH_ALGO_SHA256 };
 	int rc, xattr_len, evm_immutable = 0, ima_present = 0;
 
+#else
+	struct evm_digest digest;
+	struct inode *inode;
+	int rc, xattr_len;
+#endif
+
 	if (iint && (iint->evm_status == INTEGRITY_PASS ||
 		     iint->evm_status == INTEGRITY_PASS_IMMUTABLE))
 		return iint->evm_status;
@@ -184,7 +218,11 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 	if (rc <= 0) {
 		evm_status = INTEGRITY_FAIL;
 		if (rc == -ENODATA) {
+#ifdef CONFIG_IMA_DIGEST_LIST
 			rc = evm_find_protected_xattrs(dentry, &ima_present);
+#else
+			rc = evm_find_protected_xattrs(dentry);
+#endif
 			if (rc > 0)
 				evm_status = INTEGRITY_NOLABEL;
 			else if (rc == 0)
@@ -192,6 +230,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 		} else if (rc == -EOPNOTSUPP) {
 			evm_status = INTEGRITY_UNKNOWN;
 		}
+#ifdef CONFIG_IMA_DIGEST_LIST
 		/* IMA added a fake xattr, set also EVM fake xattr */
 		if (!ima_present && xattr_name &&
 		    !strcmp(xattr_name, XATTR_NAME_IMA) &&
@@ -206,6 +245,9 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 			goto out;
 
 		saved_evm_status = evm_status;
+#else
+		goto out;
+#endif
 	}
 
 	xattr_len = rc;
@@ -213,6 +255,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 	/* check value type */
 	switch (xattr_data->type) {
 	case EVM_XATTR_HMAC:
+#ifdef CONFIG_IMA_DIGEST_LIST
 		if (xattr_len != hash_digest_size[evm_hash_algo] + 1) {
 			evm_status = INTEGRITY_FAIL;
 			goto out;
@@ -231,6 +274,25 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 		evm_immutable = 1;
 		fallthrough;
 	case EVM_IMA_XATTR_DIGSIG:
+#else
+		if (xattr_len != sizeof(struct evm_xattr)) {
+			evm_status = INTEGRITY_FAIL;
+			goto out;
+		}
+
+		digest.hdr.algo = HASH_ALGO_SHA1;
+		rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
+				   xattr_value_len, &digest);
+		if (rc)
+			break;
+		rc = crypto_memneq(xattr_data->data, digest.digest,
+				   SHA1_DIGEST_SIZE);
+		if (rc)
+			rc = -EINVAL;
+		break;
+	case EVM_IMA_XATTR_DIGSIG:
+	case EVM_XATTR_PORTABLE_DIGSIG:
+#endif
 		/* accept xattr with non-empty signature field */
 		if (xattr_len <= sizeof(struct signature_v2_hdr)) {
 			evm_status = INTEGRITY_FAIL;
@@ -262,6 +324,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 			}
 		}
 		break;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	case EVM_IMA_XATTR_DIGEST_LIST:
 		/* At this point, we cannot determine whether metadata are
 		 * immutable or not. However, it is safe to return the
@@ -302,11 +365,13 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 			evm_status = INTEGRITY_PASS;
 		}
 		break;
+#endif
 	default:
 		rc = -EINVAL;
 		break;
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (rc && xattr_data == (struct evm_ima_xattr_data *)&evm_fake_xattr) {
 		evm_status = saved_evm_status;
 	} else if (rc) {
@@ -315,10 +380,17 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 			evm_status = evm_immutable ?
 				     INTEGRITY_FAIL_IMMUTABLE : INTEGRITY_FAIL;
 	}
+#else
+	if (rc)
+		evm_status = (rc == -ENODATA) ?
+				INTEGRITY_NOXATTRS : INTEGRITY_FAIL;
+#endif
 out:
 	if (iint)
 		iint->evm_status = evm_status;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (xattr_data != (struct evm_ima_xattr_data *)&evm_fake_xattr)
+#endif
 		kfree(xattr_data);
 	return evm_status;
 }
@@ -397,6 +469,7 @@ static enum integrity_status evm_verify_current_integrity(struct dentry *dentry)
 	return evm_verify_hmac(dentry, NULL, NULL, 0, NULL);
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 /*
  * evm_xattr_acl_change - check if passed ACL changes the inode mode
  * @dentry: pointer to the affected dentry
@@ -468,6 +541,7 @@ static int evm_xattr_change(struct dentry *dentry, const char *xattr_name,
 	kfree(xattr_data);
 	return rc;
 }
+#endif
 
 /*
  * evm_protect_xattr - protect the EVM extended attribute
@@ -519,6 +593,7 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
 				    -EPERM, 0);
 	}
 out:
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (evm_ignore_error_safe(evm_status))
 		return 0;
 
@@ -532,6 +607,7 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
 	if (evm_status == INTEGRITY_PASS_IMMUTABLE &&
 	    !evm_xattr_change(dentry, xattr_name, xattr_value, xattr_value_len))
 		return 0;
+#endif
 
 	if (evm_status != INTEGRITY_PASS)
 		integrity_audit_msg(AUDIT_INTEGRITY_METADATA, d_backing_inode(dentry),
@@ -569,8 +645,12 @@ int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name,
 		if (!xattr_value_len)
 			return -EINVAL;
 		if (xattr_data->type != EVM_IMA_XATTR_DIGSIG &&
+#ifdef CONFIG_IMA_DIGEST_LIST
 		    xattr_data->type != EVM_XATTR_PORTABLE_DIGSIG &&
 		    xattr_data->type != EVM_IMA_XATTR_DIGEST_LIST)
+#else
+		    xattr_data->type != EVM_XATTR_PORTABLE_DIGSIG)
+#endif
 			return -EPERM;
 	}
 	return evm_protect_xattr(dentry, xattr_name, xattr_value,
@@ -605,6 +685,7 @@ static void evm_reset_status(struct inode *inode)
 		iint->evm_status = INTEGRITY_UNKNOWN;
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 /**
  * evm_status_revalidate - report whether EVM status re-validation is necessary
  * @xattr_name: pointer to the affected extended attribute name
@@ -629,6 +710,7 @@ bool evm_status_revalidate(const char *xattr_name)
 
 	return true;
 }
+#endif
 
 /**
  * evm_inode_post_setxattr - update 'security.evm' to reflect the changes
@@ -646,13 +728,20 @@ bool evm_status_revalidate(const char *xattr_name)
 void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
 			     const void *xattr_value, size_t xattr_value_len)
 {
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (!evm_status_revalidate(xattr_name))
+#else
+	if (!evm_key_loaded() || (!evm_protected_xattr(xattr_name)
+				  && !posix_xattr_acl(xattr_name)))
+#endif
 		return;
 
 	evm_reset_status(dentry->d_inode);
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (!strcmp(xattr_name, XATTR_NAME_EVM))
 		return;
+#endif
 
 	evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len);
 }
@@ -669,17 +758,24 @@ void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
  */
 void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
 {
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (!evm_status_revalidate(xattr_name))
+#else
+	if (!evm_key_loaded() || !evm_protected_xattr(xattr_name))
+#endif
 		return;
 
 	evm_reset_status(dentry->d_inode);
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (!strcmp(xattr_name, XATTR_NAME_EVM))
 		return;
+#endif
 
 	evm_update_evmxattr(dentry, xattr_name, NULL, 0);
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static int evm_attr_change(struct dentry *dentry, struct iattr *attr)
 {
 	struct inode *inode = d_backing_inode(dentry);
@@ -692,6 +788,7 @@ static int evm_attr_change(struct dentry *dentry, struct iattr *attr)
 
 	return 1;
 }
+#endif
 
 /**
  * evm_inode_setattr - prevent updating an invalid EVM extended attribute
@@ -714,6 +811,7 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
 	if (!(ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)))
 		return 0;
 	evm_status = evm_verify_current_integrity(dentry);
+#ifdef CONFIG_IMA_DIGEST_LIST
 	/*
 	 * Writing attrs is safe for portable signatures, as portable signatures
 	 * are immutable and can never be updated.
@@ -727,6 +825,11 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
 	if (evm_status == INTEGRITY_PASS_IMMUTABLE &&
 	    !evm_attr_change(dentry, attr))
 		return 0;
+#else
+	if ((evm_status == INTEGRITY_PASS) ||
+	    (evm_status == INTEGRITY_NOXATTRS))
+		return 0;
+#endif
 
 	integrity_audit_msg(AUDIT_INTEGRITY_METADATA, d_backing_inode(dentry),
 			    dentry->d_name.name, "appraise_metadata",
@@ -747,15 +850,21 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
  */
 void evm_inode_post_setattr(struct dentry *dentry, int ia_valid)
 {
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (!evm_status_revalidate(NULL))
 		return;
 
 	evm_reset_status(dentry->d_inode);
+#else
+	if (!evm_key_loaded())
+		return;
+#endif
 
 	if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
 		evm_update_evmxattr(dentry, NULL, NULL, 0);
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 /*
  * evm_inode_init_security - initializes security.evm HMAC value
  */
@@ -787,6 +896,38 @@ int evm_inode_init_security(struct inode *inode,
 	kfree(xattr_data);
 	return rc;
 }
+#else
+/*
+ * evm_inode_init_security - initializes security.evm
+ */
+int evm_inode_init_security(struct inode *inode,
+				 const struct xattr *lsm_xattr,
+				 struct xattr *evm_xattr)
+{
+	struct evm_xattr *xattr_data;
+	int rc;
+
+	if (!evm_key_loaded() || !evm_protected_xattr(lsm_xattr->name))
+		return 0;
+
+	xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS);
+	if (!xattr_data)
+		return -ENOMEM;
+
+	xattr_data->data.type = EVM_XATTR_HMAC;
+	rc = evm_init_hmac(inode, lsm_xattr, xattr_data->digest);
+	if (rc < 0)
+		goto out;
+
+	evm_xattr->value = xattr_data;
+	evm_xattr->value_len = sizeof(*xattr_data);
+	evm_xattr->name = XATTR_EVM_SUFFIX;
+	return 0;
+out:
+	kfree(xattr_data);
+	return rc;
+}
+#endif
 EXPORT_SYMBOL_GPL(evm_inode_init_security);
 
 #ifdef CONFIG_EVM_LOAD_X509
@@ -802,6 +943,7 @@ void __init evm_load_x509(void)
 
 static int __init init_evm(void)
 {
+#ifdef CONFIG_IMA_DIGEST_LIST
 	int error, i;
 	struct list_head *pos, *q;
 
@@ -809,6 +951,10 @@ static int __init init_evm(void)
 			 CONFIG_EVM_DEFAULT_HASH);
 	if (i >= 0)
 		evm_hash_algo = i;
+#else
+	int error;
+	struct list_head *pos, *q;
+#endif
 
 	evm_init_config();
 
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index 8953ac6412c3..df994202ac0f 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -209,10 +209,14 @@ void __init integrity_load_keys(void)
 {
 	ima_load_x509();
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (!IS_ENABLED(CONFIG_IMA_LOAD_X509))
 		evm_load_x509();
 
 	ima_load_digest_lists();
+#else
+    evm_load_x509();
+#endif
 }
 
 static int __init integrity_fs_init(void)
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 46afb6bef45b..e512a17b09dd 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -53,11 +53,11 @@ extern int ima_hash_algo_idx __ro_after_init;
 extern int ima_extra_slots __ro_after_init;
 extern int ima_appraise;
 extern struct tpm_chip *ima_tpm_chip;
+extern const char boot_aggregate_name[];
+#ifdef CONFIG_IMA_DIGEST_LIST
 extern int ima_digest_list_pcr;
 extern bool ima_plus_standard_pcr;
-extern const char boot_aggregate_name[];
 extern int ima_digest_list_actions;
-#ifdef CONFIG_IMA_DIGEST_LIST
 extern int ima_digest_db_max_size __ro_after_init;
 extern int ima_digest_db_size;
 #endif
@@ -189,6 +189,7 @@ static inline unsigned int ima_hash_key(u8 *digest)
 	return (digest[0] | digest[1] << 8) % IMA_MEASURE_HTABLE_SIZE;
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 #define __ima_hooks(hook)				\
 	hook(NONE, none)				\
 	hook(FILE_CHECK, file)				\
@@ -205,6 +206,23 @@ static inline unsigned int ima_hash_key(u8 *digest)
 	hook(KEY_CHECK, key)				\
 	hook(DIGEST_LIST_CHECK, digest_list)		\
 	hook(MAX_CHECK, none)
+#else
+#define __ima_hooks(hook)				\
+	hook(NONE, none)				\
+	hook(FILE_CHECK, file)				\
+	hook(MMAP_CHECK, mmap)				\
+	hook(BPRM_CHECK, bprm)				\
+	hook(CREDS_CHECK, creds)			\
+	hook(POST_SETATTR, post_setattr)		\
+	hook(MODULE_CHECK, module)			\
+	hook(FIRMWARE_CHECK, firmware)			\
+	hook(KEXEC_KERNEL_CHECK, kexec_kernel)		\
+	hook(KEXEC_INITRAMFS_CHECK, kexec_initramfs)	\
+	hook(POLICY_CHECK, policy)			\
+	hook(KEXEC_CMDLINE, kexec_cmdline)		\
+	hook(KEY_CHECK, key)				\
+	hook(MAX_CHECK, none)
+#endif
 
 #define __ima_hook_enumify(ENUM, str)	ENUM,
 #define __ima_stringify(arg) (#arg)
@@ -264,12 +282,20 @@ int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func);
 int ima_collect_measurement(struct integrity_iint_cache *iint,
 			    struct file *file, void *buf, loff_t size,
 			    enum hash_algo algo, struct modsig *modsig);
+#ifdef CONFIG_IMA_DIGEST_LIST
 void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
 			   const unsigned char *filename,
 			   struct evm_ima_xattr_data *xattr_value,
 			   int xattr_len, const struct modsig *modsig, int pcr,
 			   struct ima_template_desc *template_desc,
 			   struct ima_digest *digest);
+#else
+void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
+			   const unsigned char *filename,
+			   struct evm_ima_xattr_data *xattr_value,
+			   int xattr_len, const struct modsig *modsig, int pcr,
+			   struct ima_template_desc *template_desc);
+#endif
 void process_buffer_measurement(struct inode *inode, const void *buf, int size,
 				const char *eventname, enum ima_hooks func,
 				int pcr, const char *keyring);
@@ -278,9 +304,15 @@ void ima_audit_measurement(struct integrity_iint_cache *iint,
 int ima_alloc_init_template(struct ima_event_data *event_data,
 			    struct ima_template_entry **entry,
 			    struct ima_template_desc *template_desc);
+#ifdef CONFIG_IMA_DIGEST_LIST
 int ima_store_template(struct ima_template_entry *entry, int violation,
 		       struct inode *inode, const unsigned char *filename,
 		       int pcr, struct ima_digest *digest);
+#else
+int ima_store_template(struct ima_template_entry *entry, int violation,
+		       struct inode *inode,
+		       const unsigned char *filename, int pcr);
+#endif
 void ima_free_template_entry(struct ima_template_entry *entry);
 const char *ima_d_path(const struct path *path, char **pathbuf, char *filename);
 
@@ -308,21 +340,41 @@ int ima_policy_show(struct seq_file *m, void *v);
 #define IMA_APPRAISE_FIRMWARE	0x10
 #define IMA_APPRAISE_POLICY	0x20
 #define IMA_APPRAISE_KEXEC	0x40
+#ifdef CONFIG_IMA_DIGEST_LIST
 #define IMA_APPRAISE_DIGEST_LIST	0x80
+#endif
 
 #ifdef CONFIG_IMA_APPRAISE
 int ima_check_blacklist(struct integrity_iint_cache *iint,
 			const struct modsig *modsig, int pcr);
+
+#ifdef CONFIG_IMA_DIGEST_LIST
 int ima_appraise_measurement(enum ima_hooks func,
 			     struct integrity_iint_cache *iint,
 			     struct file *file, const unsigned char *filename,
 			     struct evm_ima_xattr_data *xattr_value,
 			     int xattr_len, const struct modsig *modsig,
 			     struct ima_digest *found_digest);
+#else
+int ima_appraise_measurement(enum ima_hooks func,
+			     struct integrity_iint_cache *iint,
+			     struct file *file, const unsigned char *filename,
+			     struct evm_ima_xattr_data *xattr_value,
+			     int xattr_len, const struct modsig *modsig);
+#endif
+
 int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func);
 void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
 enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
 					   enum ima_hooks func);
+
+#ifndef CONFIG_IMA_DIGEST_LIST
+enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
+				 int xattr_len);
+int ima_read_xattr(struct dentry *dentry,
+		   struct evm_ima_xattr_data **xattr_value);
+#endif
+
 #else
 static inline int ima_check_blacklist(struct integrity_iint_cache *iint,
 				      const struct modsig *modsig, int pcr)
@@ -330,6 +382,7 @@ static inline int ima_check_blacklist(struct integrity_iint_cache *iint,
 	return 0;
 }
 
+#ifndef CONFIG_IMA_DIGEST_LIST
 static inline int ima_appraise_measurement(enum ima_hooks func,
 					   struct integrity_iint_cache *iint,
 					   struct file *file,
@@ -338,6 +391,15 @@ static inline int ima_appraise_measurement(enum ima_hooks func,
 					   int xattr_len,
 					   const struct modsig *modsig,
 					   struct ima_digest *found_digest)
+#else
+static inline int ima_appraise_measurement(enum ima_hooks func,
+					   struct integrity_iint_cache *iint,
+					   struct file *file,
+					   const unsigned char *filename,
+					   struct evm_ima_xattr_data *xattr_value,
+					   int xattr_len,
+					   const struct modsig *modsig)
+#endif
 {
 	return INTEGRITY_UNKNOWN;
 }
@@ -360,6 +422,20 @@ static inline enum integrity_status ima_get_cache_status(struct integrity_iint_c
 	return INTEGRITY_UNKNOWN;
 }
 
+#ifndef CONFIG_IMA_DIGEST_LIST
+static inline enum hash_algo
+ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len)
+{
+	return ima_hash_algo;
+}
+
+static inline int ima_read_xattr(struct dentry *dentry,
+				 struct evm_ima_xattr_data **xattr_value)
+{
+	return 0;
+}
+#endif
+
 #endif /* CONFIG_IMA_APPRAISE */
 
 #ifdef CONFIG_IMA_APPRAISE_MODSIG
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 6ecaf6834844..1b8d3696d873 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -99,15 +99,23 @@ int ima_alloc_init_template(struct ima_event_data *event_data,
  *
  * Returns 0 on success, error code otherwise
  */
+#ifdef CONFIG_IMA_DIGEST_LIST
 int ima_store_template(struct ima_template_entry *entry,
 		       int violation, struct inode *inode,
 		       const unsigned char *filename, int pcr,
 		       struct ima_digest *digest)
+#else
+int ima_store_template(struct ima_template_entry *entry,
+		       int violation, struct inode *inode,
+		       const unsigned char *filename, int pcr)
+#endif
 {
 	static const char op[] = "add_template_measure";
 	static const char audit_cause[] = "hashing_error";
 	char *template_name = entry->template_desc->name;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	struct ima_template_entry *duplicated_entry = NULL;
+#endif
 	int result;
 
 	if (!violation) {
@@ -121,6 +129,7 @@ int ima_store_template(struct ima_template_entry *entry,
 		}
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (ima_plus_standard_pcr && !digest) {
 		duplicated_entry = kmemdup(entry,
 			sizeof(*entry) + entry->template_desc->num_fields *
@@ -130,9 +139,11 @@ int ima_store_template(struct ima_template_entry *entry,
 	} else if (!ima_plus_standard_pcr && ima_digest_list_pcr >= 0) {
 		pcr = ima_digest_list_pcr;
 	}
+#endif
 
 	entry->pcr = pcr;
 	result = ima_add_template_entry(entry, violation, op, inode, filename);
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (result) {
 		kfree(duplicated_entry);
 	} else if (duplicated_entry) {
@@ -141,6 +152,7 @@ int ima_store_template(struct ima_template_entry *entry,
 		if (result < 0)
 			kfree(duplicated_entry);
 	}
+#endif
 
 	return result;
 }
@@ -173,8 +185,13 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
 		result = -ENOMEM;
 		goto err_out;
 	}
+#ifdef CONFIG_IMA_DIGEST_LIST
 	result = ima_store_template(entry, violation, inode, filename,
 				    CONFIG_IMA_MEASURE_PCR_IDX, NULL);
+#else
+	result = ima_store_template(entry, violation, inode,
+				    filename, CONFIG_IMA_MEASURE_PCR_IDX);
+#endif
 	if (result < 0)
 		ima_free_template_entry(entry);
 err_out:
@@ -315,18 +332,30 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
  *
  * Must be called with iint->mutex held.
  */
+#ifdef CONFIG_IMA_DIGEST_LIST
 void ima_store_measurement(struct integrity_iint_cache *iint,
 			   struct file *file, const unsigned char *filename,
 			   struct evm_ima_xattr_data *xattr_value,
 			   int xattr_len, const struct modsig *modsig, int pcr,
 			   struct ima_template_desc *template_desc,
 			   struct ima_digest *digest)
+#else
+void ima_store_measurement(struct integrity_iint_cache *iint,
+			   struct file *file, const unsigned char *filename,
+			   struct evm_ima_xattr_data *xattr_value,
+			   int xattr_len, const struct modsig *modsig, int pcr,
+			   struct ima_template_desc *template_desc)
+#endif
 {
 	static const char op[] = "add_template_measure";
 	static const char audit_cause[] = "ENOMEM";
 	int result = -ENOMEM;
 	struct inode *inode = file_inode(file);
+#ifdef CONFIG_IMA_DIGEST_LIST
 	struct ima_template_entry *entry = NULL;
+#else
+	struct ima_template_entry *entry;
+#endif
 	struct ima_event_data event_data = { .iint = iint,
 					     .file = file,
 					     .filename = filename,
@@ -344,10 +373,12 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
 	if (iint->measured_pcrs & (0x1 << pcr) && !modsig)
 		return;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (digest && !ima_plus_standard_pcr && ima_digest_list_pcr >= 0) {
 		result = -EEXIST;
 		goto out;
 	}
+#endif
 
 	result = ima_alloc_init_template(&event_data, &entry, template_desc);
 	if (result < 0) {
@@ -356,14 +387,22 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
 		return;
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	result = ima_store_template(entry, violation, inode, filename, pcr,
 				    digest);
 out:
+#else
+	result = ima_store_template(entry, violation, inode, filename, pcr);
+#endif
 	if ((!result || result == -EEXIST) && !(file->f_flags & O_DIRECT)) {
 		iint->flags |= IMA_MEASURED;
 		iint->measured_pcrs |= (0x1 << pcr);
 	}
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (result < 0 && entry)
+#else
+	if (result < 0)
+#endif
 		ima_free_template_entry(entry);
 }
 
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 956fb0f4c006..e5e071fa8565 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -15,9 +15,11 @@
 #include <keys/system_keyring.h>
 
 #include "ima.h"
+#ifdef CONFIG_IMA_DIGEST_LIST
 #include "ima_digest_list.h"
 
 static bool ima_appraise_req_evm __ro_after_init;
+#endif
 static int __init default_appraise_setup(char *str)
 {
 #ifdef CONFIG_IMA_APPRAISE_BOOTPARAM
@@ -45,16 +47,18 @@ static int __init default_appraise_setup(char *str)
 		ima_appraise = appraisal_state;
 	}
 #endif
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (strcmp(str, "enforce-evm") == 0 ||
 	    strcmp(str, "log-evm") == 0)
 		ima_appraise_req_evm = true;
+#endif
 	return 1;
 }
 
 __setup("ima_appraise=", default_appraise_setup);
 
-static bool ima_appraise_no_metadata __ro_after_init;
 #ifdef CONFIG_IMA_DIGEST_LIST
+static bool ima_appraise_no_metadata __ro_after_init;
 static int __init appraise_digest_list_setup(char *str)
 {
 	if (!strncmp(str, "digest", 6)) {
@@ -108,9 +112,11 @@ static int ima_fix_xattr(struct dentry *dentry,
 	} else {
 		offset = 0;
 		iint->ima_hash->xattr.ng.type = IMA_XATTR_DIGEST_NG;
+#ifdef CONFIG_IMA_DIGEST_LIST
 		if (test_bit(IMA_DIGEST_LIST, &iint->atomic_flags))
 			iint->ima_hash->xattr.ng.type =
 						EVM_IMA_XATTR_DIGEST_LIST;
+#endif
 		iint->ima_hash->xattr.ng.algo = algo;
 	}
 	rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA,
@@ -189,6 +195,60 @@ static void ima_cache_flags(struct integrity_iint_cache *iint,
 	}
 }
 
+#ifndef CONFIG_IMA_DIGEST_LIST
+enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
+				 int xattr_len)
+{
+	struct signature_v2_hdr *sig;
+	enum hash_algo ret;
+
+	if (!xattr_value || xattr_len < 2)
+		/* return default hash algo */
+		return ima_hash_algo;
+
+	switch (xattr_value->type) {
+	case EVM_IMA_XATTR_DIGSIG:
+		sig = (typeof(sig))xattr_value;
+		if (sig->version != 2 || xattr_len <= sizeof(*sig))
+			return ima_hash_algo;
+		return sig->hash_algo;
+		break;
+	case IMA_XATTR_DIGEST_NG:
+		/* first byte contains algorithm id */
+		ret = xattr_value->data[0];
+		if (ret < HASH_ALGO__LAST)
+			return ret;
+		break;
+	case IMA_XATTR_DIGEST:
+		/* this is for backward compatibility */
+		if (xattr_len == 21) {
+			unsigned int zero = 0;
+			if (!memcmp(&xattr_value->data[16], &zero, 4))
+				return HASH_ALGO_MD5;
+			else
+				return HASH_ALGO_SHA1;
+		} else if (xattr_len == 17)
+			return HASH_ALGO_MD5;
+		break;
+	}
+
+	/* return default hash algo */
+	return ima_hash_algo;
+}
+
+int ima_read_xattr(struct dentry *dentry,
+		   struct evm_ima_xattr_data **xattr_value)
+{
+	ssize_t ret;
+
+	ret = vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)xattr_value,
+				 0, GFP_NOFS);
+	if (ret == -EOPNOTSUPP)
+		ret = 0;
+	return ret;
+}
+#endif
+
 /*
  * xattr_verify - verify xattr digest or signature
  *
@@ -196,18 +256,27 @@ static void ima_cache_flags(struct integrity_iint_cache *iint,
  *
  * Return 0 on success, error code otherwise.
  */
+#ifdef CONFIG_IMA_DIGEST_LIST
 static int xattr_verify(enum ima_hooks func, struct integrity_iint_cache *iint,
 			struct evm_ima_xattr_data *xattr_value, int xattr_len,
 			enum integrity_status *status, const char **cause,
 			struct ima_digest *found_digest)
+#else
+static int xattr_verify(enum ima_hooks func, struct integrity_iint_cache *iint,
+			struct evm_ima_xattr_data *xattr_value, int xattr_len,
+			enum integrity_status *status, const char **cause)
+#endif
 {
 	int rc = -EINVAL, hash_start = 0;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (found_digest && *status != INTEGRITY_PASS &&
 	    *status != INTEGRITY_PASS_IMMUTABLE)
 		set_bit(IMA_DIGEST_LIST, &iint->atomic_flags);
+#endif
 
 	switch (xattr_value->type) {
+#ifdef CONFIG_IMA_DIGEST_LIST
 	case EVM_IMA_XATTR_DIGEST_LIST:
 		set_bit(IMA_DIGEST_LIST, &iint->atomic_flags);
 
@@ -217,22 +286,27 @@ static int xattr_verify(enum ima_hooks func, struct integrity_iint_cache *iint,
 			break;
 		}
 		fallthrough;
+#endif
 	case IMA_XATTR_DIGEST_NG:
 		/* first byte contains algorithm id */
 		hash_start = 1;
 		fallthrough;
 	case IMA_XATTR_DIGEST:
+#ifdef CONFIG_IMA_DIGEST_LIST
 		if (*status != INTEGRITY_PASS_IMMUTABLE &&
 		    (!found_digest || !ima_digest_is_immutable(found_digest))) {
+#endif
 			if (iint->flags & IMA_DIGSIG_REQUIRED) {
 				*cause = "IMA-signature-required";
 				*status = INTEGRITY_FAIL;
 				break;
 			}
 			clear_bit(IMA_DIGSIG, &iint->atomic_flags);
+#ifdef CONFIG_IMA_DIGEST_LIST
 		} else {
 			set_bit(IMA_DIGSIG, &iint->atomic_flags);
 		}
+#endif
 		if (xattr_len - sizeof(xattr_value->type) - hash_start >=
 				iint->ima_hash->length)
 			/*
@@ -352,26 +426,39 @@ int ima_check_blacklist(struct integrity_iint_cache *iint,
  *
  * Return 0 on success, error code otherwise
  */
+#ifdef CONFIG_IMA_DIGEST_LIST
 int ima_appraise_measurement(enum ima_hooks func,
 			     struct integrity_iint_cache *iint,
 			     struct file *file, const unsigned char *filename,
 			     struct evm_ima_xattr_data *xattr_value,
 			     int xattr_len, const struct modsig *modsig,
 			     struct ima_digest *found_digest)
+#else
+int ima_appraise_measurement(enum ima_hooks func,
+			     struct integrity_iint_cache *iint,
+			     struct file *file, const unsigned char *filename,
+			     struct evm_ima_xattr_data *xattr_value,
+			     int xattr_len, const struct modsig *modsig)
+#endif
 {
 	static const char op[] = "appraise_data";
 	const char *cause = "unknown";
 	struct dentry *dentry = file_dentry(file);
 	struct inode *inode = d_backing_inode(dentry);
 	enum integrity_status status = INTEGRITY_UNKNOWN;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	int rc = xattr_len, rc_evm;
 	char _buf[sizeof(struct evm_ima_xattr_data) + 1 + SHA512_DIGEST_SIZE];
+#else
+	int rc = xattr_len;
+#endif
 	bool try_modsig = iint->flags & IMA_MODSIG_ALLOWED && modsig;
 
 	/* If not appraising a modsig, we need an xattr. */
 	if (!(inode->i_opflags & IOP_XATTR) && !try_modsig)
 		return INTEGRITY_UNKNOWN;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (xattr_value && xattr_value->type == EVM_IMA_XATTR_DIGSIG &&
 	    xattr_len == sizeof(struct signature_v2_hdr))
 		rc = -ENODATA;
@@ -394,6 +481,7 @@ int ima_appraise_measurement(enum ima_hooks func,
 			rc = xattr_len;
 		}
 	}
+#endif
 
 	/* If reading the xattr failed and there's no modsig, error out. */
 	if (rc <= 0 && !try_modsig) {
@@ -417,11 +505,15 @@ int ima_appraise_measurement(enum ima_hooks func,
 	switch (status) {
 	case INTEGRITY_PASS:
 	case INTEGRITY_PASS_IMMUTABLE:
+#ifdef CONFIG_IMA_DIGEST_LIST
 		break;
 	case INTEGRITY_UNKNOWN:
 		if (ima_appraise_req_evm &&
 		    xattr_value->type != EVM_IMA_XATTR_DIGSIG && !found_digest)
 			goto out;
+#else
+	case INTEGRITY_UNKNOWN:
+#endif
 		break;
 	case INTEGRITY_NOXATTRS:	/* No EVM protected xattrs. */
 		/* It's fine not to have xattrs when using a modsig. */
@@ -429,6 +521,7 @@ int ima_appraise_measurement(enum ima_hooks func,
 			break;
 		fallthrough;
 	case INTEGRITY_NOLABEL:		/* No security.evm xattr. */
+#ifdef CONFIG_IMA_DIGEST_LIST
 		/*
 		 * If the digest-nometadata mode is selected, allow access
 		 * without metadata check. EVM will eventually create an HMAC
@@ -446,11 +539,14 @@ int ima_appraise_measurement(enum ima_hooks func,
 			    ima_digest_is_immutable(found_digest))
 				break;
 		}
+#endif
 		cause = "missing-HMAC";
 		goto out;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	case INTEGRITY_FAIL_IMMUTABLE:
 		set_bit(IMA_DIGSIG, &iint->atomic_flags);
 		fallthrough;
+#endif
 	case INTEGRITY_FAIL:		/* Invalid HMAC/signature. */
 		cause = "invalid-HMAC";
 		goto out;
@@ -458,6 +554,7 @@ int ima_appraise_measurement(enum ima_hooks func,
 		WARN_ONCE(true, "Unexpected integrity status %d\n", status);
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if ((iint->flags & IMA_META_IMMUTABLE_REQUIRED) &&
 	    status != INTEGRITY_PASS_IMMUTABLE) {
 		status = INTEGRITY_FAIL;
@@ -466,10 +563,16 @@ int ima_appraise_measurement(enum ima_hooks func,
 				    filename, op, cause, rc, 0);
 		goto out;
 	}
+#endif
 
 	if (xattr_value)
+#ifdef CONFIG_IMA_DIGEST_LIST
 		rc = xattr_verify(func, iint, xattr_value, xattr_len, &status,
 				  &cause, found_digest);
+#else
+		rc = xattr_verify(func, iint, xattr_value, xattr_len, &status,
+				  &cause);
+#endif
 
 	/*
 	 * If we have a modsig and either no imasig or the imasig's key isn't
@@ -503,6 +606,7 @@ int ima_appraise_measurement(enum ima_hooks func,
 				status = INTEGRITY_PASS;
 		}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 		/*
 		 * Permit new files with file/EVM portable signatures, but
 		 * without data.
@@ -511,6 +615,13 @@ int ima_appraise_measurement(enum ima_hooks func,
 		    test_bit(IMA_DIGSIG, &iint->atomic_flags)) {
 			status = INTEGRITY_PASS;
 		}
+#else
+		/* Permit new files with file signatures, but without data. */
+		if (inode->i_size == 0 && iint->flags & IMA_NEW_FILE &&
+		    xattr_value && xattr_value->type == EVM_IMA_XATTR_DIGSIG) {
+			status = INTEGRITY_PASS;
+		}
+#endif
 
 		integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename,
 				    op, cause, rc, 0);
@@ -567,6 +678,10 @@ void ima_inode_post_setattr(struct dentry *dentry)
 		return;
 
 	action = ima_must_appraise(inode, MAY_ACCESS, POST_SETATTR);
+#ifndef CONFIG_IMA_DIGEST_LIST
+	if (!action)
+		__vfs_removexattr(dentry, XATTR_NAME_IMA);
+#endif
 	iint = integrity_iint_find(inode);
 	if (iint) {
 		set_bit(IMA_CHANGE_ATTR, &iint->atomic_flags);
@@ -620,11 +735,16 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
 	if (result == 1) {
 		if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST))
 			return -EINVAL;
+#ifndef CONFIG_IMA_DIGEST_LIST
+		ima_reset_appraise_flags(d_backing_inode(dentry),
+			xvalue->type == EVM_IMA_XATTR_DIGSIG);
+#endif
 		result = 0;
 	}
 	return result;
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 void ima_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
 			     const void *xattr_value, size_t xattr_value_len)
 {
@@ -641,6 +761,7 @@ void ima_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
 	if (result == 1 || evm_status_revalidate(xattr_name))
 		ima_reset_appraise_flags(d_backing_inode(dentry), digsig);
 }
+#endif
 
 int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name)
 {
@@ -648,11 +769,15 @@ int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name)
 
 	result = ima_protect_xattr(dentry, xattr_name, NULL, 0);
 	if (result == 1) {
+#ifndef CONFIG_IMA_DIGEST_LIST
+		ima_reset_appraise_flags(d_backing_inode(dentry), 0);
+#endif
 		result = 0;
 	}
 	return result;
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 void ima_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
 {
 	int result;
@@ -661,3 +786,4 @@ void ima_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
 	if (result == 1 || evm_status_revalidate(xattr_name))
 		ima_reset_appraise_flags(d_backing_inode(dentry), 0);
 }
+#endif
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index f1bc3e201bd8..4ceee381d58b 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -21,11 +21,15 @@
 #include <linux/rcupdate.h>
 #include <linux/parser.h>
 #include <linux/vmalloc.h>
+#ifdef CONFIG_IMA_DIGEST_LIST
 #include <linux/file.h>
+#endif
 #include <linux/ctype.h>
 
 #include "ima.h"
+#ifdef CONFIG_IMA_DIGEST_LIST
 #include "ima_digest_list.h"
+#endif
 
 static DEFINE_MUTEX(ima_write_mutex);
 
@@ -36,9 +40,11 @@ static struct dentry *ascii_runtime_measurements;
 static struct dentry *runtime_measurements_count;
 static struct dentry *violations;
 static struct dentry *ima_policy;
+#ifdef CONFIG_IMA_DIGEST_LIST
 static struct dentry *digests_count;
 static struct dentry *digest_list_data;
 static struct dentry *digest_list_data_del;
+#endif
 
 bool ima_canonical_fmt;
 static int __init default_canonical_fmt_setup(char *str)
@@ -52,6 +58,7 @@ __setup("ima_canonical_fmt", default_canonical_fmt_setup);
 
 static int valid_policy = 1;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static ssize_t ima_show_htable_value(struct file *filp, char __user *buf,
 				     size_t count, loff_t *ppos)
 {
@@ -63,19 +70,54 @@ static ssize_t ima_show_htable_value(struct file *filp, char __user *buf,
 		val = &ima_htable.violations;
 	else if (filp->f_path.dentry == runtime_measurements_count)
 		val = &ima_htable.len;
-#ifdef CONFIG_IMA_DIGEST_LIST
 	else if (filp->f_path.dentry == digests_count)
 		val = &ima_digests_htable.len;
-#endif
 
 	len = scnprintf(tmpbuf, sizeof(tmpbuf), "%li\n", atomic_long_read(val));
 	return simple_read_from_buffer(buf, count, ppos, tmpbuf, len);
 }
+#else
+static ssize_t ima_show_htable_value(char __user *buf, size_t count,
+				     loff_t *ppos, atomic_long_t *val)
+{
+	char tmpbuf[32];	/* greater than largest 'long' string value */
+	ssize_t len;
+	len = scnprintf(tmpbuf, sizeof(tmpbuf), "%li\n", atomic_long_read(val));
+	return simple_read_from_buffer(buf, count, ppos, tmpbuf, len);
+}
+#endif
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static const struct file_operations ima_htable_value_ops = {
 	.read = ima_show_htable_value,
 	.llseek = generic_file_llseek,
 };
+#else
+static ssize_t ima_show_htable_violations(struct file *filp,
+					  char __user *buf,
+					  size_t count, loff_t *ppos)
+{
+	return ima_show_htable_value(buf, count, ppos, &ima_htable.violations);
+}
+
+static const struct file_operations ima_htable_violations_ops = {
+	.read = ima_show_htable_violations,
+	.llseek = generic_file_llseek,
+};
+
+static ssize_t ima_show_measurements_count(struct file *filp,
+					   char __user *buf,
+					   size_t count, loff_t *ppos)
+{
+	return ima_show_htable_value(buf, count, ppos, &ima_htable.len);
+
+}
+
+static const struct file_operations ima_measurements_count_ops = {
+	.read = ima_show_measurements_count,
+	.llseek = generic_file_llseek,
+};
+#endif
 
 /* returns pointer to hlist_node */
 static void *ima_measurements_start(struct seq_file *m, loff_t *pos)
@@ -275,6 +317,7 @@ static const struct file_operations ima_ascii_measurements_ops = {
 	.release = seq_release,
 };
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static ssize_t ima_read_file(char *path, struct dentry *dentry)
 {
 	void *data = NULL;
@@ -320,7 +363,6 @@ static ssize_t ima_read_file(char *path, struct dentry *dentry)
 			rc = ima_parse_add_rule(p);
 		} else if (dentry == digest_list_data ||
 			   dentry == digest_list_data_del) {
-#ifdef CONFIG_IMA_DIGEST_LIST
 			/* Only check size when adding digest lists */
 			if (dentry == digest_list_data &&
 			    size > ima_digest_db_max_size - ima_digest_db_size) {
@@ -328,7 +370,6 @@ static ssize_t ima_read_file(char *path, struct dentry *dentry)
 				rc = -ENOMEM;
 				break;
 			}
-#endif
 			/*
 			 * Disable usage of digest lists if not measured
 			 * or appraised.
@@ -343,12 +384,10 @@ static ssize_t ima_read_file(char *path, struct dentry *dentry)
 
 		if (rc < 0)
 			break;
-#ifdef CONFIG_IMA_DIGEST_LIST
 		else if (dentry == digest_list_data)
 			pr_debug("digest imported, current DB size: %d\n", ima_digest_db_size);
 		else if (dentry == digest_list_data_del)
 			pr_debug("digest deleted, current DB size: %d\n", ima_digest_db_size);
-#endif
 		size -= rc;
 	}
 
@@ -461,6 +500,104 @@ static enum ima_fs_flags ima_get_dentry_flag(struct dentry *dentry)
 
 	return flag;
 }
+#else
+static ssize_t ima_read_policy(char *path)
+{
+	void *data = NULL;
+	char *datap;
+	size_t size;
+	int rc, pathlen = strlen(path);
+
+	char *p;
+
+	/* remove \n */
+	datap = path;
+	strsep(&datap, "\n");
+
+	rc = kernel_read_file_from_path(path, 0, &data, INT_MAX, NULL,
+					READING_POLICY);
+	if (rc < 0) {
+		pr_err("Unable to open file: %s (%d)", path, rc);
+		return rc;
+	}
+	size = rc;
+	rc = 0;
+
+	datap = data;
+	while (size > 0 && (p = strsep(&datap, "\n"))) {
+		pr_debug("rule: %s\n", p);
+		rc = ima_parse_add_rule(p);
+		if (rc < 0)
+			break;
+		size -= rc;
+	}
+
+	vfree(data);
+	if (rc < 0)
+		return rc;
+	else if (size)
+		return -EINVAL;
+	else
+		return pathlen;
+}
+
+static ssize_t ima_write_policy(struct file *file, const char __user *buf,
+				size_t datalen, loff_t *ppos)
+{
+	char *data;
+	ssize_t result;
+
+	if (datalen >= PAGE_SIZE)
+		datalen = PAGE_SIZE - 1;
+
+	/* No partial writes. */
+	result = -EINVAL;
+	if (*ppos != 0)
+		goto out;
+
+	data = memdup_user_nul(buf, datalen);
+	if (IS_ERR(data)) {
+		result = PTR_ERR(data);
+		goto out;
+	}
+
+	result = mutex_lock_interruptible(&ima_write_mutex);
+	if (result < 0)
+		goto out_free;
+
+	if (data[0] == '/') {
+		result = ima_read_policy(data);
+	} else if (ima_appraise & IMA_APPRAISE_POLICY) {
+		pr_err("signed policy file (specified as an absolute pathname) required\n");
+		integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
+				    "policy_update", "signed policy required",
+				    1, 0);
+		result = -EACCES;
+	} else {
+		result = ima_parse_add_rule(data);
+	}
+	mutex_unlock(&ima_write_mutex);
+out_free:
+	kfree(data);
+out:
+	if (result < 0)
+		valid_policy = 0;
+
+	return result;
+}
+
+static struct dentry *ima_dir;
+static struct dentry *ima_symlink;
+static struct dentry *binary_runtime_measurements;
+static struct dentry *ascii_runtime_measurements;
+static struct dentry *runtime_measurements_count;
+static struct dentry *violations;
+static struct dentry *ima_policy;
+
+enum ima_fs_flags {
+	IMA_FS_BUSY,
+};
+#endif
 
 static unsigned long ima_fs_flags;
 
@@ -473,6 +610,7 @@ static const struct seq_operations ima_policy_seqops = {
 };
 #endif
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 /*
  * ima_open_data_upload: sequentialize access to the data upload interface
  */
@@ -568,6 +706,79 @@ static const struct file_operations ima_data_upload_ops = {
 	.release = ima_release_data_upload,
 	.llseek = generic_file_llseek,
 };
+#else
+/*
+ * ima_open_policy: sequentialize access to the policy file
+ */
+static int ima_open_policy(struct inode *inode, struct file *filp)
+{
+	if (!(filp->f_flags & O_WRONLY)) {
+#ifndef	CONFIG_IMA_READ_POLICY
+		return -EACCES;
+#else
+		if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
+			return -EACCES;
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+		return seq_open(filp, &ima_policy_seqops);
+#endif
+	}
+	if (test_and_set_bit(IMA_FS_BUSY, &ima_fs_flags))
+		return -EBUSY;
+	return 0;
+}
+
+/*
+ * ima_release_policy - start using the new measure policy rules.
+ *
+ * Initially, ima_measure points to the default policy rules, now
+ * point to the new policy rules, and remove the securityfs policy file,
+ * assuming a valid policy.
+ */
+static int ima_release_policy(struct inode *inode, struct file *file)
+{
+	const char *cause = valid_policy ? "completed" : "failed";
+
+	if ((file->f_flags & O_ACCMODE) == O_RDONLY)
+		return seq_release(inode, file);
+
+	if (valid_policy && ima_check_policy() < 0) {
+		cause = "failed";
+		valid_policy = 0;
+	}
+
+	pr_info("policy update %s\n", cause);
+	integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
+			    "policy_update", cause, !valid_policy, 0);
+
+	if (!valid_policy) {
+		ima_delete_rules();
+		valid_policy = 1;
+		clear_bit(IMA_FS_BUSY, &ima_fs_flags);
+		return 0;
+	}
+
+	ima_update_policy();
+#if !defined(CONFIG_IMA_WRITE_POLICY) && !defined(CONFIG_IMA_READ_POLICY)
+	securityfs_remove(ima_policy);
+	ima_policy = NULL;
+#elif defined(CONFIG_IMA_WRITE_POLICY)
+	clear_bit(IMA_FS_BUSY, &ima_fs_flags);
+#elif defined(CONFIG_IMA_READ_POLICY)
+	inode->i_mode &= ~S_IWUSR;
+#endif
+	return 0;
+}
+
+static const struct file_operations ima_measure_policy_ops = {
+	.open = ima_open_policy,
+	.write = ima_write_policy,
+	.read = seq_read,
+	.release = ima_release_policy,
+	.llseek = generic_file_llseek,
+};
+
+#endif
 
 int __init ima_fs_init(void)
 {
@@ -594,6 +805,7 @@ int __init ima_fs_init(void)
 	if (IS_ERR(ascii_runtime_measurements))
 		goto out;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	runtime_measurements_count =
 	    securityfs_create_file("runtime_measurements_count",
 				   S_IRUSR | S_IRGRP, ima_dir, NULL,
@@ -613,7 +825,6 @@ int __init ima_fs_init(void)
 	if (IS_ERR(ima_policy))
 		goto out;
 
-#ifdef CONFIG_IMA_DIGEST_LIST
 	digests_count = securityfs_create_file("digests_count",
 					       S_IRUSR | S_IRGRP, ima_dir,
 					       NULL, &ima_htable_value_ops);
@@ -631,12 +842,34 @@ int __init ima_fs_init(void)
 						      &ima_data_upload_ops);
 	if (IS_ERR(digest_list_data_del))
 		goto out;
+#else
+	runtime_measurements_count =
+	    securityfs_create_file("runtime_measurements_count",
+				   S_IRUSR | S_IRGRP, ima_dir, NULL,
+				   &ima_measurements_count_ops);
+	if (IS_ERR(runtime_measurements_count))
+		goto out;
+
+	violations =
+	    securityfs_create_file("violations", S_IRUSR | S_IRGRP,
+				   ima_dir, NULL, &ima_htable_violations_ops);
+	if (IS_ERR(violations))
+		goto out;
+
+	ima_policy = securityfs_create_file("policy", POLICY_FILE_FLAGS,
+					    ima_dir, NULL,
+					    &ima_measure_policy_ops);
+	if (IS_ERR(ima_policy))
+		goto out;
+
 #endif
 	return 0;
 out:
+#ifdef CONFIG_IMA_DIGEST_LIST
 	securityfs_remove(digest_list_data_del);
 	securityfs_remove(digest_list_data);
 	securityfs_remove(digests_count);
+#endif
 	securityfs_remove(ima_policy);
 	securityfs_remove(violations);
 	securityfs_remove(runtime_measurements_count);
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index 913d6b879b0b..085e8a049f51 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -84,9 +84,15 @@ static int __init ima_add_boot_aggregate(void)
 		goto err_out;
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	result = ima_store_template(entry, violation, NULL,
 				    boot_aggregate_name,
 				    CONFIG_IMA_MEASURE_PCR_IDX, NULL);
+#else
+	result = ima_store_template(entry, violation, NULL,
+				    boot_aggregate_name,
+				    CONFIG_IMA_MEASURE_PCR_IDX);
+#endif
 	if (result < 0) {
 		ima_free_template_entry(entry);
 		audit_cause = "store_entry";
@@ -107,8 +113,10 @@ void __init ima_load_x509(void)
 	ima_policy_flag &= ~unset_flags;
 	integrity_load_x509(INTEGRITY_KEYRING_IMA, CONFIG_IMA_X509_PATH);
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	/* load also EVM key to avoid appraisal */
 	evm_load_x509();
+#endif
 
 	ima_policy_flag |= unset_flags;
 }
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 999d5904cce0..c4121330a647 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -28,7 +28,9 @@
 #include <linux/fs.h>
 
 #include "ima.h"
+#ifdef CONFIG_IMA_DIGEST_LIST
 #include "ima_digest_list.h"
+#endif
 
 #ifdef CONFIG_IMA_APPRAISE
 int ima_appraise = IMA_APPRAISE_ENFORCE;
@@ -38,12 +40,14 @@ int ima_appraise;
 
 int ima_hash_algo = HASH_ALGO_SHA1;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 /* Actions (measure/appraisal) for which digest lists can be used */
 int ima_digest_list_actions;
 /* PCR used for digest list measurements */
 int ima_digest_list_pcr = -1;
 /* Flag to include standard measurement if digest list PCR is specified */
 bool ima_plus_standard_pcr;
+#endif
 
 static int hash_setup_done;
 
@@ -156,6 +160,7 @@ static void ima_rdwr_violation_check(struct file *file,
 				  "invalid_pcr", "open_writers");
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
 					int xattr_len)
 {
@@ -209,6 +214,7 @@ static int ima_read_xattr(struct dentry *dentry,
 		ret = 0;
 	return ret;
 }
+#endif
 
 static void ima_check_last_writer(struct integrity_iint_cache *iint,
 				  struct inode *inode, struct file *file)
@@ -268,7 +274,9 @@ static int process_measurement(struct file *file, const struct cred *cred,
 	const char *pathname = NULL;
 	int rc = 0, action, must_appraise = 0;
 	int pcr = CONFIG_IMA_MEASURE_PCR_IDX;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	struct ima_digest *found_digest;
+#endif
 	struct evm_ima_xattr_data *xattr_value = NULL;
 	struct modsig *modsig = NULL;
 	int xattr_len = 0;
@@ -398,28 +406,42 @@ static int process_measurement(struct file *file, const struct cred *cred,
 	if (!pathbuf)	/* ima_rdwr_violation possibly pre-fetched */
 		pathname = ima_d_path(&file->f_path, &pathbuf, filename);
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (!pathname || strlen(pathname) > IMA_EVENT_NAME_LEN_MAX)
 		pathname = file->f_path.dentry->d_name.name;
 
 	found_digest = ima_lookup_digest(iint->ima_hash->digest, hash_algo,
 					 COMPACT_FILE);
+#endif
 
 	if (action & IMA_MEASURE)
+#ifdef CONFIG_IMA_DIGEST_LIST
 		ima_store_measurement(iint, file, pathname,
 				      xattr_value, xattr_len, modsig, pcr,
 				      template_desc,
 				      ima_digest_allow(found_digest,
 						       IMA_MEASURE));
+#else
+		ima_store_measurement(iint, file, pathname,
+				      xattr_value, xattr_len, modsig, pcr,
+				      template_desc);
+#endif
 
 	if (rc == 0 && (action & IMA_APPRAISE_SUBMASK)) {
 		rc = ima_check_blacklist(iint, modsig, pcr);
 		if (rc != -EPERM) {
 			inode_lock(inode);
+#ifdef CONFIG_IMA_DIGEST_LIST
 			rc = ima_appraise_measurement(func, iint, file,
 					      pathname, xattr_value,
 					      xattr_len, modsig,
 					      ima_digest_allow(found_digest,
 							       IMA_APPRAISE));
+#else
+			rc = ima_appraise_measurement(func, iint, file,
+					      pathname, xattr_value,
+					      xattr_len, modsig);
+#endif
 			inode_unlock(inode);
 		}
 		if (!rc)
@@ -568,15 +590,21 @@ int ima_bprm_check(struct linux_binprm *bprm)
 int ima_file_check(struct file *file, int mask)
 {
 	u32 secid;
-	int rc;
 
 	security_task_getsecid(current, &secid);
+#ifdef CONFIG_IMA_DIGEST_LIST
+	int rc;
 	rc = process_measurement(file, current_cred(), secid, NULL, 0,
 				 mask & (MAY_READ | MAY_WRITE | MAY_EXEC |
 					 MAY_APPEND), FILE_CHECK);
 	if (ima_current_is_parser() && !rc)
 		ima_check_measured_appraised(file);
 	return rc;
+#else
+	return process_measurement(file, current_cred(), secid, NULL, 0,
+				 mask & (MAY_READ | MAY_WRITE | MAY_EXEC |
+					 MAY_APPEND), FILE_CHECK);
+#endif
 }
 EXPORT_SYMBOL_GPL(ima_file_check);
 
@@ -739,7 +767,9 @@ const int read_idmap[READING_MAX_ID] = {
 	[READING_KEXEC_IMAGE] = KEXEC_KERNEL_CHECK,
 	[READING_KEXEC_INITRAMFS] = KEXEC_INITRAMFS_CHECK,
 	[READING_POLICY] = POLICY_CHECK,
+#ifdef CONFIG_IMA_DIGEST_LIST
 	[READING_DIGEST_LIST] = DIGEST_LIST_CHECK
+#endif
 };
 
 /**
@@ -941,7 +971,11 @@ void process_buffer_measurement(struct inode *inode, const void *buf, int size,
 		goto out;
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	ret = ima_store_template(entry, violation, NULL, buf, pcr, NULL);
+#else
+	ret = ima_store_template(entry, violation, NULL, buf, pcr);
+#endif
 	if (ret < 0) {
 		audit_cause = "store_entry";
 		ima_free_template_entry(entry);
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 274f4c7c99f4..3e14b55ecf0f 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -21,7 +21,9 @@
 #include <linux/ima.h>
 
 #include "ima.h"
+#ifdef CONFIG_IMA_DIGEST_LIST
 #include "ima_digest_list.h"
+#endif
 
 /* flags definitions */
 #define IMA_FUNC	0x0001
@@ -35,7 +37,9 @@
 #define IMA_PCR		0x0100
 #define IMA_FSNAME	0x0200
 #define IMA_KEYRINGS	0x0400
+#ifdef CONFIG_IMA_DIGEST_LIST
 #define IMA_PARSER	0x0800
+#endif
 
 #define UNKNOWN		0
 #define MEASURE		0x0001	/* same as IMA_MEASURE */
@@ -58,7 +62,11 @@ enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE,
 	LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE
 };
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 enum policy_types { ORIGINAL_TCB = 1, DEFAULT_TCB, EXEC_TCB };
+#else
+enum policy_types { ORIGINAL_TCB = 1, DEFAULT_TCB };
+#endif
 
 enum policy_rule_list { IMA_DEFAULT_POLICY = 1, IMA_CUSTOM_POLICY };
 
@@ -145,11 +153,13 @@ static struct ima_rule_entry default_measurement_rules[] __ro_after_init = {
 	{.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC},
 	{.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC},
 	{.action = MEASURE, .func = POLICY_CHECK, .flags = IMA_FUNC},
+#ifdef CONFIG_IMA_DIGEST_LIST
 	{.action = MEASURE, .func = DIGEST_LIST_CHECK, .flags = IMA_FUNC},
 };
 
 static struct ima_rule_entry ima_parser_measure_rule __ro_after_init = {
 	.action = MEASURE, .flags = IMA_PARSER
+#endif
 };
 
 static struct ima_rule_entry default_appraise_rules[] __ro_after_init = {
@@ -181,12 +191,14 @@ static struct ima_rule_entry default_appraise_rules[] __ro_after_init = {
 #endif
 };
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static struct ima_rule_entry appraise_exec_rules[] __ro_after_init = {
 	{.action = APPRAISE, .func = BPRM_CHECK,
 	 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
 	{.action = APPRAISE, .func = MMAP_CHECK,
 	 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
 };
+#endif
 
 static struct ima_rule_entry build_appraise_rules[] __ro_after_init = {
 #ifdef CONFIG_IMA_APPRAISE_REQUIRE_MODULE_SIGS
@@ -216,6 +228,7 @@ static struct ima_rule_entry secure_boot_rules[] __ro_after_init = {
 	 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
 	{.action = APPRAISE, .func = POLICY_CHECK,
 	 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
+#ifdef CONFIG_IMA_DIGEST_LIST
 	{.action = APPRAISE, .func = DIGEST_LIST_CHECK,
 	 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
 };
@@ -223,6 +236,7 @@ static struct ima_rule_entry secure_boot_rules[] __ro_after_init = {
 static struct ima_rule_entry ima_parser_appraise_rule __ro_after_init = {
 	.action = APPRAISE,
 	.flags = IMA_PARSER | IMA_DIGSIG_REQUIRED
+#endif
 };
 
 /* An array of architecture specific rules */
@@ -246,8 +260,10 @@ static int __init default_measure_policy_setup(char *str)
 __setup("ima_tcb", default_measure_policy_setup);
 
 static bool ima_use_appraise_tcb __initdata;
+#ifdef CONFIG_IMA_DIGEST_LIST
 static bool ima_use_appraise_exec_tcb __initdata;
 static bool ima_use_appraise_exec_immutable __initdata;
+#endif
 static bool ima_use_secure_boot __initdata;
 static bool ima_fail_unverifiable_sigs __ro_after_init;
 static int __init policy_setup(char *str)
@@ -259,14 +275,18 @@ static int __init policy_setup(char *str)
 			continue;
 		if ((strcmp(p, "tcb") == 0) && !ima_policy)
 			ima_policy = DEFAULT_TCB;
+#ifdef CONFIG_IMA_DIGEST_LIST
 		else if ((strcmp(p, "exec_tcb") == 0) && !ima_policy)
 			ima_policy = EXEC_TCB;
+#endif
 		else if (strcmp(p, "appraise_tcb") == 0)
 			ima_use_appraise_tcb = true;
+#ifdef CONFIG_IMA_DIGEST_LIST
 		else if (strcmp(p, "appraise_exec_tcb") == 0)
 			ima_use_appraise_exec_tcb = true;
 		else if (strcmp(p, "appraise_exec_immutable") == 0)
 			ima_use_appraise_exec_immutable = true;
+#endif
 		else if (strcmp(p, "secure_boot") == 0)
 			ima_use_secure_boot = true;
 		else if (strcmp(p, "fail_securely") == 0)
@@ -569,9 +589,11 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
 	if ((rule->flags & IMA_FOWNER) &&
 	    !rule->fowner_op(inode->i_uid, rule->fowner))
 		return false;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if ((rule->flags & IMA_PARSER) &&
 	    !ima_current_is_parser())
 		return false;
+#endif
 	for (i = 0; i < MAX_LSM_RULES; i++) {
 		int rc = 0;
 		u32 osid;
@@ -752,19 +774,27 @@ static int ima_appraise_flag(enum ima_hooks func)
 		return IMA_APPRAISE_POLICY;
 	else if (func == KEXEC_KERNEL_CHECK)
 		return IMA_APPRAISE_KEXEC;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	else if (func == DIGEST_LIST_CHECK)
 		return IMA_APPRAISE_DIGEST_LIST;
+#endif
 	return 0;
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static void __init add_rules(struct ima_rule_entry *entries, int count,
 			     enum policy_rule_list policy_rule)
+#else
+static void add_rules(struct ima_rule_entry *entries, int count,
+			     enum policy_rule_list policy_rule)
+#endif
 {
 	int i = 0;
 
 	for (i = 0; i < count; i++) {
 		struct ima_rule_entry *entry;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 		if (ima_policy == EXEC_TCB) {
 			if (entries == dont_measure_rules)
 				if ((entries[i].flags & IMA_FSMAGIC) &&
@@ -792,6 +822,7 @@ static void __init add_rules(struct ima_rule_entry *entries, int count,
 			    (entries[i].flags & IMA_FUNC) &&
 			    entries[i].func == BPRM_CHECK)
 				entries[i].flags |= IMA_META_IMMUTABLE_REQUIRED;
+#endif
 
 		if (policy_rule & IMA_DEFAULT_POLICY)
 			list_add_tail(&entries[i].list, &ima_default_rules);
@@ -879,8 +910,10 @@ void __init ima_init_policy(void)
 			  ARRAY_SIZE(original_measurement_rules),
 			  IMA_DEFAULT_POLICY);
 		break;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	case EXEC_TCB:
 		fallthrough;
+#endif
 	case DEFAULT_TCB:
 		add_rules(default_measurement_rules,
 			  ARRAY_SIZE(default_measurement_rules),
@@ -889,8 +922,10 @@ void __init ima_init_policy(void)
 		break;
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (ima_policy)
 		add_rules(&ima_parser_measure_rule, 1, IMA_DEFAULT_POLICY);
+#endif
 
 	/*
 	 * Based on runtime secure boot flags, insert arch specific measurement
@@ -909,7 +944,11 @@ void __init ima_init_policy(void)
 	 * Insert the builtin "secure_boot" policy rules requiring file
 	 * signatures, prior to other appraise rules.
 	 */
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (ima_use_secure_boot || ima_use_appraise_exec_tcb)
+#else
+	if (ima_use_secure_boot)
+#endif
 		add_rules(secure_boot_rules, ARRAY_SIZE(secure_boot_rules),
 			  IMA_DEFAULT_POLICY);
 
@@ -929,11 +968,16 @@ void __init ima_init_policy(void)
 				  IMA_DEFAULT_POLICY | IMA_CUSTOM_POLICY);
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (ima_use_appraise_tcb || ima_use_appraise_exec_tcb)
+#else
+	if (ima_use_appraise_tcb)
+#endif
 		add_rules(default_appraise_rules,
 			  ARRAY_SIZE(default_appraise_rules),
 			  IMA_DEFAULT_POLICY);
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (ima_use_appraise_exec_tcb)
 		add_rules(appraise_exec_rules,
 			  ARRAY_SIZE(appraise_exec_rules),
@@ -942,6 +986,7 @@ void __init ima_init_policy(void)
 	if (ima_use_secure_boot || ima_use_appraise_tcb ||
 	    ima_use_appraise_exec_tcb)
 		add_rules(&ima_parser_appraise_rule, 1, IMA_DEFAULT_POLICY);
+#endif
 
 	ima_update_policy_flag();
 }
@@ -1002,7 +1047,11 @@ enum {
 	Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt,
 	Opt_appraise_type, Opt_appraise_flag,
 	Opt_permit_directio, Opt_pcr, Opt_template, Opt_keyrings,
+#ifdef CONFIG_IMA_DIGEST_LIST
 	Opt_parser, Opt_err
+#else
+	Opt_err
+#endif
 };
 
 static const match_table_t policy_tokens = {
@@ -1039,7 +1088,9 @@ static const match_table_t policy_tokens = {
 	{Opt_pcr, "pcr=%s"},
 	{Opt_template, "template=%s"},
 	{Opt_keyrings, "keyrings=%s"},
+#ifdef CONFIG_IMA_DIGEST_LIST
 	{Opt_parser, "parser"},
+#endif
 	{Opt_err, NULL}
 };
 
@@ -1134,9 +1185,14 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
 	if (entry->action != MEASURE && entry->flags & IMA_PCR)
 		return false;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (entry->action != APPRAISE &&
 	    entry->flags & (IMA_DIGSIG_REQUIRED | IMA_MODSIG_ALLOWED |
 			    IMA_CHECK_BLACKLIST | IMA_META_IMMUTABLE_REQUIRED))
+#else
+	if (entry->action != APPRAISE &&
+	    entry->flags & (IMA_DIGSIG_REQUIRED | IMA_MODSIG_ALLOWED | IMA_CHECK_BLACKLIST))
+#endif
 		return false;
 
 	/*
@@ -1162,13 +1218,19 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
 	case POST_SETATTR:
 	case FIRMWARE_CHECK:
 	case POLICY_CHECK:
+#ifdef CONFIG_IMA_DIGEST_LIST
 	case DIGEST_LIST_CHECK:
+#endif
 		if (entry->flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC |
 				     IMA_UID | IMA_FOWNER | IMA_FSUUID |
 				     IMA_INMASK | IMA_EUID | IMA_PCR |
 				     IMA_FSNAME | IMA_DIGSIG_REQUIRED |
+#ifdef CONFIG_IMA_DIGEST_LIST
 				     IMA_PERMIT_DIRECTIO |
 				     IMA_META_IMMUTABLE_REQUIRED | IMA_PARSER))
+#else
+					 IMA_PERMIT_DIRECTIO))
+#endif
 			return false;
 
 		break;
@@ -1180,8 +1242,12 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
 				     IMA_INMASK | IMA_EUID | IMA_PCR |
 				     IMA_FSNAME | IMA_DIGSIG_REQUIRED |
 				     IMA_PERMIT_DIRECTIO | IMA_MODSIG_ALLOWED |
+#ifdef CONFIG_IMA_DIGEST_LIST
 				     IMA_CHECK_BLACKLIST |
 				     IMA_META_IMMUTABLE_REQUIRED))
+#else
+				     IMA_CHECK_BLACKLIST))
+#endif
 			return false;
 
 		break;
@@ -1338,8 +1404,10 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 			else if (IS_ENABLED(CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS) &&
 				 strcmp(args[0].from, "KEY_CHECK") == 0)
 				entry->func = KEY_CHECK;
+#ifdef CONFIG_IMA_DIGEST_LIST
 			else if (strcmp(args[0].from, "DIGEST_LIST_CHECK") == 0)
 				entry->func = DIGEST_LIST_CHECK;
+#endif
 			else
 				result = -EINVAL;
 			if (!result)
@@ -1526,8 +1594,10 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 				 strcmp(args[0].from, "imasig|modsig") == 0)
 				entry->flags |= IMA_DIGSIG_REQUIRED |
 						IMA_MODSIG_ALLOWED;
+#ifdef CONFIG_IMA_DIGEST_LIST
 			else if (strcmp(args[0].from, "meta_immutable") == 0)
 				entry->flags |= IMA_META_IMMUTABLE_REQUIRED;
+#endif
 			else
 				result = -EINVAL;
 			break;
@@ -1546,8 +1616,12 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 			ima_log_string(ab, "pcr", args[0].from);
 
 			result = kstrtoint(args[0].from, 10, &entry->pcr);
+#ifdef CONFIG_IMA_DIGEST_LIST
 			if (result || INVALID_PCR(entry->pcr) ||
 			    entry->pcr == ima_digest_list_pcr)
+#else
+			if (result || INVALID_PCR(entry->pcr))
+#endif
 				result = -EINVAL;
 			else
 				entry->flags |= IMA_PCR;
@@ -1574,10 +1648,12 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 						 &(template_desc->fields),
 						 &(template_desc->num_fields));
 			entry->template = template_desc;
+#ifdef CONFIG_IMA_DIGEST_LIST
 			break;
 		case Opt_parser:
 			audit_log_format(ab, "parser ");
 			entry->flags |= IMA_PARSER;
+#endif
 			break;
 		case Opt_err:
 			ima_log_string(ab, "UNKNOWN", p);
@@ -1849,8 +1925,10 @@ int ima_policy_show(struct seq_file *m, void *v)
 		seq_puts(m, " ");
 	}
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (entry->flags & IMA_PARSER)
 		seq_puts(m, "parser ");
+#endif
 
 	for (i = 0; i < MAX_LSM_RULES; i++) {
 		if (entry->lsm[i].rule) {
@@ -1893,8 +1971,10 @@ int ima_policy_show(struct seq_file *m, void *v)
 	}
 	if (entry->flags & IMA_CHECK_BLACKLIST)
 		seq_puts(m, "appraise_flag=check_blacklist ");
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (entry->flags & IMA_META_IMMUTABLE_REQUIRED)
 		seq_puts(m, "appraise_type=meta_immutable ");
+#endif
 	if (entry->flags & IMA_PERMIT_DIRECTIO)
 		seq_puts(m, "permit_directio ");
 	rcu_read_unlock();
diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
index 6f126dbd2b39..a40098347f81 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -45,8 +45,10 @@ static const struct ima_template_field supported_fields[] = {
 	{.field_id = "d-modsig", .field_init = ima_eventdigest_modsig_init,
 	 .field_show = ima_show_template_digest_ng},
 	{.field_id = "modsig", .field_init = ima_eventmodsig_init,
+#ifdef CONFIG_IMA_DIGEST_LIST
 	 .field_show = ima_show_template_sig},
 	{.field_id = "evmsig", .field_init = ima_eventevmsig_init,
+#endif
 	 .field_show = ima_show_template_sig},
 };
 
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
index 90040fac150b..7308ee587314 100644
--- a/security/integrity/ima/ima_template_lib.c
+++ b/security/integrity/ima/ima_template_lib.c
@@ -10,7 +10,9 @@
  */
 
 #include "ima_template_lib.h"
+#ifdef CONFIG_IMA_DIGEST_LIST
 #include <linux/xattr.h>
+#endif
 
 static bool ima_template_hash_algo_allowed(u8 algo)
 {
@@ -439,7 +441,11 @@ int ima_eventsig_init(struct ima_event_data *event_data,
 	struct evm_ima_xattr_data *xattr_value = event_data->xattr_value;
 
 	if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG))
+#ifdef CONFIG_IMA_DIGEST_LIST
 		return ima_eventevmsig_init(event_data, field_data);
+#else
+		return 0;
+#endif
 
 	return ima_write_template_field_data(xattr_value, event_data->xattr_len,
 					     DATA_FMT_HEX, field_data);
@@ -486,6 +492,7 @@ int ima_eventmodsig_init(struct ima_event_data *event_data,
 					     field_data);
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 /*
  *  ima_eventevmsig_init - include the EVM portable signature as part of the
  *  template data
@@ -514,3 +521,4 @@ int ima_eventevmsig_init(struct ima_event_data *event_data,
 	kfree(xattr_data);
 	return rc;
 }
+#endif
diff --git a/security/integrity/ima/ima_template_lib.h b/security/integrity/ima/ima_template_lib.h
index f4b2a2056d1d..5313a8a22e45 100644
--- a/security/integrity/ima/ima_template_lib.h
+++ b/security/integrity/ima/ima_template_lib.h
@@ -46,6 +46,8 @@ int ima_eventbuf_init(struct ima_event_data *event_data,
 		      struct ima_field_data *field_data);
 int ima_eventmodsig_init(struct ima_event_data *event_data,
 			 struct ima_field_data *field_data);
+#ifdef CONFIG_IMA_DIGEST_LIST
 int ima_eventevmsig_init(struct ima_event_data *event_data,
 			 struct ima_field_data *field_data);
+#endif
 #endif /* __LINUX_IMA_TEMPLATE_LIB_H */
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 77e6819e8db8..d9cf29e286a9 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -14,10 +14,13 @@
 
 #include <linux/types.h>
 #include <linux/integrity.h>
+#include <crypto/sha1.h>
 #include <crypto/sha2.h>
 #include <linux/key.h>
 #include <linux/audit.h>
+#ifdef CONFIG_IMA_DIGEST_LIST
 #include <linux/hash_info.h>
+#endif
 
 /* iint action cache flags */
 #define IMA_MEASURE		0x00000001
@@ -40,7 +43,9 @@
 #define IMA_FAIL_UNVERIFIABLE_SIGS	0x10000000
 #define IMA_MODSIG_ALLOWED	0x20000000
 #define IMA_CHECK_BLACKLIST	0x40000000
+#ifdef CONFIG_IMA_DIGEST_LIST
 #define IMA_META_IMMUTABLE_REQUIRED	0x80000000
+#endif
 
 #define IMA_DO_MASK		(IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
 				 IMA_HASH | IMA_APPRAISE_SUBMASK)
@@ -72,7 +77,9 @@
 #define IMA_CHANGE_ATTR		2
 #define IMA_DIGSIG		3
 #define IMA_MUST_MEASURE	4
+#ifdef CONFIG_IMA_DIGEST_LIST
 #define IMA_DIGEST_LIST		5
+#endif
 
 enum evm_ima_xattr_type {
 	IMA_XATTR_DIGEST = 0x01,
@@ -80,7 +87,9 @@ enum evm_ima_xattr_type {
 	EVM_IMA_XATTR_DIGSIG,
 	IMA_XATTR_DIGEST_NG,
 	EVM_XATTR_PORTABLE_DIGSIG,
+#ifdef CONFIG_IMA_DIGEST_LIST
 	EVM_IMA_XATTR_DIGEST_LIST,
+#endif
 	IMA_XATTR_LAST
 };
 
@@ -92,7 +101,11 @@ struct evm_ima_xattr_data {
 /* Only used in the EVM HMAC code. */
 struct evm_xattr {
 	struct evm_ima_xattr_data data;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	u8 digest[SHA512_DIGEST_SIZE];
+#else
+	u8 digest[SHA1_DIGEST_SIZE];
+#endif
 } __packed;
 
 #define IMA_MAX_DIGEST_SIZE	64
@@ -144,6 +157,7 @@ struct integrity_iint_cache {
 	struct ima_digest_data *ima_hash;
 };
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 enum compact_types { COMPACT_KEY, COMPACT_PARSER, COMPACT_FILE,
 		     COMPACT_METADATA, COMPACT__LAST };
 enum compact_modifiers { COMPACT_MOD_IMMUTABLE, COMPACT_MOD__LAST };
@@ -162,7 +176,6 @@ static inline bool ima_digest_is_immutable(struct ima_digest *digest)
 	return (digest->modifiers & (1 << COMPACT_MOD_IMMUTABLE));
 }
 
-#ifdef CONFIG_IMA_DIGEST_LIST
 struct ima_digest *ima_lookup_digest(u8 *digest, enum hash_algo algo,
 				     enum compact_types type);
 struct ima_digest *ima_digest_allow(struct ima_digest *digest, int action);
diff --git a/security/security.c b/security/security.c
index 5678d4e334fb..11c859a9b8ed 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1362,7 +1362,9 @@ void security_inode_post_setxattr(struct dentry *dentry, const char *name,
 	if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
 		return;
 	call_void_hook(inode_post_setxattr, dentry, name, value, size, flags);
+#ifdef CONFIG_IMA_DIGEST_LIST
 	ima_inode_post_setxattr(dentry, name, value, size);
+#endif
 	evm_inode_post_setxattr(dentry, name, value, size);
 }
 
-- 
2.33.0
                    
                  
                  
                          
                            
                            3
                            
                          
                          
                            
                            2
                            
                          
                          
                            
    
                          
                        
                     
                        
                    
                        
                            
                                
                            
                            [PATCH OLK-5.10] exfat: check if filename entries exceeds max filename length
                        
                        
by ZhaoLong Wang 16 Aug '23
                    by ZhaoLong Wang 16 Aug '23
16 Aug '23
                    
                        From: Namjae Jeon <linkinjeon(a)kernel.org>
stable inclusion
from stable-v5.10.190
commit 381f7df0f3c3bd7dceb3e2b2b64c2f6247e2ac19
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I7TLII
CVE: CVE-2023-4273
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id…
---------------------------
[ Upstream commit d42334578eba1390859012ebb91e1e556d51db49 ]
exfat_extract_uni_name copies characters from a given file name entry into
the 'uniname' variable. This variable is actually defined on the stack of
the exfat_readdir() function. According to the definition of
the 'exfat_uni_name' type, the file name should be limited 255 characters
(+ null teminator space), but the exfat_get_uniname_from_ext_entry()
function can write more characters because there is no check if filename
entries exceeds max filename length. This patch add the check not to copy
filename characters when exceeding max filename length.
Cc: stable(a)vger.kernel.org
Cc: Yuezhang Mo <Yuezhang.Mo(a)sony.com>
Reported-by: Maxim Suhanov <dfirblog(a)gmail.com>
Reviewed-by: Sungjong Seo <sj1557.seo(a)samsung.com>
Signed-off-by: Namjae Jeon <linkinjeon(a)kernel.org>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
Signed-off-by: ZhaoLong Wang <wangzhaolong1(a)huawei.com>
---
 fs/exfat/dir.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
index dedbc55cd48f..0d736bf97146 100644
--- a/fs/exfat/dir.c
+++ b/fs/exfat/dir.c
@@ -33,6 +33,7 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb,
 {
 	int i;
 	struct exfat_entry_set_cache *es;
+	unsigned int uni_len = 0, len;
 
 	es = exfat_get_dentry_set(sb, p_dir, entry, ES_ALL_ENTRIES);
 	if (!es)
@@ -51,7 +52,10 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb,
 		if (exfat_get_entry_type(ep) != TYPE_EXTEND)
 			break;
 
-		exfat_extract_uni_name(ep, uniname);
+		len = exfat_extract_uni_name(ep, uniname);
+		uni_len += len;
+		if (len != EXFAT_FILE_NAME_LEN || uni_len >= MAX_NAME_LENGTH)
+			break;
 		uniname += EXFAT_FILE_NAME_LEN;
 	}
 
@@ -1026,7 +1030,8 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
 			if (entry_type == TYPE_EXTEND) {
 				unsigned short entry_uniname[16], unichar;
 
-				if (step != DIRENT_STEP_NAME) {
+				if (step != DIRENT_STEP_NAME ||
+				    name_len >= MAX_NAME_LENGTH) {
 					step = DIRENT_STEP_FILE;
 					continue;
 				}
-- 
2.34.3
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            1
                            
                          
                          
                            
    
                          
                        
                     
                        
                    15 Aug '23
                    
                        hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I7THI2
--------------------------------
The latest contribution guide is archived at
https://gitee.com/openeuler/kernel-docs and
https://gitee.com/openeuler/community/tree/master/sig/Kernel
Signed-off-by: Wei Li <liwei391(a)huawei.com>
---
 README | 226 ---------------------------------------------------------
 1 file changed, 226 deletions(-)
diff --git a/README b/README
index 21b2e09d62db..2c927ccbd970 100644
--- a/README
+++ b/README
@@ -1,229 +1,3 @@
-# How to Contribute
--------
-
--  [How to Contribute](#How to Contribute)
-
-   \- [Sign the CLA](#Sign the CLA)
-
-   \- [Steps of submitting patches](#Steps of submitting patches)
-
-   \- [Use the unified patch format](#Use the unified patch format)
-
-   \- [Define the patch format](#Define the patch format)
-
-   \- [Examples](#Examples)
-
-   \- [Email client - Thunderbird settings](#Email client - Thunderbird settings)
-
--  [Linux kernel](#Linux kernel)
-
-###  Sign the CLA
-
--------
-
-Before making any contributions to openEuler, sign the CLA first.
-
-Address: [https://openeuler.org/en/cla.html](https://openeuler.org/en/cla.html)
-
-### Steps of submitting patches
--------
-
-**Step 1** Compile and test your patches.
-
-**Step 2** Generate patches.
-
-Your patches should be generated based on the latest openEuler branch using git-format-patch. If your patches are in a patchset, it is better to use the **--cover-letter** option to describe what the patchset does.
-
-Use **scripts/checkpatch.pl** to ensure that no coding style issue exists.
-
-In addition, ensure that your patches comply with the unified openEuler patch format described below.
-
-**Step 3** Send your patches to the openEuler mailing list.
-
-To do so, run the following command:
-
-   `git send-email *.patch -to="kernel(a)openeuler.org" --suppress-cc=all`
-
-*NOTE*: Add **--suppress-cc=all** if you use git-send-email; otherwise, the email will be copied to all people in the upstream community and mailing lists.
-
-For details about how to send patches using git-send-email, see [https://git-scm.com/docs/git-send-email](https://git-scm.com/docs/git-send-….
-
-**Step 4** Mark "v1, v2, v3 ..." in your patch subject if you have multiple versions to send out.
-
-Use the **--subject-prefix="PATCH v2"** option to add the v2 tag to the patchset.
-
-   `git format-patch --subject-prefix="PATCH v2" -1`
-
-Subject examples:
-
-   Subject: [PATCH v2 01/27] fork: fix some -Wmissing-prototypes warnings
-
-   Subject: [PATCH v3] ext2: improve scalability of bitmap searching
-
-**Step 5** Upstream your kernel patches to the kernel community (recommended). openEuler will synchronize with the kernel master in a timely manner.
-
-**Step 6** Sign your work - the Developer’s Certificate of Origin.
-
- Similar to the upstream kernel community, you also need to sign your patch.
-
- For details, see [https://www.kernel.org/doc/html/latest/process/submitting-patches.html](htt….
-
- The sign-off is a simple line at the end of the explanation of the patch, which certifies that you wrote it or otherwise have the  right to pass it on as an open source patch. The rules are pretty simple. You can certify as below:
-
-  Developer’s Certificate of Origin 1.1
-
-  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-  By making a contribution to this project, I certify that:
-
-   (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file;
-
-   (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file;
-
-   (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it.
-
-   (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved.
-
-Then you add a line saying:
-
-Signed-off-by: Random J Developer <random(a)developer.example.org>
-
-Use your real name (sorry, no pseudonyms or anonymous contributions).
-
-### Use the unified patch format
--------
-
-Reasons:
-
-1. Long term maintainability
-
-  openEuler will merge massive patches. If all patches are merged by casual
-
-  changelog formats without a unified format, the git logs will be messy, and
-
-  then it is hard to figure out the original patches.
-
-2. Kernel upgrade
-
-  We definitely will upgrade our openEuler kernel in someday, so strict patch management
-
-  will alleviate the pain to migrate patches during big upgrades.
-
-3. Easy for script parsing
-
-  Keyword highlighting is necessary for script parsing.
-
-### Define the patch format
--------
-
-[M] stands for "mandatory".
-
-[O] stands for "option".
-
-$category can be: bug preparation, bugfix, perf, feature, doc, other...
-
-If category is feature, we need to add a feature name as below:
-
-```cpp
-category: feature
-feature: YYY (the feature name)
-```
-
-If the patch is related to CVE or bugzilla, we need to add the corresponding tag as below (In general, it should include at least one of the following):
-
-```cpp
-CVE: $cve-id
-bugzilla: $bug-id
-```
-
-Additional changelog should include at least one of the following:
-
-1.  Why we should apply this patch
-
-2. What real problems in the product does this patch resolved
-
-3.  How could we reproduce this bug or how to test
-
-4.  Other useful information for help to understand this patch or problem
-
-The detailed information is very useful for migrating a patch to another kernel branch.
-
-Example for mainline patch:
-
-```cpp
-mainline inclusion            [M]
-from $mainline-version   [M]
-commit $id                        [M]
-category: $category         [M]
-bugzilla: $bug-id               [O]
-CVE: $cve-id                       [O]
-
-additional changelog       [O]
-
---------------------------------
-
-original changelog
-Signed-off-by: $yourname <$yourname(a)huawei.com>  [M]
-($mainline-version could be mainline-3.5, mainline-3.6, etc...)
-```
-
-### Examples
--------
-
-```cpp
-mainline inclusion
-from mainline-4.10
-commit 0becc0ae5b42828785b589f686725ff5bc3b9b25
-category: bugfix
-bugzilla: 3004
-CVE: N/A
-
-The patch fixes a BUG_ON in the product: Injecting a single bit ECC error to the memory before system boot using hardware inject tools will cause a large amount of CMCI during system booting .
-[   1.146580] mce: [Hardware Error]: Machine check events logged
-[   1.152908] ------------[ cut here ]------------
-[   1.157751] kernel BUG at kernel/timer.c:951!
-[   1.162321] invalid opcode: 0000 [#1] SMP
-
--------------------------------------------------
-
-original changelog
-
-<original S-O-B>
-Signed-off-by: Zhang San <zhangsan(a)huawei.com>
-Tested-by: Li Si <lisi(a)huawei.com>
-```
-
-### Email client - Thunderbird settings
--------
-
-If you are a new developer in the kernel community, it is highly recommended that you use the Thunderbird mail client.
-
-1.  Thunderbird Installation
-
-  Obtain the English version of Thunderbird from [http://www.mozilla.org/]( http://www.mozilla.org/) and install it on your system.
-
-  Download URL: https://www.thunderbird.net/en-US/thunderbird/all/
-
-2.  Settings
-
-  2.1 Use the plain text format instead of the HTML format.
-
-    Choose **Options > Account Settings > Composition & Addressing**, and do **NOT** select Compose message in HTML format.
-
-  2.2 Editor settings
-
-    **Tools > Options> Advanced > Config editor**
-
-    \- To bring up the Thunderbird's registry editor, set **mailnews.send_plaintext_flowed** to **false**.
-
-    \- Disable HTML Format: Set **mail.identity.id1.compose_html** to **false**.
-
-    \- Enable UTF-8: Set **prefs.converted-to-utf8** to **true**.
-
-    \- View messages in UTF-8: Set **mailnews.view_default_charset** to **UTF-8**.
-
-    \- Set **mailnews.wraplength** to **9999** to avoid auto-wrap.
-
 Linux kernel
 ============
 
-- 
2.25.1
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            1