lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20210727102602.259038-1-wzc@smail.nju.edu.cn>
Date:   Tue, 27 Jul 2021 18:26:02 +0800
From:   Wang Zi-cheng <wzc@...il.nju.edu.cn>
To:     linux-hardening@...r.kernel.org
Cc:     Wang Zi-cheng <wzc@...il.nju.edu.cn>
Subject: [PATCH] RFC struct const ops pointer member hardening

Signed-off-by: Wang Zi-cheng <wzc@...il.nju.edu.cn>
----------------------
RFC struct const ops pointer member hardening

some security sensitive kernel objects, i.e. inode, file, use 'const' to declare operations pointers, 
and these pointers reference to the static global variables in read only data segment.

```
struct file {
  ...
	const struct file_operations	*f_op;

const struct file_operations ext4_file_operations = {
```

However, const pointers are just compile hints with no hardware restrictions and prone to be modified by attakers at runtime.

It would be safer to make sure struct const pointer members are not pointing to malicious payload in the slab objects(direct mapping region).

we only need to check "open" syscall, because most file-related operations start with "open".

On the other side, kernel uses `kmem_cache_create` to alloc file/inode rather than `kmalloc`, 
which makes it hard to exploit through heap overflow or UAF, so maybe this is not a "must" update.
----------------------
---
 arch/x86/include/asm/pgtable_64_types.h |  3 +++
 fs/open.c                               |  4 ++++
 include/linux/mm.h                      | 11 +++++++++++
 3 files changed, 18 insertions(+)

diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h
index 91ac10654570..ec6ce27dd3a3 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -133,13 +133,16 @@ extern unsigned int ptrs_per_p4d;
 # define VMALLOC_START		vmalloc_base
 # define VMALLOC_SIZE_TB	(pgtable_l5_enabled() ? VMALLOC_SIZE_TB_L5 : VMALLOC_SIZE_TB_L4)
 # define VMEMMAP_START		vmemmap_base
+# define DIRECT_MAPPING_SIZE_TB 	(pgtable_l5_enabled() ? DIRECT_MAPPING_TB_L5 : DIRECT_MAPPING_TB_L4)
 #else
 # define VMALLOC_START		__VMALLOC_BASE_L4
 # define VMALLOC_SIZE_TB	VMALLOC_SIZE_TB_L4
 # define VMEMMAP_START		__VMEMMAP_BASE_L4
+# define DIRECT_MAPPING_SIZE_TB		DIRECT_MAPPING_TB_L4
 #endif /* CONFIG_DYNAMIC_MEMORY_LAYOUT */
 
 #define VMALLOC_END		(VMALLOC_START + (VMALLOC_SIZE_TB << 40) - 1)
+#define DIRECT_MAPPING_END		(__PAGE_OFFSET + (DIRECT_MAPPING_SIZE_TB << 40) - 1)
 
 #define MODULES_VADDR		(__START_KERNEL_map + KERNEL_IMAGE_SIZE)
 /* The module sections ends with the start of the fixmap */
diff --git a/fs/open.c b/fs/open.c
index e53af13b5835..930cbd75e1e2 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -820,6 +820,10 @@ static int do_dentry_open(struct file *f,
 
 	/* normally all 3 are set; ->open() can clear them if needed */
 	f->f_mode |= FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE;
+	/* check if f_op point to malicious payload */
+	WARN_ON (!check_valid_ops_pointer((unsigned long) f->f_op));
+	WARN_ON (!check_valid_ops_pointer((unsigned long) f->f_inode->i_op));
+	
 	if (!open)
 		open = f->f_op->open;
 	if (open) {
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 8ae31622deef..75336676006b 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3251,5 +3251,16 @@ static inline int seal_check_future_write(int seals, struct vm_area_struct *vma)
 	return 0;
 }
 
+static inline bool check_valid_ops_pointer(unsigned long addr)
+{
+#ifdef CONFIG_X86_64
+	if (addr >= __PAGE_OFFSET && addr <= DIRECT_MAPPING_END) 
+		return false;
+	else
+		return true;
+#endif
+	return true;
+}
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_MM_H */
-- 
2.32.0



Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ