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]
Message-ID: <CANXhq0oduoX-gdG17FCwqpS5GAvY9w13B8a7YP0t2vNAHvKB_g@mail.gmail.com>
Date:   Tue, 7 Apr 2020 17:17:22 +0800
From:   Zong Li <zong.li@...ive.com>
To:     Alex Ghiti <alex@...ti.fr>
Cc:     Palmer Dabbelt <palmer@...belt.com>,
        Paul Walmsley <paul.walmsley@...ive.com>,
        linux-riscv <linux-riscv@...ts.infradead.org>,
        "linux-kernel@...r.kernel.org List" <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH RFC 2/8] riscv/kaslr: introduce functions to clear page table

On Tue, Apr 7, 2020 at 1:09 PM Alex Ghiti <alex@...ti.fr> wrote:
>
> 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.
>

Yes, it's a better way. Thanks.

> Alex

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ