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>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 7 Apr 2020 01:09:02 -0400
From:   Alex Ghiti <alex@...ti.fr>
To:     Zong Li <zong.li@...ive.com>, palmer@...belt.com,
        paul.walmsley@...ive.com, linux-riscv@...ts.infradead.org,
        linux-kernel@...r.kernel.org
Subject: Re: [PATCH RFC 2/8] riscv/kaslr: introduce functions to clear page
 table

On 3/24/20 3:30 AM, Zong Li wrote:
> In KASLR, we need to re-create page table after getting a random
> destination. Introduce clear function to clear old content. Also, the
> page table entries allow writing value when it's empty, so we have to
> clear the early page table.
> 
> This patch is a preparation to support KASLR.
> 
> Signed-off-by: Zong Li <zong.li@...ive.com>
> ---
>   arch/riscv/mm/init.c | 54 ++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 54 insertions(+)
> 
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index ace5d74fd939..51e263c04fa2 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -315,6 +315,7 @@ static void __init create_pmd_mapping(pmd_t *pmdp,
>   #define get_pgd_next_virt(__pa)	get_pmd_virt(__pa)
>   #define create_pgd_next_mapping(__nextp, __va, __pa, __sz, __prot)	\
>   	create_pmd_mapping(__nextp, __va, __pa, __sz, __prot)
> +#define clear_pgd_next_mapping(__nextp)	clear_pmd(__nextp)
>   #define fixmap_pgd_next		fixmap_pmd
>   #else
>   #define pgd_next_t		pte_t
> @@ -322,6 +323,7 @@ static void __init create_pmd_mapping(pmd_t *pmdp,
>   #define get_pgd_next_virt(__pa)	get_pte_virt(__pa)
>   #define create_pgd_next_mapping(__nextp, __va, __pa, __sz, __prot)	\
>   	create_pte_mapping(__nextp, __va, __pa, __sz, __prot)
> +#define clear_pgd_next_mapping(__nextp)	clear_pte(__nextp)
>   #define fixmap_pgd_next		fixmap_pte
>   #endif
>   
> @@ -361,6 +363,58 @@ static uintptr_t __init best_map_size(phys_addr_t base, phys_addr_t size)
>   	return PMD_SIZE;
>   }
>   
> +#ifdef CONFIG_RANDOMIZE_BASE
> +static void __init clear_pte(pte_t *ptep)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < PTRS_PER_PTE; i++)
> +		if (!pte_none(ptep[i]))
> +			ptep[i] = __pte(0);
> +}
> +
> +static void __init clear_pmd(pmd_t *pmdp)
> +{
> +	unsigned int i;
> +	pte_t *ptep;
> +	phys_addr_t pte_phys;
> +	uintptr_t kaslr_offset = get_kaslr_offset();
> +
> +	for (i = 0; i < PTRS_PER_PMD; i++)
> +		if (!pmd_none(pmdp[i])) {
> +			if (pmd_leaf(pmdp[i])) {
> +				pmd_clear(&pmdp[i]);
> +			} else {
> +				pte_phys = PFN_PHYS(_pmd_pfn(pmdp[i]));
> +				ptep = get_pte_virt(pte_phys + kaslr_offset);
> +				clear_pte(ptep);
> +				pmd_clear(&pmdp[i]);
> +			}
> +		}
> +}
> +
> +static void __init clear_pgd(pgd_t *pgdp)
> +{
> +	unsigned int i;
> +	pgd_next_t *nextp;
> +	phys_addr_t next_phys;
> +	uintptr_t kaslr_offset = get_kaslr_offset();
> +
> +	for (i = 0; i < PTRS_PER_PGD; i++)
> +		if (pgd_val(pgdp[i]) != 0) {
> +			if (pgd_leaf(pgd_val(pgdp[i]))) {
> +				set_pgd(&pgdp[i], __pgd(0));
> +			} else {
> +				next_phys = PFN_PHYS(_pgd_pfn(pgdp[i]));
> +				nextp = get_pgd_next_virt(next_phys +
> +							  kaslr_offset);
> +				clear_pgd_next_mapping(nextp);
> +				set_pgd(&pgdp[i], __pgd(0));
> +			}
> +		}
> +}
> +#endif
> +
>   /*
>    * setup_vm() is called from head.S with MMU-off.
>    *
> 

If this is only for clearing early page tables, a memset is way easier 
as there is only one page per level to clear.

Alex

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ