From: Juergen Gross <jgross@suse.com>
To: Jan Beulich <JBeulich@suse.com>,
mingo@elte.hu, Thomas Gleixner <tglx@linutronix.de>,
hpa@zytor.com
Cc: xen-devel <xen-devel@lists.xenproject.org>,
Boris Ostrovsky <boris.ostrovsky@oracle.com>,
sds@tycho.nsa.gov, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/2] x86: consider effective protection attributes in W+X check
Date: Thu, 14 Dec 2017 15:04:09 +0100 [thread overview]
Message-ID: <fcb65c2e-d0eb-24c2-ad2b-e956291db01a@suse.com> (raw)
In-Reply-To: <5A2FBE0A0200007800196B4F@suse.com>
On 12/12/17 11:31, Jan Beulich wrote:
> Using just the leaf page table entry flags would cause a false warning
> in case _PAGE_RW is clear or _PAGE_NX is set in a higher level entry.
> Hand through both the current entry's flags as well as the accumulated
> effective value (the latter as pgprotval_t instead of pgprot_t, as it's
> not an actual entry's value).
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
> ---
> arch/x86/mm/dump_pagetables.c | 92 ++++++++++++++++++++++++++----------------
> 1 file changed, 57 insertions(+), 35 deletions(-)
>
> --- 4.15-rc3/arch/x86/mm/dump_pagetables.c
> +++ 4.15-rc3-x86-dumppgt-effective-prot/arch/x86/mm/dump_pagetables.c
> @@ -29,6 +29,7 @@
> struct pg_state {
> int level;
> pgprot_t current_prot;
> + pgprotval_t effective_prot;
> unsigned long start_address;
> unsigned long current_address;
> const struct addr_marker *marker;
> @@ -202,9 +203,9 @@ static unsigned long normalize_addr(unsi
> * print what we collected so far.
> */
> static void note_page(struct seq_file *m, struct pg_state *st,
> - pgprot_t new_prot, int level)
> + pgprot_t new_prot, pgprotval_t new_eff, int level)
> {
> - pgprotval_t prot, cur;
> + pgprotval_t prot, cur, eff;
> static const char units[] = "BKMGTPE";
>
> /*
> @@ -214,23 +215,24 @@ static void note_page(struct seq_file *m
> */
> prot = pgprot_val(new_prot);
> cur = pgprot_val(st->current_prot);
> + eff = st->effective_prot;
>
> if (!st->level) {
> /* First entry */
> st->current_prot = new_prot;
> + st->effective_prot = new_eff;
> st->level = level;
> st->marker = address_markers;
> st->lines = 0;
> pt_dump_seq_printf(m, st->to_dmesg, "---[ %s ]---\n",
> st->marker->name);
> - } else if (prot != cur || level != st->level ||
> + } else if (prot != cur || new_eff != eff || level != st->level ||
> st->current_address >= st->marker[1].start_address) {
> const char *unit = units;
> unsigned long delta;
> int width = sizeof(unsigned long) * 2;
> - pgprotval_t pr = pgprot_val(st->current_prot);
>
> - if (st->check_wx && (pr & _PAGE_RW) && !(pr & _PAGE_NX)) {
> + if (st->check_wx && (eff & _PAGE_RW) && !(eff & _PAGE_NX)) {
> WARN_ONCE(1,
> "x86/mm: Found insecure W+X mapping at address %p/%pS\n",
> (void *)st->start_address,
> @@ -284,21 +286,30 @@ static void note_page(struct seq_file *m
>
> st->start_address = st->current_address;
> st->current_prot = new_prot;
> + st->effective_prot = new_eff;
> st->level = level;
> }
> }
>
> -static void walk_pte_level(struct seq_file *m, struct pg_state *st, pmd_t addr, unsigned long P)
> +static inline pgprotval_t effective_prot(pgprotval_t prot1, pgprotval_t prot2)
> +{
> + return (prot1 & prot2 & (_PAGE_USER | _PAGE_RW)) |
> + ((prot1 | prot2) & _PAGE_NX);
> +}
> +
> +static void walk_pte_level(struct seq_file *m, struct pg_state *st, pmd_t addr,
> + pgprotval_t eff_in, unsigned long P)
> {
> int i;
> pte_t *start;
> - pgprotval_t prot;
> + pgprotval_t prot, eff;
>
> start = (pte_t *)pmd_page_vaddr(addr);
> for (i = 0; i < PTRS_PER_PTE; i++) {
> prot = pte_flags(*start);
> + eff = effective_prot(eff_in, prot);
> st->current_address = normalize_addr(P + i * PTE_LEVEL_MULT);
> - note_page(m, st, __pgprot(prot), 5);
> + note_page(m, st, __pgprot(prot), eff, 5);
> start++;
> }
> }
> @@ -335,42 +346,45 @@ static inline bool kasan_page_table(stru
>
> #if PTRS_PER_PMD > 1
>
> -static void walk_pmd_level(struct seq_file *m, struct pg_state *st, pud_t addr, unsigned long P)
> +static void walk_pmd_level(struct seq_file *m, struct pg_state *st, pud_t addr,
> + pgprotval_t eff_in, unsigned long P)
> {
> int i;
> pmd_t *start, *pmd_start;
> - pgprotval_t prot;
> + pgprotval_t prot, eff;
>
> pmd_start = start = (pmd_t *)pud_page_vaddr(addr);
> for (i = 0; i < PTRS_PER_PMD; i++) {
> st->current_address = normalize_addr(P + i * PMD_LEVEL_MULT);
> if (!pmd_none(*start)) {
> + prot = pmd_flags(*start);
> + eff = effective_prot(eff_in, prot);
> if (pmd_large(*start) || !pmd_present(*start)) {
> - prot = pmd_flags(*start);
> - note_page(m, st, __pgprot(prot), 4);
> + note_page(m, st, __pgprot(prot), eff, 4);
> } else if (!kasan_page_table(m, st, pmd_start)) {
> - walk_pte_level(m, st, *start,
> + walk_pte_level(m, st, *start, eff,
> P + i * PMD_LEVEL_MULT);
> }
You can drop the braces for both cases. Applies to similar
constructs below, too.
With that fixed you can add my:
Reviewed-by: Juergen Gross <jgross@suse.com>
Juergen
next prev parent reply other threads:[~2017-12-14 14:04 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-12 10:24 [PATCH 0/2] x86: deal with remaining W+X pages on Xen Jan Beulich
2017-12-12 10:31 ` [PATCH 1/2] x86: consider effective protection attributes in W+X check Jan Beulich
2017-12-12 10:36 ` Ingo Molnar
2017-12-12 10:43 ` Jan Beulich
2017-12-12 10:32 ` [PATCH 2/2] x86-64/Xen: eliminate W+X mappings Jan Beulich
2017-12-12 10:38 ` Ingo Molnar
2017-12-12 10:48 ` Jan Beulich
2017-12-12 10:54 ` Ingo Molnar
[not found] ` <5A2FC2280200007800196BB8@suse.com>
2017-12-12 13:14 ` Juergen Gross
2017-12-18 11:11 ` [PATCH v2] " Jan Beulich
2017-12-18 12:28 ` Ingo Molnar
2017-12-18 15:52 ` Joe Perches
2017-12-18 16:37 ` [PATCH v3] " Jan Beulich
[not found] ` <5A2FBE0A0200007800196B4F@suse.com>
2017-12-14 14:04 ` Juergen Gross [this message]
2017-12-14 14:12 ` [PATCH 1/2] x86: consider effective protection attributes in W+X check Thomas Gleixner
2017-12-14 14:15 ` Jan Beulich
2017-12-14 14:17 ` Thomas Gleixner
2017-12-14 14:21 ` Juergen Gross
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=fcb65c2e-d0eb-24c2-ad2b-e956291db01a@suse.com \
--to=jgross@suse.com \
--cc=JBeulich@suse.com \
--cc=boris.ostrovsky@oracle.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=sds@tycho.nsa.gov \
--cc=tglx@linutronix.de \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox