arm64 CONFIG_DEBUG_SET_MODULE_RONX support
v4 cover arm64 CONFIG_DEBUG_SET_MODULE_RONX support
Hi,
This is another version of DEBUG_SET_MODULE_RONX support for arm64.
Thanks,
Laura
v4: Switch to one function to do set/clear per suggestion of Will
v3: Addressed comments by Will/Steve
Laura Abbott (2):
arm64: Introduce {set,clear}_pte_bit
arm64: Add CONFIG_DEBUG_SET_MODULE_RONX support
arch/arm64/Kconfig.debug | 11 +++++ arch/arm64/include/asm/cacheflush.h | 4 ++ arch/arm64/include/asm/pgtable.h | 33 +++++++------ arch/arm64/mm/Makefile | 2 +- arch/arm64/mm/pageattr.c | 96 +++++++++++++++++++++++++++++++++++++ 5 files changed, 131 insertions(+), 15 deletions(-) create mode 100644 arch/arm64/mm/pageattr.c
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
PATCH v4 1/2 arm64: Introduce {set,clear}_pte_bit
It's useful to be able to change individual bits in ptes at times. Introduce functions for this and update existing pte_mk* functions to use these primatives.
--- arch/arm64/include/asm/pgtable.h | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-)
arch/arm64/include/asm/pgtable.h +19 -14
@@ -149,46 +149,51 @@ extern struct page *empty_zero_page;#define pte_valid_not_user (pte) \ ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID) -static inline pte_t pte_wrprotect (pte_t pte) +static pte_t clear_pte_bit (pte_t pte,pgprot_t prot) { -pte_val (pte) &= ~PTE_WRITE ; +pte_val (pte) &= ~pgprot_val (prot);return pte; } -static inline pte_t pte_mkwrite (pte_t pte) +static pte_t set_pte_bit (pte_t pte,pgprot_t prot) { -pte_val (pte) |=PTE_WRITE ; +pte_val (pte) |=pgprot_val (prot);return pte; } +static inline pte_t pte_wrprotect (pte_t pte) +{ +return clear_pte_bit (pte,__pgprot (PTE_WRITE )); +} + +static inline pte_t pte_mkwrite (pte_t pte) +{ +return set_pte_bit (pte,__pgprot (PTE_WRITE )); +} +static inline pte_t pte_mkclean (pte_t pte) { -pte_val (pte) &= ~PTE_DIRTY ; -return pte; +return clear_pte_bit (pte,__pgprot (PTE_DIRTY )); }static inline pte_t pte_mkdirty (pte_t pte) { -pte_val (pte) |=PTE_DIRTY ; -return pte; +return set_pte_bit (pte,__pgprot (PTE_DIRTY )); }static inline pte_t pte_mkold (pte_t pte) { -pte_val (pte) &= ~PTE_AF ; -return pte; +return clear_pte_bit (pte,__pgprot (PTE_AF )); }static inline pte_t pte_mkyoung (pte_t pte) { -pte_val (pte) |=PTE_AF ; -return pte; +return set_pte_bit (pte,__pgprot (PTE_AF )); }static inline pte_t pte_mkspecial (pte_t pte) { -pte_val (pte) |=PTE_SPECIAL ; -return pte; +return set_pte_bit (pte,__pgprot (PTE_SPECIAL )); }static inline void set_pte (pte_t *ptep,pte_t pte)
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Catalin Marinas
maintainerPATCH v4 1/2 arm64: Introduce {set,clear}_pte_bit
Quoted 13 lines · Laura Abbott
arch/arm64/include/asm/pgtable.h +2
-2@@ -149,46 +149,51 @@ extern struct page *empty_zero_page;#define pte_valid_not_user (pte) \ ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID) -static inline pte_t pte_wrprotect (pte_t pte) +static pte_t clear_pte_bit (pte_t pte,pgprot_t prot) { -pte_val (pte) &= ~PTE_WRITE ; +pte_val (pte) &= ~pgprot_val (prot);
arch/arm64/include/asm/pgtable.h extern struct page *empty_zero_page; · line 162
Quoted 10 lines
arch/arm64/include/asm/pgtable.h +2
-2return pte; } -static inline pte_t pte_mkwrite (pte_t pte) +static pte_t set_pte_bit (pte_t pte,pgprot_t prot) { -pte_val (pte) |=PTE_WRITE ; +pte_val (pte) |=pgprot_val (prot);return pte; }
Why these two functions don't have an "inline"?
Signature · 1 line
Catalin
PATCH v4 1/2 arm64: Introduce {set,clear}_pte_bit
Quoted 17 lines · Catalin Marinas
Quoted 16 lines · Laura Abbott
arch/arm64/include/asm/pgtable.h +2
-2@@ -149,46 +149,51 @@ extern struct page *empty_zero_page;#define pte_valid_not_user (pte) \ ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID) -static inline pte_t pte_wrprotect (pte_t pte) +static pte_t clear_pte_bit (pte_t pte,pgprot_t prot) { -pte_val (pte) &= ~PTE_WRITE ; +pte_val (pte) &= ~pgprot_val (prot);return pte; }
Quoted 10 lines
arch/arm64/include/asm/pgtable.h extern struct page *empty_zero_page; · line 162
Quoted 7 lines
arch/arm64/include/asm/pgtable.h +2
-2-static inline pte_t pte_mkwrite (pte_t pte) +static pte_t set_pte_bit (pte_t pte,pgprot_t prot) { -pte_val (pte) |=PTE_WRITE ; +pte_val (pte) |=pgprot_val (prot);return pte; }Why these two functions don't have an "inline"?
That's an error on my part.
Will, you mentioned you applied these patches already, how would you like to fix this up?
Laura
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH v4 1/2 arm64: Introduce {set,clear}_pte_bit
Quoted 29 lines · Laura Abbott
Quoted 17 lines · Catalin Marinas
Quoted 16 lines · Laura Abbott
arch/arm64/include/asm/pgtable.h +2
-2@@ -149,46 +149,51 @@ extern struct page *empty_zero_page;#define pte_valid_not_user (pte) \ ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID) -static inline pte_t pte_wrprotect (pte_t pte) +static pte_t clear_pte_bit (pte_t pte,pgprot_t prot) { -pte_val (pte) &= ~PTE_WRITE ; +pte_val (pte) &= ~pgprot_val (prot);return pte; }Quoted 10 lines
arch/arm64/include/asm/pgtable.h extern struct page *empty_zero_page; · line 162
Quoted 7 lines
arch/arm64/include/asm/pgtable.h +2
-2-static inline pte_t pte_mkwrite (pte_t pte) +static pte_t set_pte_bit (pte_t pte,pgprot_t prot) { -pte_val (pte) |=PTE_WRITE ; +pte_val (pte) |=pgprot_val (prot);return pte; }Why these two functions don't have an "inline"?
Quoted 4 lines
That's an error on my part.
Will, you mentioned you applied these patches already, how would you like to fix this up?
Yup, I can easily add the missing inline keywords. Did you see Catalin's other comment? It looks like we're missing a '-1' on the end address before checking whether or not it sits in a module. If you confirm, I can add that too.
Will
PATCH v4 1/2 arm64: Introduce {set,clear}_pte_bit
Quoted 35 lines · Will Deacon
Quoted 29 lines · Laura Abbott
Quoted 17 lines · Catalin Marinas
Quoted 16 lines · Laura Abbott
arch/arm64/include/asm/pgtable.h +2
-2@@ -149,46 +149,51 @@ extern struct page *empty_zero_page;#define pte_valid_not_user (pte) \ ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID) -static inline pte_t pte_wrprotect (pte_t pte) +static pte_t clear_pte_bit (pte_t pte,pgprot_t prot) { -pte_val (pte) &= ~PTE_WRITE ; +pte_val (pte) &= ~pgprot_val (prot);return pte; }Quoted 10 lines
arch/arm64/include/asm/pgtable.h extern struct page *empty_zero_page; · line 162
Quoted 7 lines
arch/arm64/include/asm/pgtable.h +2
-2-static inline pte_t pte_mkwrite (pte_t pte) +static pte_t set_pte_bit (pte_t pte,pgprot_t prot) { -pte_val (pte) |=PTE_WRITE ; +pte_val (pte) |=pgprot_val (prot);return pte; }Why these two functions don't have an "inline"?
Quoted 4 lines
That's an error on my part.
Will, you mentioned you applied these patches already, how would you like to fix this up?
Quoted 7 lines
Yup, I can easily add the missing inline keywords. Did you see Catalin's other comment? It looks like we're missing a '-1' on the end address before checking whether or not it sits in a module. If you confirm, I can add that too.
Will
Yes, Catalin's review was correct, we need the -1 as well.
Thanks,
Laura
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH v4 2/2 arm64: Add CONFIG_DEBUG_SET_MODULE_RONX support
In reply to Laura AbbottIn a similar fashion to other architecture, add the infrastructure and Kconfig to enable DEBUG_SET_MODULE_RONX support. When enabled, module ranges will be marked read-only/no-execute as appropriate.
--- arch/arm64/Kconfig.debug | 11 +++++ arch/arm64/include/asm/cacheflush.h | 4 ++ arch/arm64/mm/Makefile | 2 +- arch/arm64/mm/pageattr.c | 96 +++++++++++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/mm/pageattr.c
arch/arm64/Kconfig.debug +11 -0
@@ -43,4 +43,15 @@ config ARM64_RANDOMIZE_TEXT_OFFSET of TEXT_OFFSET and platforms must not require a specific value. +config DEBUG_SET_MODULE_RONX + bool "Set loadable kernel module data as NX and text as RO" + depends on MODULES + help + This option helps catch unintended modifications to loadable + kernel module's text and read-only data. It also prevents execution + of module data. Such protection may interfere with run-time code + patching and dynamic kernel tracing - and they might also protect + against certain classes of kernel exploits. + If in doubt, say "N". + endmenu
arch/arm64/include/asm/cacheflush.h +4 -0
@@ -148,4 +148,8 @@ static inline void flush_cache_vunmap(unsigned long start, unsigned long end) { } +int set_memory_ro (unsigned long addr,int numpages); +int set_memory_rw (unsigned long addr,int numpages); +int set_memory_x (unsigned long addr,int numpages); +int set_memory_nx (unsigned long addr,int numpages);#endif
arch/arm64/mm/Makefile +1 -1
@@ -1,5 +1,5 @@ obj-y := dma-mapping.o extable.o fault.o init.o \ cache.o copypage.o flush.o \ ioremap.o mmap.o pgd.o mmu.o \ - context.o proc.o + context.o proc.o pageattr.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
arch/arm64/mm/pageattr.c new file +96 -0
96 lines not on this page · raw message
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Catalin Marinas
maintainerPATCH v4 2/2 arm64: Add CONFIG_DEBUG_SET_MODULE_RONX support
Quoted 2 lines · Laura Abbott
arch/arm64/mm/pageattr.c new file +0
-0
[...]
Quoted 6 lines
arch/arm64/mm/pageattr.c new file +6
-0+static int change_memory_common (unsigned long addr,int numpages, +pgprot_t set_mask,pgprot_t clear_mask) +{ +unsigned long start = addr; +unsigned long size =PAGE_SIZE *numpages; +unsigned long end = start + size;
arch/arm64/mm/pageattr.c line 54
Quoted 10 lines
arch/arm64/mm/pageattr.c new file +10
-0+int ret; +struct page_change_data data; + +if (!IS_ALIGNED (addr,PAGE_SIZE )) { + addr &=PAGE_MASK ; +WARN_ON_ONCE (1 ); + } + +if (!is_module_address (start) || !is_module_address (end)) +return -EINVAL ;
Minor thing, "end" is exclusive here. Do you still get the right check with is_module_address(end)?
Signature · 1 line
Catalin
PATCH v4 2/2 arm64: Add CONFIG_DEBUG_SET_MODULE_RONX support
Quoted 15 lines · Catalin Marinas
Quoted 2 lines · Laura Abbott
arch/arm64/mm/pageattr.c new file +0
-0[...]
Quoted 11 lines
arch/arm64/mm/pageattr.c new file +11
-0+static int change_memory_common (unsigned long addr,int numpages, +pgprot_t set_mask,pgprot_t clear_mask) +{ +unsigned long start = addr; +unsigned long size =PAGE_SIZE *numpages; +unsigned long end = start + size; +int ret; +struct page_change_data data; + +if (!IS_ALIGNED (addr,PAGE_SIZE )) { + addr &=PAGE_MASK ;
Quoted 9 lines
arch/arm64/mm/pageattr.c line 54
Quoted 5 lines
arch/arm64/mm/pageattr.c new file +5
-0+WARN_ON_ONCE (1 ); + } + +if (!is_module_address (start) || !is_module_address (end)) +return -EINVAL ;Minor thing, "end" is exclusive here. Do you still get the right check with
is_module_address(end)?
No, You are correct. I'll talk to Will to get that fixed up.
Thanks,
Laura
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH v4 2/2 arm64: Add CONFIG_DEBUG_SET_MODULE_RONX support
Quoted 26 lines · Laura Abbott
Quoted 15 lines · Catalin Marinas
Quoted 2 lines · Laura Abbott
arch/arm64/mm/pageattr.c new file +0
-0[...]
Quoted 11 lines
arch/arm64/mm/pageattr.c new file +11
-0+static int change_memory_common (unsigned long addr,int numpages, +pgprot_t set_mask,pgprot_t clear_mask) +{ +unsigned long start = addr; +unsigned long size =PAGE_SIZE *numpages; +unsigned long end = start + size; +int ret; +struct page_change_data data; + +if (!IS_ALIGNED (addr,PAGE_SIZE )) { + addr &=PAGE_MASK ;Quoted 9 lines
arch/arm64/mm/pageattr.c line 54
Quoted 5 lines
arch/arm64/mm/pageattr.c new file +5
-0+WARN_ON_ONCE (1 ); + } + +if (!is_module_address (start) || !is_module_address (end)) +return -EINVAL ;Minor thing, "end" is exclusive here. Do you still get the right check with
is_module_address(end)?
Quoted 1 line
No, You are correct. I'll talk to Will to get that fixed up.
I already had a crack at fixing it:
How did I do?
Will
PATCH v4 2/2 arm64: Add CONFIG_DEBUG_SET_MODULE_RONX support
Hi Will,
Quoted 6 lines · Will Deacon
Quoted 5 lines · Laura Abbott
Quoted 4 lines · Catalin Marinas
Quoted 2 lines · Laura Abbott
arch/arm64/mm/pageattr.c new file +0
-0[...]
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
arch/arm64/mm/pageattr.c line 49
Quoted 11 lines
arch/arm64/mm/pageattr.c new file +11
-0+static int change_memory_common (unsigned long addr,int numpages, +pgprot_t set_mask,pgprot_t clear_mask) +{ +unsigned long start = addr; +unsigned long size =PAGE_SIZE *numpages; +unsigned long end = start + size; +int ret; +struct page_change_data data; + +if (!IS_ALIGNED (addr,PAGE_SIZE )) { + addr &=PAGE_MASK ;
I don't see any uses of addr after this.
Perhaps we also meant to compute start and end?
Quoted 24 lines
Quoted 11 lines
Quoted 9 lines
arch/arm64/mm/pageattr.c line 54
Quoted 5 lines
arch/arm64/mm/pageattr.c new file +5
-0+WARN_ON_ONCE (1 ); + } + +if (!is_module_address (start) || !is_module_address (end)) +return -EINVAL ;Minor thing, "end" is exclusive here. Do you still get the right check with
is_module_address(end)?No, You are correct. I'll talk to Will to get that fixed up.
I already had a crack at fixing it:
How did I do?
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v4 2/2 arm64: Add CONFIG_DEBUG_SET_MODULE_RONX support
Quoted 7 lines · Zi Shen Lim
Quoted 6 lines · Will Deacon
Quoted 5 lines · Laura Abbott
Quoted 4 lines · Catalin Marinas
Quoted 2 lines · Laura Abbott
arch/arm64/mm/pageattr.c new file +0
-0[...]
Quoted 14 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
arch/arm64/mm/pageattr.c line 49
Quoted 11 lines
arch/arm64/mm/pageattr.c new file +11
-0+static int change_memory_common (unsigned long addr,int numpages, +pgprot_t set_mask,pgprot_t clear_mask) +{ +unsigned long start = addr; +unsigned long size =PAGE_SIZE *numpages; +unsigned long end = start + size; +int ret; +struct page_change_data data; + +if (!IS_ALIGNED (addr,PAGE_SIZE )) { + addr &=PAGE_MASK ;I don't see any uses of addr after this.
Perhaps we also meant to compute start and end?
Actually, I think the alignment fixup should just be performed directly on start, but this is Laura's code so it would be good if she could confirm.
Laura -- what's the right thing to do here? (sending a fix patch would be ideal :)
Will
PATCH v4 2/2 arm64: Add CONFIG_DEBUG_SET_MODULE_RONX support
Quoted 24 lines · Will Deacon
Quoted 7 lines · Zi Shen Lim
Quoted 6 lines · Will Deacon
Quoted 5 lines · Laura Abbott
Quoted 4 lines · Catalin Marinas
Quoted 2 lines · Laura Abbott
arch/arm64/mm/pageattr.c new file +0
-0[...]
Quoted 14 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
arch/arm64/mm/pageattr.c line 49
Quoted 11 lines
arch/arm64/mm/pageattr.c new file +11
-0+static int change_memory_common (unsigned long addr,int numpages, +pgprot_t set_mask,pgprot_t clear_mask) +{ +unsigned long start = addr; +unsigned long size =PAGE_SIZE *numpages; +unsigned long end = start + size; +int ret; +struct page_change_data data; + +if (!IS_ALIGNED (addr,PAGE_SIZE )) { + addr &=PAGE_MASK ;I don't see any uses of addr after this.
Perhaps we also meant to compute start and end?
Quoted 8 lines
Actually, I think the alignment fixup should just be performed directly on start, but this is Laura's code so it would be good if she could confirm.
Laura -- what's the right thing to do here? (sending a fix patch would be ideal :)
Will
Yes this needs to be fixed. I'll send a patch out tomorrow.
Thanks,
Laura
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH 1/1 arm64: pageattr: Correctly adjust unaligned start addresses
The start address needs to be actually updated after it is detected to be unaligned. Adjust it and the end address properly.
--- arch/arm64/mm/pageattr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm64/mm/pageattr.c +2 -1
@@ -46,7 +46,8 @@ static int change_memory_common(unsigned long addr, int numpages,struct page_change_data data;if (!IS_ALIGNED (addr,PAGE_SIZE )) { - addr &=PAGE_MASK ; + start &=PAGE_MASK ; + end = start + size;WARN_ON_ONCE (1 ); }
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
PATCH 1/1 arm64: pageattr: Correctly adjust unaligned start addresses
Quoted 15 lines · Laura Abbott
The start address needs to be actually updated after it is detected to be unaligned. Adjust it and the end address properly.
Reported-by Zi Shen Lim <[email protected]>Signed-off-by Laura Abbott <[email protected]>--- arch/arm64/mm/pageattr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)arch/arm64/mm/pageattr.c +0
-0
arch/arm64/mm/pageattr.c static int change_memory_common(unsigned long addr, int numpages, · line 53
Quoted 9 lines
arch/arm64/mm/pageattr.c +2
-1@@ -46,7 +46,8 @@ static int change_memory_common(unsigned long addr, int numpages,struct page_change_data data;if (!IS_ALIGNED (addr,PAGE_SIZE )) { - addr &=PAGE_MASK ; + start &=PAGE_MASK ; + end = start + size;WARN_ON_ONCE (1 ); }
Looks good to me.
Quoted 4 lines
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
PATCH 1/1 arm64: pageattr: Correctly adjust unaligned start addresses
In reply to Laura AbbottQuoted 9 lines · Laura Abbott
The start address needs to be actually updated after it is detected to be unaligned. Adjust it and the end address properly.
Reported-by Zi Shen Lim <[email protected]>Signed-off-by Laura Abbott <[email protected]>--- arch/arm64/mm/pageattr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Applied. Thanks.
Signature · 1 line
Catalin
v4 cover arm64 CONFIG_DEBUG_SET_MODULE_RONX support
In reply to Laura AbbottQuoted 6 lines · Laura Abbott
This is another version of
DEBUG_SET_MODULE_RONXsupport for arm64.Thanks,
Laurav4: Switch to one function to do set/clear per suggestion of Will
Thanks Laura. It looks like you addressed all the comments I made after you sent this too, so I've applied it to our devel branch for the moment.
Cheers,
Will