Kernel
  Threads by month 
                
            - ----- 2025 -----
- November
- 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
- 20964 discussions
 
                        
                    
                        
                            
                                
                            
                            [PATCH openEuler-1.0-LTS] tracing: Fix race issue between cpu buffer write and swap
                        
                        
by Zheng Yejian 04 Sep '23
                    by Zheng Yejian 04 Sep '23
04 Sep '23
                    
                        mainline inclusion
from mainline-v6.6-rc1
commit 3163f635b20e9e1fb4659e74f47918c9dddfe64e
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I7YE3Y
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
-------------------------------------------
Warning happened in rb_end_commit() at code:
	if (RB_WARN_ON(cpu_buffer, !local_read(&cpu_buffer->committing)))
  WARNING: CPU: 0 PID: 139 at kernel/trace/ring_buffer.c:3142
	rb_commit+0x402/0x4a0
  Call Trace:
   ring_buffer_unlock_commit+0x42/0x250
   trace_buffer_unlock_commit_regs+0x3b/0x250
   trace_event_buffer_commit+0xe5/0x440
   trace_event_buffer_reserve+0x11c/0x150
   trace_event_raw_event_sched_switch+0x23c/0x2c0
   __traceiter_sched_switch+0x59/0x80
   __schedule+0x72b/0x1580
   schedule+0x92/0x120
   worker_thread+0xa0/0x6f0
It is because the race between writing event into cpu buffer and swapping
cpu buffer through file per_cpu/cpu0/snapshot:
  Write on CPU 0             Swap buffer by per_cpu/cpu0/snapshot on CPU 1
  --------                   --------
                             tracing_snapshot_write()
                               [...]
  ring_buffer_lock_reserve()
    cpu_buffer = buffer->buffers[cpu]; // 1. Suppose find 'cpu_buffer_a';
    [...]
    rb_reserve_next_event()
      [...]
                               ring_buffer_swap_cpu()
                                 if (local_read(&cpu_buffer_a->committing))
                                     goto out_dec;
                                 if (local_read(&cpu_buffer_b->committing))
                                     goto out_dec;
                                 buffer_a->buffers[cpu] = cpu_buffer_b;
                                 buffer_b->buffers[cpu] = cpu_buffer_a;
                                 // 2. cpu_buffer has swapped here.
      rb_start_commit(cpu_buffer);
      if (unlikely(READ_ONCE(cpu_buffer->buffer)
          != buffer)) { // 3. This check passed due to 'cpu_buffer->buffer'
        [...]           //    has not changed here.
        return NULL;
      }
                                 cpu_buffer_b->buffer = buffer_a;
                                 cpu_buffer_a->buffer = buffer_b;
                                 [...]
      // 4. Reserve event from 'cpu_buffer_a'.
  ring_buffer_unlock_commit()
    [...]
    cpu_buffer = buffer->buffers[cpu]; // 5. Now find 'cpu_buffer_b' !!!
    rb_commit(cpu_buffer)
      rb_end_commit()  // 6. WARN for the wrong 'committing' state !!!
Based on above analysis, we can easily reproduce by following testcase:
  ``` bash
  #!/bin/bash
  dmesg -n 7
  sysctl -w kernel.panic_on_warn=1
  TR=/sys/kernel/tracing
  echo 7 > ${TR}/buffer_size_kb
  echo "sched:sched_switch" > ${TR}/set_event
  while [ true ]; do
          echo 1 > ${TR}/per_cpu/cpu0/snapshot
  done &
  while [ true ]; do
          echo 1 > ${TR}/per_cpu/cpu0/snapshot
  done &
  while [ true ]; do
          echo 1 > ${TR}/per_cpu/cpu0/snapshot
  done &
  ```
To fix it, IIUC, we can use smp_call_function_single() to do the swap on
the target cpu where the buffer is located, so that above race would be
avoided.
Link: https://lore.kernel.org/linux-trace-kernel/20230831132739.4070878-1-zhengye…
Cc: <mhiramat(a)kernel.org>
Fixes: f1affcaaa861 ("tracing: Add snapshot in the per_cpu trace directories")
Signed-off-by: Zheng Yejian <zhengyejian1(a)huawei.com>
Signed-off-by: Steven Rostedt (Google) <rostedt(a)goodmis.org>
Signed-off-by: Zheng Yejian <zhengyejian1(a)huawei.com>
---
 kernel/trace/trace.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 8b5ede27b38e..64fd3c3f84f2 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -6463,6 +6463,11 @@ static int tracing_snapshot_open(struct inode *inode, struct file *file)
 	return ret;
 }
 
+static void tracing_swap_cpu_buffer(void *tr)
+{
+	update_max_tr_single((struct trace_array *)tr, current, smp_processor_id());
+}
+
 static ssize_t
 tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,
 		       loff_t *ppos)
@@ -6512,13 +6517,15 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,
 			ret = tracing_alloc_snapshot_instance(tr);
 		if (ret < 0)
 			break;
-		local_irq_disable();
 		/* Now, we're going to swap */
-		if (iter->cpu_file == RING_BUFFER_ALL_CPUS)
+		if (iter->cpu_file == RING_BUFFER_ALL_CPUS) {
+			local_irq_disable();
 			update_max_tr(tr, current, smp_processor_id());
-		else
-			update_max_tr_single(tr, current, iter->cpu_file);
-		local_irq_enable();
+			local_irq_enable();
+		} else {
+			smp_call_function_single(iter->cpu_file, tracing_swap_cpu_buffer,
+						 (void *)tr, 1);
+		}
 		break;
 	default:
 		if (tr->allocated_snapshot) {
-- 
2.25.1
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            1
                            
                          
                          
                            
    
                          
                        
                     
                        
                    
                        
                            
                                
                            
                            [PATCH OLK-5.10] tracing: Fix race issue between cpu buffer write and swap
                        
                        
by Zheng Yejian 04 Sep '23
                    by Zheng Yejian 04 Sep '23
04 Sep '23
                    
                        mainline inclusion
from mainline-v6.6-rc1
commit 3163f635b20e9e1fb4659e74f47918c9dddfe64e
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I7YE3Y
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?…
-------------------------------------------
Warning happened in rb_end_commit() at code:
	if (RB_WARN_ON(cpu_buffer, !local_read(&cpu_buffer->committing)))
  WARNING: CPU: 0 PID: 139 at kernel/trace/ring_buffer.c:3142
	rb_commit+0x402/0x4a0
  Call Trace:
   ring_buffer_unlock_commit+0x42/0x250
   trace_buffer_unlock_commit_regs+0x3b/0x250
   trace_event_buffer_commit+0xe5/0x440
   trace_event_buffer_reserve+0x11c/0x150
   trace_event_raw_event_sched_switch+0x23c/0x2c0
   __traceiter_sched_switch+0x59/0x80
   __schedule+0x72b/0x1580
   schedule+0x92/0x120
   worker_thread+0xa0/0x6f0
It is because the race between writing event into cpu buffer and swapping
cpu buffer through file per_cpu/cpu0/snapshot:
  Write on CPU 0             Swap buffer by per_cpu/cpu0/snapshot on CPU 1
  --------                   --------
                             tracing_snapshot_write()
                               [...]
  ring_buffer_lock_reserve()
    cpu_buffer = buffer->buffers[cpu]; // 1. Suppose find 'cpu_buffer_a';
    [...]
    rb_reserve_next_event()
      [...]
                               ring_buffer_swap_cpu()
                                 if (local_read(&cpu_buffer_a->committing))
                                     goto out_dec;
                                 if (local_read(&cpu_buffer_b->committing))
                                     goto out_dec;
                                 buffer_a->buffers[cpu] = cpu_buffer_b;
                                 buffer_b->buffers[cpu] = cpu_buffer_a;
                                 // 2. cpu_buffer has swapped here.
      rb_start_commit(cpu_buffer);
      if (unlikely(READ_ONCE(cpu_buffer->buffer)
          != buffer)) { // 3. This check passed due to 'cpu_buffer->buffer'
        [...]           //    has not changed here.
        return NULL;
      }
                                 cpu_buffer_b->buffer = buffer_a;
                                 cpu_buffer_a->buffer = buffer_b;
                                 [...]
      // 4. Reserve event from 'cpu_buffer_a'.
  ring_buffer_unlock_commit()
    [...]
    cpu_buffer = buffer->buffers[cpu]; // 5. Now find 'cpu_buffer_b' !!!
    rb_commit(cpu_buffer)
      rb_end_commit()  // 6. WARN for the wrong 'committing' state !!!
Based on above analysis, we can easily reproduce by following testcase:
  ``` bash
  #!/bin/bash
  dmesg -n 7
  sysctl -w kernel.panic_on_warn=1
  TR=/sys/kernel/tracing
  echo 7 > ${TR}/buffer_size_kb
  echo "sched:sched_switch" > ${TR}/set_event
  while [ true ]; do
          echo 1 > ${TR}/per_cpu/cpu0/snapshot
  done &
  while [ true ]; do
          echo 1 > ${TR}/per_cpu/cpu0/snapshot
  done &
  while [ true ]; do
          echo 1 > ${TR}/per_cpu/cpu0/snapshot
  done &
  ```
To fix it, IIUC, we can use smp_call_function_single() to do the swap on
the target cpu where the buffer is located, so that above race would be
avoided.
Link: https://lore.kernel.org/linux-trace-kernel/20230831132739.4070878-1-zhengye…
Cc: <mhiramat(a)kernel.org>
Fixes: f1affcaaa861 ("tracing: Add snapshot in the per_cpu trace directories")
Signed-off-by: Zheng Yejian <zhengyejian1(a)huawei.com>
Signed-off-by: Steven Rostedt (Google) <rostedt(a)goodmis.org>
Signed-off-by: Zheng Yejian <zhengyejian1(a)huawei.com>
---
 kernel/trace/trace.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 2ba13e9d61bd..6eead8a61195 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -7068,6 +7068,11 @@ static int tracing_snapshot_open(struct inode *inode, struct file *file)
 	return ret;
 }
 
+static void tracing_swap_cpu_buffer(void *tr)
+{
+	update_max_tr_single((struct trace_array *)tr, current, smp_processor_id());
+}
+
 static ssize_t
 tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,
 		       loff_t *ppos)
@@ -7126,13 +7131,15 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,
 			ret = tracing_alloc_snapshot_instance(tr);
 		if (ret < 0)
 			break;
-		local_irq_disable();
 		/* Now, we're going to swap */
-		if (iter->cpu_file == RING_BUFFER_ALL_CPUS)
+		if (iter->cpu_file == RING_BUFFER_ALL_CPUS) {
+			local_irq_disable();
 			update_max_tr(tr, current, smp_processor_id(), NULL);
-		else
-			update_max_tr_single(tr, current, iter->cpu_file);
-		local_irq_enable();
+			local_irq_enable();
+		} else {
+			smp_call_function_single(iter->cpu_file, tracing_swap_cpu_buffer,
+						 (void *)tr, 1);
+		}
 		break;
 	default:
 		if (tr->allocated_snapshot) {
-- 
2.25.1
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            1
                            
                          
                          
                            
    
                          
                        
                    
                    
                        From: Ma Wupeng <mawupeng1(a)huawei.com>
Cleanup for gmem.
Ma Wupeng (4):
  mm: gmem: Stop use gm_fault during alloc/free
  mm: gmem: Remove unused gm_mappings_free
  mm: gmem: Cleanup in gmem_handle_evict_page
  mm: gmem: Cleanup in gm flag
 drivers/remote_pager/msg_handler_origin.c | 40 ++++++-------
 include/linux/gmem.h                      | 69 +++++------------------
 mm/gmem.c                                 | 31 ++--------
 mm/huge_memory.c                          |  3 +-
 mm/mmap.c                                 | 16 +-----
 mm/vm_object.c                            |  2 +-
 6 files changed, 46 insertions(+), 115 deletions(-)
-- 
2.25.1
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            5
                            
                          
                          
                            
    
                          
                        
                     
                        
                    04 Sep '23
                    
                        euleros inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I277UJ
--------------------------------
Isolate the IMA digest list code by using macros.
changelog
v2:
	Exclude some macros for code that has already
	been merged into upstream kernel.
v3:
	add patch header and fix some simple code warnings
v4:
	merge some duplicate code and add macro comments.
Signed-off-by: Zhou Shuiqing <zhoushuiqing2(a)huawei.com>
---
 fs/xattr.c                                |   4 +
 include/linux/evm.h                       |   5 +-
 include/linux/ima.h                       |   8 +
 include/linux/integrity.h                 |   2 +
 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         | 117 +++++++++++
 security/integrity/iint.c                 |   4 +
 security/integrity/ima/ima.h              |  62 +++++-
 security/integrity/ima/ima_api.c          |  39 ++++
 security/integrity/ima/ima_appraise.c     | 125 +++++++++++-
 security/integrity/ima/ima_fs.c           | 238 +++++++++++++++++++++-
 security/integrity/ima/ima_init.c         |   6 +
 security/integrity/ima/ima_main.c         |  33 +++
 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            |  32 ++-
 security/security.c                       |   2 +
 21 files changed, 785 insertions(+), 28 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..fbaebb01b8a6 100644
--- a/include/linux/evm.h
+++ b/include/linux/evm.h
@@ -35,7 +35,9 @@ 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);
+#ifdef CONFIG_IMA_DIGEST_LIST
 extern bool evm_status_revalidate(const char *xattr_name);
+#endif
 #ifdef CONFIG_FS_POSIX_ACL
 extern int posix_xattr_acl(const char *xattrname);
 #else
@@ -105,10 +107,11 @@ static inline int evm_inode_init_security(struct inode *inode,
 	return 0;
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static inline bool evm_status_revalidate(const char *xattr_name)
 {
 	return false;
 }
-
+#endif /* CONFIG_IMA_DIGEST_LIST */
 #endif /* CONFIG_EVM */
 #endif /* LINUX_EVM_H */
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/include/linux/integrity.h b/include/linux/integrity.h
index 2ea0f2f65ab6..b3e403f214f0 100644
--- a/include/linux/integrity.h
+++ b/include/linux/integrity.h
@@ -13,7 +13,9 @@ enum integrity_status {
 	INTEGRITY_PASS = 0,
 	INTEGRITY_PASS_IMMUTABLE,
 	INTEGRITY_FAIL,
+#ifdef CONFIG_IMA_DIGEST_LIST
 	INTEGRITY_FAIL_IMMUTABLE,
+#endif
 	INTEGRITY_NOLABEL,
 	INTEGRITY_NOXATTRS,
 	INTEGRITY_UNKNOWN,
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..c67271c45e50 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>
@@ -27,10 +29,17 @@
 
 int evm_initialized;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static const char * const integrity_status_msg[] = {
 	"pass", "pass_immutable", "fail", "fail_immutable", "no_label",
 	"no_xattrs", "unknown"
 };
+#else
+static const char * const integrity_status_msg[] = {
+	"pass", "pass_immutable", "fail", "no_label", "no_xattrs", "unknown"
+};
+#endif
+
 int evm_hmac_attrs;
 
 static struct xattr_list evm_config_default_xattrnames[] = {
@@ -57,22 +66,32 @@ 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)
+#else
+static int __init evm_set_fixmode(char *str)
+#endif
 {
 	if (strncmp(str, "fix", 3) == 0)
 		evm_fixmode = 1;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	else if (strncmp(str, "x509", 4) == 0)
 		evm_initialized |= EVM_INIT_X509;
 	else if (strncmp(str, "allow_metadata_writes", 21) == 0)
 		evm_initialized |= EVM_ALLOW_METADATA_WRITES;
 	else if (strncmp(str, "complete", 8) == 0)
 		evm_initialized |= EVM_SETUP_COMPLETE;
+#endif
 	else
 		pr_err("invalid \"%s\" mode", str);
 
 	return 1;
 }
+#ifdef CONFIG_IMA_DIGEST_LIST
 __setup("evm=", evm_set_param);
+#else
+__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,23 +255,37 @@ 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) {
+#else
+		if (xattr_len != sizeof(struct evm_xattr)) {
+#endif
 			evm_status = INTEGRITY_FAIL;
 			goto out;
 		}
+#ifdef CONFIG_IMA_DIGEST_LIST
 		digest.hdr.algo = evm_hash_algo;
+#else
+		digest.hdr.algo = HASH_ALGO_SHA1;
+#endif
 		rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
 				   xattr_value_len, &digest);
 		if (rc)
 			break;
 		rc = crypto_memneq(xattr_data->data, digest.digest,
+#ifdef CONFIG_IMA_DIGEST_LIST
 				   hash_digest_size[evm_hash_algo]);
+#else
+				   SHA1_DIGEST_SIZE);
+#endif
 		if (rc)
 			rc = -EINVAL;
 		break;
 	case EVM_XATTR_PORTABLE_DIGSIG:
+#ifdef CONFIG_IMA_DIGEST_LIST
 		evm_immutable = 1;
 		fallthrough;
+#endif
 	case EVM_IMA_XATTR_DIGSIG:
 		/* accept xattr with non-empty signature field */
 		if (xattr_len <= sizeof(struct signature_v2_hdr)) {
@@ -262,6 +318,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 +359,13 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 			evm_status = INTEGRITY_PASS;
 		}
 		break;
+#endif /* CONFIG_IMA_DIGEST_LIST */
 	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 +374,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 +463,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 +535,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 +587,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 +601,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 +639,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 +679,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 +704,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 +722,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 +752,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 +782,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,19 +805,26 @@ 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);
+
 	/*
 	 * Writing attrs is safe for portable signatures, as portable signatures
 	 * are immutable and can never be updated.
 	 */
 	if ((evm_status == INTEGRITY_PASS) ||
+#ifdef CONFIG_IMA_DIGEST_LIST
 	    (evm_status == INTEGRITY_NOXATTRS) ||
 	    (evm_status == INTEGRITY_FAIL_IMMUTABLE) ||
 	    (evm_ignore_error_safe(evm_status)))
+#else
+		(evm_status == INTEGRITY_NOXATTRS))
+#endif
 		return 0;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (evm_status == INTEGRITY_PASS_IMMUTABLE &&
 	    !evm_attr_change(dentry, attr))
 		return 0;
+#endif
 
 	integrity_audit_msg(AUDIT_INTEGRITY_METADATA, d_backing_inode(dentry),
 			    dentry->d_name.name, "appraise_metadata",
@@ -747,10 +845,16 @@ 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))
+#else
+	if (!evm_key_loaded())
+#endif
 		return;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	evm_reset_status(dentry->d_inode);
+#endif
 
 	if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
 		evm_update_evmxattr(dentry, NULL, NULL, 0);
@@ -766,8 +870,12 @@ int evm_inode_init_security(struct inode *inode,
 	struct evm_xattr *xattr_data;
 	int rc;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (!(evm_initialized & EVM_INIT_HMAC) ||
 	    !evm_protected_xattr(lsm_xattr->name))
+#else
+	if (!evm_key_loaded() || !evm_protected_xattr(lsm_xattr->name))
+#endif
 		return 0;
 
 	xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS);
@@ -780,7 +888,11 @@ 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;
+#else
+	evm_xattr->value_len = sizeof(*xattr_data);
+#endif
 	evm_xattr->name = XATTR_EVM_SUFFIX;
 	return 0;
 out:
@@ -802,6 +914,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 +922,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..bd66cadc4a3a 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))
+#endif
 		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..2145eb0c76e0 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 /* CONFIG_IMA_DIGEST_LIST */
 
 #define __ima_hook_enumify(ENUM, str)	ENUM,
 #define __ima_stringify(arg) (#arg)
@@ -268,8 +286,12 @@ 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,
+#ifdef CONFIG_IMA_DIGEST_LIST
 			   struct ima_template_desc *template_desc,
 			   struct ima_digest *digest);
+#else
+			   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);
@@ -280,7 +302,11 @@ int ima_alloc_init_template(struct ima_event_data *event_data,
 			    struct ima_template_desc *template_desc);
 int ima_store_template(struct ima_template_entry *entry, int violation,
 		       struct inode *inode, const unsigned char *filename,
+#ifdef CONFIG_IMA_DIGEST_LIST
 		       int pcr, struct ima_digest *digest);
+#else
+			   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,7 +334,9 @@ 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,
@@ -317,12 +345,24 @@ 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,
+#ifdef CONFIG_IMA_DIGEST_LIST
 			     int xattr_len, const struct modsig *modsig,
 			     struct ima_digest *found_digest);
+#else
+			     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)
@@ -336,8 +376,12 @@ static inline int ima_appraise_measurement(enum ima_hooks func,
 					   const unsigned char *filename,
 					   struct evm_ima_xattr_data *xattr_value,
 					   int xattr_len,
+#ifndef CONFIG_IMA_DIGEST_LIST
 					   const struct modsig *modsig,
 					   struct ima_digest *found_digest)
+#else
+					   const struct modsig *modsig)
+#endif
 {
 	return INTEGRITY_UNKNOWN;
 }
@@ -360,6 +404,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..3c59049e58ad 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;
+	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 /* CONFIG_IMA_DIGEST_LIST */
+
 /*
  * 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,21 +286,28 @@ 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;
 				break;
 			}
+#ifdef CONFIG_IMA_DIGEST_LIST
 			clear_bit(IMA_DIGSIG, &iint->atomic_flags);
 		} else {
 			set_bit(IMA_DIGSIG, &iint->atomic_flags);
+#endif
 		}
 		if (xattr_len - sizeof(xattr_value->type) - hash_start >=
 				iint->ima_hash->length)
@@ -352,26 +428,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 +483,7 @@ int ima_appraise_measurement(enum ima_hooks func,
 			rc = xattr_len;
 		}
 	}
+#endif /* CONFIG_IMA_DIGEST_LIST */
 
 	/* If reading the xattr failed and there's no modsig, error out. */
 	if (rc <= 0 && !try_modsig) {
@@ -417,11 +507,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 +523,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 +541,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 +556,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 +565,15 @@ int ima_appraise_measurement(enum ima_hooks func,
 				    filename, op, cause, rc, 0);
 		goto out;
 	}
+#endif
 
 	if (xattr_value)
 		rc = xattr_verify(func, iint, xattr_value, xattr_len, &status,
+#ifdef CONFIG_IMA_DIGEST_LIST
 				  &cause, found_digest);
+#else
+				  &cause);
+#endif
 
 	/*
 	 * If we have a modsig and either no imasig or the imasig's key isn't
@@ -508,7 +612,11 @@ int ima_appraise_measurement(enum ima_hooks func,
 		 * without data.
 		 */
 		if (inode->i_size == 0 && iint->flags & IMA_NEW_FILE &&
+#ifdef CONFIG_IMA_DIGEST_LIST
 		    test_bit(IMA_DIGSIG, &iint->atomic_flags)) {
+#else
+		    xattr_value && xattr_value->type == EVM_IMA_XATTR_DIGSIG) {
+#endif
 			status = INTEGRITY_PASS;
 		}
 
@@ -567,6 +675,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 +732,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 +758,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 +766,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 +783,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..996a287b4b77 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,55 @@ 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 /* CONFIG_IMA_DIGEST_LIST */
 
+#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 /* CONFIG_IMA_DIGEST_LIST */
 
 /* returns pointer to hlist_node */
 static void *ima_measurements_start(struct seq_file *m, loff_t *pos)
@@ -275,6 +318,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 +364,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 +371,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 +385,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 +501,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 /* CONFIG_IMA_DIGEST_LIST */
 
 static unsigned long ima_fs_flags;
 
@@ -473,6 +611,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 +707,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 /* CONFIG_IMA_DIGEST_LIST */
 
 int __init ima_fs_init(void)
 {
@@ -597,19 +809,31 @@ int __init ima_fs_init(void)
 	runtime_measurements_count =
 	    securityfs_create_file("runtime_measurements_count",
 				   S_IRUSR | S_IRGRP, ima_dir, NULL,
+#ifdef CONFIG_IMA_DIGEST_LIST
 				   &ima_htable_value_ops);
+#else
+				   &ima_measurements_count_ops);
+#endif
 	if (IS_ERR(runtime_measurements_count))
 		goto out;
 
 	violations =
 	    securityfs_create_file("violations", S_IRUSR | S_IRGRP,
+#ifdef CONFIG_IMA_DIGEST_LIST
 				   ima_dir, NULL, &ima_htable_value_ops);
+#else
+				   ima_dir, NULL, &ima_htable_violations_ops);
+#endif
 	if (IS_ERR(violations))
 		goto out;
 
 	ima_policy = securityfs_create_file("policy", POLICY_FILE_FLAGS,
 					    ima_dir, NULL,
+#ifdef CONFIG_IMA_DIGEST_LIST
 					    &ima_data_upload_ops);
+#else
+						&ima_measure_policy_ops);
+#endif
 	if (IS_ERR(ima_policy))
 		goto out;
 
@@ -634,9 +858,11 @@ int __init ima_fs_init(void)
 #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..7ab87713a2e4 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -86,7 +86,11 @@ static int __init ima_add_boot_aggregate(void)
 
 	result = ima_store_template(entry, violation, NULL,
 				    boot_aggregate_name,
+#ifdef CONFIG_IMA_DIGEST_LIST
 				    CONFIG_IMA_MEASURE_PCR_IDX, NULL);
+#else
+				    CONFIG_IMA_MEASURE_PCR_IDX);
+#endif
 	if (result < 0) {
 		ima_free_template_entry(entry);
 		audit_cause = "store_entry";
@@ -107,8 +111,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..0afcbd5dd196 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 /* CONFIG_IMA_DIGEST_LIST */
 
 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,39 @@ 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)
 		ima_store_measurement(iint, file, pathname,
 				      xattr_value, xattr_len, modsig, pcr,
+#ifdef CONFIG_IMA_DIGEST_LIST
 				      template_desc,
 				      ima_digest_allow(found_digest,
 						       IMA_MEASURE));
+#else
+				      template_desc);
+#endif
 
 	if (rc == 0 && (action & IMA_APPRAISE_SUBMASK)) {
 		rc = ima_check_blacklist(iint, modsig, pcr);
 		if (rc != -EPERM) {
 			inode_lock(inode);
+
 			rc = ima_appraise_measurement(func, iint, file,
 					      pathname, xattr_value,
+#ifdef CONFIG_IMA_DIGEST_LIST
 					      xattr_len, modsig,
 					      ima_digest_allow(found_digest,
 							       IMA_APPRAISE));
+#else
+					      xattr_len, modsig);
+#endif
 			inode_unlock(inode);
 		}
 		if (!rc)
@@ -568,15 +587,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 +766,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 +970,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..84528e1413ad 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 /* CONFIG_IMA_DIGEST_LIST */
 
 		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..4a7b5df58863 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -46,8 +46,10 @@ static const struct ima_template_field supported_fields[] = {
 	 .field_show = ima_show_template_digest_ng},
 	{.field_id = "modsig", .field_init = ima_eventmodsig_init,
 	 .field_show = ima_show_template_sig},
+#ifdef CONFIG_IMA_DIGEST_LIST
 	{.field_id = "evmsig", .field_init = ima_eventevmsig_init,
 	 .field_show = ima_show_template_sig},
+#endif
 };
 
 /*
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..7d0d5be28908 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 /* CONFIG_IMA_DIGEST_LIST */
 #endif /* __LINUX_IMA_TEMPLATE_LIB_H */
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 77e6819e8db8..cb1c178f8ac4 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,27 +176,11 @@ 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);
 void __init ima_load_digest_lists(void);
-#else
-static inline struct ima_digest *ima_lookup_digest(u8 *digest,
-						   enum hash_algo algo,
-						   enum compact_types type)
-{
-	return NULL;
-}
-static inline struct ima_digest *ima_digest_allow(struct ima_digest *digest,
-						  int action)
-{
-	return NULL;
-}
-static inline void ima_load_digest_lists(void)
-{
-}
-#endif
+#endif  /* CONFIG_IMA_DIGEST_LIST */
 
 /* rbtree tree calls to lookup, insert, delete
  * integrity data associated with an inode.
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
                            
                          
                          
                            
    
                          
                        
                     
                        
                    
                        
                            
                                
                            
                            [PATCH v4 openEuler-23.09] ima: Add macros to isolate the IMA digest list
                        
                        
by Zhou Shuiqing 04 Sep '23
                    by Zhou Shuiqing 04 Sep '23
04 Sep '23
                    
                        euleros inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I277UJ
--------------------------------
Isolate the IMA digest list code by using macros.
changelog
v2:
	Exclude some macros for code that has already
	been merged into upstream kernel.
v3:
	add patch header and fix some simple code warnings
v4:
	merge some duplicate code and add macro comments.
Signed-off-by: Zhou Shuiqing <zhoushuiqing2(a)huawei.com>
---
 fs/xattr.c                                |   4 +
 include/linux/evm.h                       |   5 +-
 include/linux/ima.h                       |   8 +
 include/linux/integrity.h                 |   2 +
 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         | 117 +++++++++++
 security/integrity/iint.c                 |   4 +
 security/integrity/ima/ima.h              |  62 +++++-
 security/integrity/ima/ima_api.c          |  39 ++++
 security/integrity/ima/ima_appraise.c     | 125 +++++++++++-
 security/integrity/ima/ima_fs.c           | 238 +++++++++++++++++++++-
 security/integrity/ima/ima_init.c         |   6 +
 security/integrity/ima/ima_main.c         |  33 +++
 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            |  32 ++-
 security/security.c                       |   2 +
 21 files changed, 785 insertions(+), 28 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..fbaebb01b8a6 100644
--- a/include/linux/evm.h
+++ b/include/linux/evm.h
@@ -35,7 +35,9 @@ 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);
+#ifdef CONFIG_IMA_DIGEST_LIST
 extern bool evm_status_revalidate(const char *xattr_name);
+#endif
 #ifdef CONFIG_FS_POSIX_ACL
 extern int posix_xattr_acl(const char *xattrname);
 #else
@@ -105,10 +107,11 @@ static inline int evm_inode_init_security(struct inode *inode,
 	return 0;
 }
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static inline bool evm_status_revalidate(const char *xattr_name)
 {
 	return false;
 }
-
+#endif /* CONFIG_IMA_DIGEST_LIST */
 #endif /* CONFIG_EVM */
 #endif /* LINUX_EVM_H */
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/include/linux/integrity.h b/include/linux/integrity.h
index 2ea0f2f65ab6..b3e403f214f0 100644
--- a/include/linux/integrity.h
+++ b/include/linux/integrity.h
@@ -13,7 +13,9 @@ enum integrity_status {
 	INTEGRITY_PASS = 0,
 	INTEGRITY_PASS_IMMUTABLE,
 	INTEGRITY_FAIL,
+#ifdef CONFIG_IMA_DIGEST_LIST
 	INTEGRITY_FAIL_IMMUTABLE,
+#endif
 	INTEGRITY_NOLABEL,
 	INTEGRITY_NOXATTRS,
 	INTEGRITY_UNKNOWN,
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..c67271c45e50 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>
@@ -27,10 +29,17 @@
 
 int evm_initialized;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 static const char * const integrity_status_msg[] = {
 	"pass", "pass_immutable", "fail", "fail_immutable", "no_label",
 	"no_xattrs", "unknown"
 };
+#else
+static const char * const integrity_status_msg[] = {
+	"pass", "pass_immutable", "fail", "no_label", "no_xattrs", "unknown"
+};
+#endif
+
 int evm_hmac_attrs;
 
 static struct xattr_list evm_config_default_xattrnames[] = {
@@ -57,22 +66,32 @@ 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)
+#else
+static int __init evm_set_fixmode(char *str)
+#endif
 {
 	if (strncmp(str, "fix", 3) == 0)
 		evm_fixmode = 1;
+#ifdef CONFIG_IMA_DIGEST_LIST
 	else if (strncmp(str, "x509", 4) == 0)
 		evm_initialized |= EVM_INIT_X509;
 	else if (strncmp(str, "allow_metadata_writes", 21) == 0)
 		evm_initialized |= EVM_ALLOW_METADATA_WRITES;
 	else if (strncmp(str, "complete", 8) == 0)
 		evm_initialized |= EVM_SETUP_COMPLETE;
+#endif
 	else
 		pr_err("invalid \"%s\" mode", str);
 
 	return 1;
 }
+#ifdef CONFIG_IMA_DIGEST_LIST
 __setup("evm=", evm_set_param);
+#else
+__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,23 +255,37 @@ 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) {
+#else
+		if (xattr_len != sizeof(struct evm_xattr)) {
+#endif
 			evm_status = INTEGRITY_FAIL;
 			goto out;
 		}
+#ifdef CONFIG_IMA_DIGEST_LIST
 		digest.hdr.algo = evm_hash_algo;
+#else
+		digest.hdr.algo = HASH_ALGO_SHA1;
+#endif
 		rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
 				   xattr_value_len, &digest);
 		if (rc)
 			break;
 		rc = crypto_memneq(xattr_data->data, digest.digest,
+#ifdef CONFIG_IMA_DIGEST_LIST
 				   hash_digest_size[evm_hash_algo]);
+#else
+				   SHA1_DIGEST_SIZE);
+#endif
 		if (rc)
 			rc = -EINVAL;
 		break;
 	case EVM_XATTR_PORTABLE_DIGSIG:
+#ifdef CONFIG_IMA_DIGEST_LIST
 		evm_immutable = 1;
 		fallthrough;
+#endif
 	case EVM_IMA_XATTR_DIGSIG:
 		/* accept xattr with non-empty signature field */
 		if (xattr_len <= sizeof(struct signature_v2_hdr)) {
@@ -262,6 +318,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 +359,13 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
 			evm_status = INTEGRITY_PASS;
 		}
 		break;
+#endif /* CONFIG_IMA_DIGEST_LIST */
 	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 +374,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 +463,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 +535,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 +587,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 +601,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 +639,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 +679,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 +704,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 +722,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 +752,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 +782,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,19 +805,26 @@ 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);
+
 	/*
 	 * Writing attrs is safe for portable signatures, as portable signatures
 	 * are immutable and can never be updated.
 	 */
 	if ((evm_status == INTEGRITY_PASS) ||
+#ifdef CONFIG_IMA_DIGEST_LIST
 	    (evm_status == INTEGRITY_NOXATTRS) ||
 	    (evm_status == INTEGRITY_FAIL_IMMUTABLE) ||
 	    (evm_ignore_error_safe(evm_status)))
+#else
+		(evm_status == INTEGRITY_NOXATTRS))
+#endif
 		return 0;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (evm_status == INTEGRITY_PASS_IMMUTABLE &&
 	    !evm_attr_change(dentry, attr))
 		return 0;
+#endif
 
 	integrity_audit_msg(AUDIT_INTEGRITY_METADATA, d_backing_inode(dentry),
 			    dentry->d_name.name, "appraise_metadata",
@@ -747,10 +845,16 @@ 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))
+#else
+	if (!evm_key_loaded())
+#endif
 		return;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	evm_reset_status(dentry->d_inode);
+#endif
 
 	if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
 		evm_update_evmxattr(dentry, NULL, NULL, 0);
@@ -766,8 +870,12 @@ int evm_inode_init_security(struct inode *inode,
 	struct evm_xattr *xattr_data;
 	int rc;
 
+#ifdef CONFIG_IMA_DIGEST_LIST
 	if (!(evm_initialized & EVM_INIT_HMAC) ||
 	    !evm_protected_xattr(lsm_xattr->name))
+#else
+	if (!evm_key_loaded() || !evm_protected_xattr(lsm_xattr->name))
+#endif
 		return 0;
 
 	xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS);
@@ -780,7 +888,11 @@ 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;
+#else
+	evm_xattr->value_len = sizeof(*xattr_data);
+#endif
 	evm_xattr->name = XATTR_EVM_SUFFIX;
 	return 0;
 out:
@@ -802,6 +914,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 +922,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..bd66cadc4a3a 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))
+#endif
 		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..2145eb0c76e0 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 /* CONFIG_IMA_DIGEST_LIST */
 
 #define __ima_hook_enumify(ENUM, str)	ENUM,
 #define __ima_stringify(arg) (#arg)
@@ -268,8 +286,12 @@ 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,
+#ifdef CONFIG_IMA_DIGEST_LIST
 			   struct ima_template_desc *template_desc,
 			   struct ima_digest *digest);
+#else
+			   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);
@@ -280,7 +302,11 @@ int ima_alloc_init_template(struct ima_event_data *event_data,
 			    struct ima_template_desc *template_desc);
 int ima_store_template(struct ima_template_entry *entry, int violation,
 		       struct inode *inode, const unsigned char *filename,
+#ifdef CONFIG_IMA_DIGEST_LIST
 		       int pcr, struct ima_digest *digest);
+#else
+			   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,7 +334,9 @@ 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,
@@ -317,12 +345,24 @@ 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,
+#ifdef CONFIG_IMA_DIGEST_LIST
 			     int xattr_len, const struct modsig *modsig,
 			     struct ima_digest *found_digest);
+#else
+			     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)
@@ -336,8 +376,12 @@ static inline int ima_appraise_measurement(enum ima_hooks func,
 					   const unsigned char *filename,
 					   struct evm_ima_xattr_data *xattr_value,
 					   int xattr_len,
+#ifndef CONFIG_IMA_DIGEST_LIST
 					   const struct modsig *modsig,
 					   struct ima_digest *found_digest)
+#else
+					   const struct modsig *modsig)
+#endif
 {
 	return INTEGRITY_UNKNOWN;
 }
@@ -360,6 +404,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..3c59049e58ad 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;
+	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 /* CONFIG_IMA_DIGEST_LIST */
+
 /*
  * 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,21 +286,28 @@ 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;
 				break;
 			}
+#ifdef CONFIG_IMA_DIGEST_LIST
 			clear_bit(IMA_DIGSIG, &iint->atomic_flags);
 		} else {
 			set_bit(IMA_DIGSIG, &iint->atomic_flags);
+#endif
 		}
 		if (xattr_len - sizeof(xattr_value->type) - hash_start >=
 				iint->ima_hash->length)
@@ -352,26 +428,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 +483,7 @@ int ima_appraise_measurement(enum ima_hooks func,
 			rc = xattr_len;
 		}
 	}
+#endif /* CONFIG_IMA_DIGEST_LIST */
 
 	/* If reading the xattr failed and there's no modsig, error out. */
 	if (rc <= 0 && !try_modsig) {
@@ -417,11 +507,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 +523,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 +541,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 +556,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 +565,15 @@ int ima_appraise_measurement(enum ima_hooks func,
 				    filename, op, cause, rc, 0);
 		goto out;
 	}
+#endif
 
 	if (xattr_value)
 		rc = xattr_verify(func, iint, xattr_value, xattr_len, &status,
+#ifdef CONFIG_IMA_DIGEST_LIST
 				  &cause, found_digest);
+#else
+				  &cause);
+#endif
 
 	/*
 	 * If we have a modsig and either no imasig or the imasig's key isn't
@@ -508,7 +612,11 @@ int ima_appraise_measurement(enum ima_hooks func,
 		 * without data.
 		 */
 		if (inode->i_size == 0 && iint->flags & IMA_NEW_FILE &&
+#ifdef CONFIG_IMA_DIGEST_LIST
 		    test_bit(IMA_DIGSIG, &iint->atomic_flags)) {
+#else
+		    xattr_value && xattr_value->type == EVM_IMA_XATTR_DIGSIG) {
+#endif
 			status = INTEGRITY_PASS;
 		}
 
@@ -567,6 +675,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 +732,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 +758,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 +766,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 +783,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..996a287b4b77 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,55 @@ 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 /* CONFIG_IMA_DIGEST_LIST */
 
+#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 /* CONFIG_IMA_DIGEST_LIST */
 
 /* returns pointer to hlist_node */
 static void *ima_measurements_start(struct seq_file *m, loff_t *pos)
@@ -275,6 +318,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 +364,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 +371,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 +385,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 +501,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 /* CONFIG_IMA_DIGEST_LIST */
 
 static unsigned long ima_fs_flags;
 
@@ -473,6 +611,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 +707,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 /* CONFIG_IMA_DIGEST_LIST */
 
 int __init ima_fs_init(void)
 {
@@ -597,19 +809,31 @@ int __init ima_fs_init(void)
 	runtime_measurements_count =
 	    securityfs_create_file("runtime_measurements_count",
 				   S_IRUSR | S_IRGRP, ima_dir, NULL,
+#ifdef CONFIG_IMA_DIGEST_LIST
 				   &ima_htable_value_ops);
+#else
+				   &ima_measurements_count_ops);
+#endif
 	if (IS_ERR(runtime_measurements_count))
 		goto out;
 
 	violations =
 	    securityfs_create_file("violations", S_IRUSR | S_IRGRP,
+#ifdef CONFIG_IMA_DIGEST_LIST
 				   ima_dir, NULL, &ima_htable_value_ops);
+#else
+				   ima_dir, NULL, &ima_htable_violations_ops);
+#endif
 	if (IS_ERR(violations))
 		goto out;
 
 	ima_policy = securityfs_create_file("policy", POLICY_FILE_FLAGS,
 					    ima_dir, NULL,
+#ifdef CONFIG_IMA_DIGEST_LIST
 					    &ima_data_upload_ops);
+#else
+						&ima_measure_policy_ops);
+#endif
 	if (IS_ERR(ima_policy))
 		goto out;
 
@@ -634,9 +858,11 @@ int __init ima_fs_init(void)
 #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..7ab87713a2e4 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -86,7 +86,11 @@ static int __init ima_add_boot_aggregate(void)
 
 	result = ima_store_template(entry, violation, NULL,
 				    boot_aggregate_name,
+#ifdef CONFIG_IMA_DIGEST_LIST
 				    CONFIG_IMA_MEASURE_PCR_IDX, NULL);
+#else
+				    CONFIG_IMA_MEASURE_PCR_IDX);
+#endif
 	if (result < 0) {
 		ima_free_template_entry(entry);
 		audit_cause = "store_entry";
@@ -107,8 +111,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..0afcbd5dd196 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 /* CONFIG_IMA_DIGEST_LIST */
 
 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,39 @@ 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)
 		ima_store_measurement(iint, file, pathname,
 				      xattr_value, xattr_len, modsig, pcr,
+#ifdef CONFIG_IMA_DIGEST_LIST
 				      template_desc,
 				      ima_digest_allow(found_digest,
 						       IMA_MEASURE));
+#else
+				      template_desc);
+#endif
 
 	if (rc == 0 && (action & IMA_APPRAISE_SUBMASK)) {
 		rc = ima_check_blacklist(iint, modsig, pcr);
 		if (rc != -EPERM) {
 			inode_lock(inode);
+
 			rc = ima_appraise_measurement(func, iint, file,
 					      pathname, xattr_value,
+#ifdef CONFIG_IMA_DIGEST_LIST
 					      xattr_len, modsig,
 					      ima_digest_allow(found_digest,
 							       IMA_APPRAISE));
+#else
+					      xattr_len, modsig);
+#endif
 			inode_unlock(inode);
 		}
 		if (!rc)
@@ -568,15 +587,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 +766,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 +970,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..84528e1413ad 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 /* CONFIG_IMA_DIGEST_LIST */
 
 		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..4a7b5df58863 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -46,8 +46,10 @@ static const struct ima_template_field supported_fields[] = {
 	 .field_show = ima_show_template_digest_ng},
 	{.field_id = "modsig", .field_init = ima_eventmodsig_init,
 	 .field_show = ima_show_template_sig},
+#ifdef CONFIG_IMA_DIGEST_LIST
 	{.field_id = "evmsig", .field_init = ima_eventevmsig_init,
 	 .field_show = ima_show_template_sig},
+#endif
 };
 
 /*
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..7d0d5be28908 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 /* CONFIG_IMA_DIGEST_LIST */
 #endif /* __LINUX_IMA_TEMPLATE_LIB_H */
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 77e6819e8db8..cb1c178f8ac4 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,27 +176,11 @@ 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);
 void __init ima_load_digest_lists(void);
-#else
-static inline struct ima_digest *ima_lookup_digest(u8 *digest,
-						   enum hash_algo algo,
-						   enum compact_types type)
-{
-	return NULL;
-}
-static inline struct ima_digest *ima_digest_allow(struct ima_digest *digest,
-						  int action)
-{
-	return NULL;
-}
-static inline void ima_load_digest_lists(void)
-{
-}
-#endif
+#endif  /* CONFIG_IMA_DIGEST_LIST */
 
 /* rbtree tree calls to lookup, insert, delete
  * integrity data associated with an inode.
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
                            
                          
                          
                            
    
                          
                        
                    
                    
                        Ye Bin (4):
  ext2: remove ext2_new_block()
  ext2: introduce flag argument for ext2_new_blocks()
  ext2: fix race between setxattr and write back
  ext2: dump current reservation window info
 fs/ext2/balloc.c | 32 +++++++++++++++++---------------
 fs/ext2/ext2.h   |  8 ++++++--
 fs/ext2/inode.c  |  2 +-
 fs/ext2/xattr.c  |  4 +++-
 4 files changed, 27 insertions(+), 19 deletions(-)
-- 
2.31.1
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            10
                            
                          
                          
                            
    
                          
                        
                     
                        
                    04 Sep '23
                    
                        Ye Bin (4):
  ext2: remove ext2_new_block()
  ext2: introduce flag argument for ext2_new_blocks()
  ext2: fix race between setxattr and write back
  ext2: dump current reservation window info
 fs/ext2/balloc.c | 32 +++++++++++++++++---------------
 fs/ext2/ext2.h   |  8 ++++++--
 fs/ext2/inode.c  |  2 +-
 fs/ext2/xattr.c  |  4 +++-
 4 files changed, 27 insertions(+), 19 deletions(-)
-- 
2.31.1
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            10
                            
                          
                          
                            
    
                          
                        
                    
                    
                        Ye Bin (4):
  ext2: remove ext2_new_block()
  ext2: introduce flag argument for ext2_new_blocks()
  ext2: fix race between setxattr and write back
  ext2: dump current reservation window info
 fs/ext2/balloc.c | 32 +++++++++++++++++---------------
 fs/ext2/ext2.h   |  8 ++++++--
 fs/ext2/inode.c  |  2 +-
 fs/ext2/xattr.c  |  4 +++-
 4 files changed, 27 insertions(+), 19 deletions(-)
-- 
2.31.1
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            3
                            
                          
                          
                            
    
                          
                        
                     
                        
                    04 Sep '23
                    
                        Hou Tao (5):
  vfs: add bare tracepoints for vfs read and release
  fs: add helper fs_file_read_do_trace()
  xfs: add trace for read and release of regular file
  ext4: add trace for the read and release of regular file
  selftests/bpf: add demo for file read pattern detection
Yufen Yu (1):
  readahead: introduce FMODE_CTL_WILLNEED to read first 2MB of file
ZhaoLong Wang (2):
  VFS: Rolling Back the fmode macro definition and structure members
  selftests/bpf: Update the demo file_read_pattern to run on libbpf 1.0+
 fs/ext4/file.c                                |   4 +
 fs/read_write.c                               |  38 +++++
 fs/xfs/xfs_file.c                             |   3 +
 include/linux/fs.h                            |  37 +++++
 include/trace/events/fs.h                     |  33 ++++
 mm/readahead.c                                |  40 ++++-
 tools/testing/selftests/bpf/Makefile          |   1 +
 .../testing/selftests/bpf/file_read_pattern.c |  73 +++++++++
 .../bpf/progs/file_read_pattern_prog.c        | 142 ++++++++++++++++++
 9 files changed, 370 insertions(+), 1 deletion(-)
 create mode 100644 include/trace/events/fs.h
 create mode 100644 tools/testing/selftests/bpf/file_read_pattern.c
 create mode 100644 tools/testing/selftests/bpf/progs/file_read_pattern_prog.c
-- 
2.39.2
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            9
                            
                          
                          
                            
    
                          
                        
                     
                        
                    
                        
                            
                                
                            
                            [PATCH v2 openEuler-1.0-LTS] sched/smt: fix unbalance sched_smt_present dec/inc
                        
                        
by Yu Liao 04 Sep '23
                    by Yu Liao 04 Sep '23
04 Sep '23
                    
                        hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I7YBSW
CVE: NA
--------------------------------
If cpuset_cpu_inactive() fails in sched_cpu_deactivate(), the
cpu offline failed, but sched_smt_present is decreased before
calling sched_cpu_deactivate, it leads unbalance dec/inc, so
fix it by increasing sched_smt_present in the error path.
Signed-off-by: Yang Yingliang <yangyingliang(a)huawei.com>
Signed-off-by: Yu Liao <liaoyu15(a)huawei.com>
---
 kernel/sched/core.c | 4 ++++
 1 file changed, 4 insertions(+)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 67bda877bfa8..7825ceaae0c4 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -5897,6 +5897,10 @@ int sched_cpu_deactivate(unsigned int cpu)
 
 	ret = cpuset_cpu_inactive(cpu);
 	if (ret) {
+#ifdef CONFIG_SCHED_SMT
+		if (cpumask_weight(cpu_smt_mask(cpu)) == 2)
+			static_branch_inc_cpuslocked(&sched_smt_present);
+#endif
 		set_cpu_active(cpu, true);
 		return ret;
 	}
-- 
2.25.1
                    
                  
                  
                          
                            
                            2
                            
                          
                          
                            
                            1
                            
                          
                          
                            
    
                          
                        
                    