From: Kees Cook <keescook@chromium.org>
To: Bill Wendling <morbo@google.com>
Cc: Juergen Gross <jgross@suse.com>,
"Srivatsa S. Bhat (VMware)" <srivatsa@csail.mit.edu>,
Alexey Makhalov <amakhalov@vmware.com>,
VMware PV-Drivers Reviewers <pv-drivers@vmware.com>,
Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>,
virtualization@lists.linux-foundation.org,
linux-kernel@vger.kernel.org,
Nathan Chancellor <nathan@kernel.org>,
Nick Desaulniers <ndesaulniers@google.com>,
llvm@lists.linux.dev, linux-hardening@vger.kernel.org
Subject: Re: [PATCH 2/2] x86/paravirt: add extra clobbers with ZERO_CALL_USED_REGS enabled
Date: Sat, 3 Sep 2022 00:18:46 -0700 [thread overview]
Message-ID: <202209022251.B14BD50B29@keescook> (raw)
In-Reply-To: <20220902213750.1124421-3-morbo@google.com>
On Fri, Sep 02, 2022 at 09:37:50PM +0000, Bill Wendling wrote:
> [...]
> callq *pv_ops+536(%rip)
Do you know which pv_ops function is this? I can't figure out where
pte_offset_kernel() gets converted into a pv_ops call....
> [...]
> --- a/arch/x86/include/asm/paravirt_types.h
> +++ b/arch/x86/include/asm/paravirt_types.h
> @@ -414,8 +414,17 @@ int paravirt_disable_iospace(void);
> "=c" (__ecx)
> #define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS, "=a" (__eax)
>
> -/* void functions are still allowed [re]ax for scratch */
> +/*
> + * void functions are still allowed [re]ax for scratch.
> + *
> + * The ZERO_CALL_USED REGS feature may end up zeroing out callee-saved
> + * registers. Make sure we model this with the appropriate clobbers.
> + */
> +#ifdef CONFIG_ZERO_CALL_USED_REGS
> +#define PVOP_VCALLEE_CLOBBERS "=a" (__eax), PVOP_VCALL_CLOBBERS
> +#else
> #define PVOP_VCALLEE_CLOBBERS "=a" (__eax)
> +#endif
> #define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS
I don't think this should depend on CONFIG_ZERO_CALL_USED_REGS; it should
always be present.
I've only been looking at this just now, so many I'm missing
something. The callee clobbers are for functions with return values,
yes?
For example, 32-bit has to manually deal with doing a 64-bit value return,
and even got it wrong originally, fixing it in commit 0eb592dbba40
("x86/paravirt: return full 64-bit result"), with:
-#define PVOP_VCALLEE_CLOBBERS "=a" (__eax)
+#define PVOP_VCALLEE_CLOBBERS "=a" (__eax), "=d" (__edx)
But the naming is confusing, since these aren't actually clobbers,
they're input constraints marked as clobbers (the "=" modifier).
Regardless, the note in the comments ...
...
* However, x86_64 also have to clobber all caller saved registers, which
* unfortunately, are quite a bit (r8 - r11)
...
... would indicate that ALL the function argument registers need to be
marked as clobbers (i.e. the compiler can't figure this out on its own).
I was going to say it seems like they're missing from EXTRA_CLOBBERS,
but it's not used with any of the macros using PVOP_VCALLEE_CLOBBERS,
and then I saw the weird alternatives patching that encodes the clobbers
a second time (CLBR_ANY vs CLBR_RET_REG) via:
#define _paravirt_alt(insn_string, type, clobber) \
"771:\n\t" insn_string "\n" "772:\n" \
".pushsection .parainstructions,\"a\"\n" \
_ASM_ALIGN "\n" \
_ASM_PTR " 771b\n" \
" .byte " type "\n" \
" .byte 772b-771b\n" \
" .short " clobber "\n" \
".popsection\n"
And after reading the alternatives patching code which parses this via
the following struct:
/* These all sit in the .parainstructions section to tell us what to patch. */
struct paravirt_patch_site {
u8 *instr; /* original instructions */
u8 type; /* type of this instruction */
u8 len; /* length of original instruction */
};
... I see it _doesn't use the clobbers_ at all! *head explode* I found
that removal in commit 27876f3882fd ("x86/paravirt: Remove clobbers from
struct paravirt_patch_site")
So, I guess the CLBR_* can all be entirely removed. But back to my other
train of thought...
It seems like all the input registers need to be explicitly listed in
the PVOP_VCALLEE_CLOBBERS list (as you have), but likely should be done
unconditionally and for 32-bit as well.
-Kees
(Also, please CC linux-hardening@vger.kernel.org.)
--
Kees Cook
WARNING: multiple messages have this Message-ID (diff)
From: Kees Cook <keescook@chromium.org>
To: Bill Wendling <morbo@google.com>
Cc: Juergen Gross <jgross@suse.com>,
x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>,
VMware PV-Drivers Reviewers <pv-drivers@vmware.com>,
Dave Hansen <dave.hansen@linux.intel.com>,
Nick Desaulniers <ndesaulniers@google.com>,
linux-kernel@vger.kernel.org,
virtualization@lists.linux-foundation.org,
Nathan Chancellor <nathan@kernel.org>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
linux-hardening@vger.kernel.org, llvm@lists.linux.dev,
Alexey Makhalov <amakhalov@vmware.com>,
Thomas Gleixner <tglx@linutronix.de>
Subject: Re: [PATCH 2/2] x86/paravirt: add extra clobbers with ZERO_CALL_USED_REGS enabled
Date: Sat, 3 Sep 2022 00:18:46 -0700 [thread overview]
Message-ID: <202209022251.B14BD50B29@keescook> (raw)
In-Reply-To: <20220902213750.1124421-3-morbo@google.com>
On Fri, Sep 02, 2022 at 09:37:50PM +0000, Bill Wendling wrote:
> [...]
> callq *pv_ops+536(%rip)
Do you know which pv_ops function is this? I can't figure out where
pte_offset_kernel() gets converted into a pv_ops call....
> [...]
> --- a/arch/x86/include/asm/paravirt_types.h
> +++ b/arch/x86/include/asm/paravirt_types.h
> @@ -414,8 +414,17 @@ int paravirt_disable_iospace(void);
> "=c" (__ecx)
> #define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS, "=a" (__eax)
>
> -/* void functions are still allowed [re]ax for scratch */
> +/*
> + * void functions are still allowed [re]ax for scratch.
> + *
> + * The ZERO_CALL_USED REGS feature may end up zeroing out callee-saved
> + * registers. Make sure we model this with the appropriate clobbers.
> + */
> +#ifdef CONFIG_ZERO_CALL_USED_REGS
> +#define PVOP_VCALLEE_CLOBBERS "=a" (__eax), PVOP_VCALL_CLOBBERS
> +#else
> #define PVOP_VCALLEE_CLOBBERS "=a" (__eax)
> +#endif
> #define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS
I don't think this should depend on CONFIG_ZERO_CALL_USED_REGS; it should
always be present.
I've only been looking at this just now, so many I'm missing
something. The callee clobbers are for functions with return values,
yes?
For example, 32-bit has to manually deal with doing a 64-bit value return,
and even got it wrong originally, fixing it in commit 0eb592dbba40
("x86/paravirt: return full 64-bit result"), with:
-#define PVOP_VCALLEE_CLOBBERS "=a" (__eax)
+#define PVOP_VCALLEE_CLOBBERS "=a" (__eax), "=d" (__edx)
But the naming is confusing, since these aren't actually clobbers,
they're input constraints marked as clobbers (the "=" modifier).
Regardless, the note in the comments ...
...
* However, x86_64 also have to clobber all caller saved registers, which
* unfortunately, are quite a bit (r8 - r11)
...
... would indicate that ALL the function argument registers need to be
marked as clobbers (i.e. the compiler can't figure this out on its own).
I was going to say it seems like they're missing from EXTRA_CLOBBERS,
but it's not used with any of the macros using PVOP_VCALLEE_CLOBBERS,
and then I saw the weird alternatives patching that encodes the clobbers
a second time (CLBR_ANY vs CLBR_RET_REG) via:
#define _paravirt_alt(insn_string, type, clobber) \
"771:\n\t" insn_string "\n" "772:\n" \
".pushsection .parainstructions,\"a\"\n" \
_ASM_ALIGN "\n" \
_ASM_PTR " 771b\n" \
" .byte " type "\n" \
" .byte 772b-771b\n" \
" .short " clobber "\n" \
".popsection\n"
And after reading the alternatives patching code which parses this via
the following struct:
/* These all sit in the .parainstructions section to tell us what to patch. */
struct paravirt_patch_site {
u8 *instr; /* original instructions */
u8 type; /* type of this instruction */
u8 len; /* length of original instruction */
};
... I see it _doesn't use the clobbers_ at all! *head explode* I found
that removal in commit 27876f3882fd ("x86/paravirt: Remove clobbers from
struct paravirt_patch_site")
So, I guess the CLBR_* can all be entirely removed. But back to my other
train of thought...
It seems like all the input registers need to be explicitly listed in
the PVOP_VCALLEE_CLOBBERS list (as you have), but likely should be done
unconditionally and for 32-bit as well.
-Kees
(Also, please CC linux-hardening@vger.kernel.org.)
--
Kees Cook
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
next prev parent reply other threads:[~2022-09-03 7:18 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-02 21:37 [PATCH 0/2] fix clobbers list with ZERO_CALL_USED_REGS feature Bill Wendling
2022-09-02 21:37 ` [PATCH 1/2] x86/paravirt: clean up typos and grammaros Bill Wendling
2022-09-03 4:28 ` Borislav Petkov
2022-09-03 4:28 ` Borislav Petkov
2022-09-04 2:13 ` Bill Wendling
2022-09-02 21:37 ` [PATCH 2/2] x86/paravirt: add extra clobbers with ZERO_CALL_USED_REGS enabled Bill Wendling
2022-09-03 7:18 ` Kees Cook [this message]
2022-09-03 7:18 ` Kees Cook
2022-09-05 6:02 ` Bill Wendling
2022-09-07 6:00 ` Nick Desaulniers
2022-09-07 6:00 ` Nick Desaulniers via Virtualization
2022-09-07 8:50 ` Peter Zijlstra
2022-09-07 8:50 ` Peter Zijlstra
2022-09-07 23:10 ` Kees Cook
2022-09-07 23:10 ` Kees Cook
2022-09-08 21:16 ` Bill Wendling
2022-09-14 14:40 ` Nathan Chancellor
2022-09-14 15:49 ` Bill Wendling
[not found] ` <20220914162149.71271-1-morbo@google.com>
2022-09-15 6:59 ` [PATCH v2 1/1] x86/paravirt: write paravirt ident function in assembly Juergen Gross
2022-09-15 6:59 ` Juergen Gross via Virtualization
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=202209022251.B14BD50B29@keescook \
--to=keescook@chromium.org \
--cc=amakhalov@vmware.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=jgross@suse.com \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=llvm@lists.linux.dev \
--cc=mingo@redhat.com \
--cc=morbo@google.com \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.com \
--cc=pv-drivers@vmware.com \
--cc=srivatsa@csail.mit.edu \
--cc=tglx@linutronix.de \
--cc=virtualization@lists.linux-foundation.org \
--cc=x86@kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.