All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
To: Borislav Petkov <bp@suse.de>
Cc: Ingo Molnar <mingo@redhat.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	"H. Peter Anvin" <hpa@zytor.com>,
	Andy Lutomirski <luto@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Brian Gerst <brgerst@gmail.com>,
	Chris Metcalf <cmetcalf@mellanox.com>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	Huang Rui <ray.huang@amd.com>, Jiri Slaby <jslaby@suse.cz>,
	Jonathan Corbet <corbet@lwn.net>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	Paul Gortmaker <paul.gortmaker@windriver.com>,
	Vlastimil Babka <vbabka@suse.cz>, Chen Yucong <slaoub@gmail.com>,
	"Ravi V. Shankar" <ravi.v.shankar@intel.com>,
	Shuah Khan <shuah@kernel.org>,
	linux-kernel@vger.kernel.org, x86@kernel.org,
	Adam Buchbinder <adam.buchbinder@gmail.com>,
	Colin Ian King <colin.king@canonical.com>,
	Lorenzo Stoakes <lstoakes@gmail.com>,
	Qiaowei Ren <qiaowei.ren@intel.com>,
	Arnaldo Carvalho de Melo <acme@redhat.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	Kees Cook <keescook@chromium.org>,
	Thomas Garnier <thgarnie@google.com>,
	Dmitry Vyukov <dvyukov@google.com>
Subject: Re: [PATCH v9 13/29] x86/insn-eval: Add utility functions to get segment selector
Date: Fri, 13 Oct 2017 11:43:43 -0700	[thread overview]
Message-ID: <1507920223.17492.85.camel@linux.intel.com> (raw)
In-Reply-To: <20171013113738.757ucfevds53eg6g@pd.tnic>

On Fri, 2017-10-13 at 13:37 +0200, Borislav Petkov wrote:
> On Thu, Oct 12, 2017 at 06:08:17PM -0700, Ricardo Neri wrote:
> > 
> > In my opinion it would be better to have all the checks in a single place.
> > This
> > makes the code easier to read that having this special case directly
> > in resolve_default_seg().
> > ...
> > Rather than checking for null insn in resolve_seg_reg(), which does not use
> > it,
> > let the functions it calls do the check if they need to.
> Of course it is using it - it is passing it down to callers.
> 
> No, this is completely backwards. You're pushing the if (!insn) check
> down instead of up. What you wanna do instead is get that "strange" case
> out of the way *first* where insn is NULL and then have the remaining
> flow with a properly allocated struct insn.

Furthermore, resolve_seg_reg() there should not be need to call
resolve_seg_reg(). It is meant to be used when decoding instructions. Callers
already know they must use CS for rIP. resolve_seg_reg() is to be used when the
segment register is not know beforehand.

Then it sounds that your second proposal address it:

1) It first handles the strange case
2) It checks if insn is valid
3) Checks if segment overrides prefixes can be used
   3.a) If yes, use them, if any.
   3.b) If no, resolve default segment register index.

resolve_default_seg() and get_seg_reg_override_idx() will assume that insn is
not null. Please find at the bottom a diff of your second proposal with minor
tweaks.

> 
> And the only case where insn is NULL is fixup_umip_exception(). All the
> other callers of insn_get_seg_base() supply a properly setup struct insn
> * AFAICT.

Yes, this is correct.
> 
> So do the minimum work of getting the segment base either directly in
> fixup_umip_exception() by calling a helper function as it matters only
> there.
> 
> And IINM, you have two possible cases:
> 
> 1. INAT_SEG_REG_IGNORE which makes segment base 0
> 
> 2. INAT_SEG_REG_DEFAULT which maps to INAT_SEG_REG_CS for the rIP case
> and then gets the selector:
> 
> 	sel = (unsigned short)(regs->cs & 0xffff);
> and then computes the base.

Yes, also correct; I modified your second proposal for cases 1 and 2.

> 
> And the mapping of sel to base you can do by carving out the piece of
> insn_get_seg_base() *after* you've computed @sel and you do the base
> computation, i.e., the piece which starts with this:
> 
>         if (v8086_mode(regs))
>                 /*
>                  * Base is simply the segment selector shifted 4
>                  * positions to the right.
> 	...
> 
> into a separate function called __get_seg_base(sel, ...).
> 
> The important thing to note here is that this function won't need insn
> so you can call it without one.

In v9 insn_get_seg_base() does not take an insn as argument (it used to take one
until v8). Also, fixup_umip_exception() calls insn_get_seg_base with
INAT_SEG_REG_CS, no need to resolve the segment register. It does it only for
!user_64bit_mode().

If a __get_seg_base(sel, ...) was implemented, then insn_get_seg_base() would
look like:

unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx)
{
	struct desc_struct *desc;
	short sel;

	sel = get_segment_selector(regs, seg_reg_idx);
	if (sel < 0)
		return -1L;
		}

	return __get_seg_base(sel, regs);
}

After having clarified that an insn is not needed in the latest iteration of
insn_get_seg_base(), I just want to double check if this is what you would like
to see.

> 
> This way you have it nice and clean designed with a clear separation of
> the cases *before* a valid struct insn * and *after*.
> 
> Right now, you have both intermixed and the code is hard to follow as
> you have to pay attention at each time: how and where am I being called.
> 
> Makes sense?

I think it does now. This is a modification of your second proposal (I hope text
does not wrap):

@@ -71,9 +71,6 @@ static int get_seg_reg_override_idx(struct insn *insn)
 	int idx = INAT_SEG_REG_DEFAULT;
 	int num_overrides = 0, i;
 
-	if (!insn)
-		return -EINVAL;
-
 	insn_get_prefixes(insn);
 
 	/* Look for any segment override prefixes. */
@@ -128,28 +125,16 @@ static int get_seg_reg_override_idx(struct insn *insn)
  *
  * Returns:
  *
- * 1 if segment override prefixes can be used with the register indicated
- * in @regoff. 0 if otherwise.
+ * True if segment override prefixes can be used with the register indicated
+ * in @regoff. False if otherwise.
  *
- * -EINVAL in case of error.
  */
-static int check_seg_overrides(struct insn *insn, int regoff)
+static bool check_seg_overrides(struct insn *insn, int regoff)
 {
-	/*
-	 * Segment override prefixes should not be used for rIP. It is not
-	 * necessary to inspect the instruction structure.
-	 */
-	if (regoff == offsetof(struct pt_regs, ip))
-		return 0;
-
-	/* Subsequent checks require a valid insn. */
-	if (!insn)
-		return -EINVAL;
-
 	if (regoff == offsetof(struct pt_regs, di) && is_string_insn(insn))
-		return 0;
+		return false;
 
-	return 1;
+	return true;
 }
 
 /**
@@ -249,18 +234,26 @@ static int resolve_default_seg(struct insn *insn, struct
pt_regs *regs, int off)
  */
 static int resolve_seg_reg(struct insn *insn, struct pt_regs *regs, int regoff)
 {
-	int ret, idx;
-
-	ret = check_seg_overrides(insn, regoff);
-	if (ret < 0)
-		return ret;
+	int idx;
 
-	if (!ret)
-		return resolve_default_seg(insn, regs, regoff);
+	/*
+	 * In the unlikely event of having to resolve the segment register
+	 * index for rIP, do it first. Segment override prefixes should not
+	 * be used. Hence, it is not necessary to inspect the instruction.
+	 */
+	if (regoff == offsetof(struct pt_regs, ip)) {
+		if (user_64bit_mode(regs))
+			return INAT_SEG_REG_IGNORE;
+		else
+			return INAT_SEG_REG_CS;
+	}
 
 	if (!insn)
 		return -EINVAL;
 
+	if (!check_seg_overrides(insn, regoff))
+		return resolve_default_seg(insn, regs, regoff);
+
 	idx = get_seg_reg_override_idx(insn);
 	if (idx < 0)
 		return idx;
Thanks and BR,
Ricardo

  reply	other threads:[~2017-10-13 18:44 UTC|newest]

Thread overview: 83+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-04  3:54 [PATCH v9 00/29] x86: Enable User-Mode Instruction Prevention Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 01/29] x86/mm: Relocate page fault error codes to traps.h Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 02/29] x86/boot: Relocate definition of the initial state of CR0 Ricardo Neri
2017-10-04  3:54   ` Ricardo Neri
2017-10-04  3:54   ` Ricardo Neri
2017-10-26  7:51   ` Andy Lutomirski
2017-10-26  7:51     ` Andy Lutomirski
2017-10-26  7:51     ` Andy Lutomirski
2017-10-26  9:00     ` Borislav Petkov
2017-10-26  9:00       ` Borislav Petkov
2017-10-26  9:00       ` Borislav Petkov
2017-10-26  9:02       ` Andy Lutomirski
2017-10-26  9:02         ` Andy Lutomirski
2017-10-26  9:02         ` Andy Lutomirski
2017-10-26 12:55         ` Borislav Petkov
2017-10-26 12:55           ` Borislav Petkov
2017-10-26 12:55           ` Borislav Petkov
2017-10-27 19:02           ` Ricardo Neri
2017-10-27 19:02             ` Ricardo Neri
2017-10-27 19:02             ` Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 03/29] ptrace,x86: Make user_64bit_mode() available to 32-bit builds Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 04/29] uprobes/x86: Use existing definitions for segment override prefixes Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 05/29] x86/mpx: Simplify handling of errors when computing linear addresses Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 06/29] x86/mpx: Use signed variables to compute effective addresses Ricardo Neri
2017-10-05  9:41   ` Borislav Petkov
2017-10-05 17:38     ` Neri, Ricardo
2017-10-04  3:54 ` [PATCH v9 07/29] x86/mpx: Do not use SIB.index if its value is 100b and ModRM.mod is not 11b Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 08/29] x86/mpx: Do not use SIB.base if its value is 101b and ModRM.mod = 0 Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 09/29] x86/mpx, x86/insn: Relocate insn util functions to a new insn-eval file Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 10/29] x86/insn-eval: Do not BUG on invalid register type Ricardo Neri
2017-10-07 16:22   ` Borislav Petkov
2017-10-09 23:56     ` Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 11/29] x86/insn-eval: Add a utility function to get register offsets Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 12/29] x86/insn-eval: Add utility function to identify string instructions Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 13/29] x86/insn-eval: Add utility functions to get segment selector Ricardo Neri
2017-10-10 22:41   ` Borislav Petkov
2017-10-12  1:12     ` Ricardo Neri
2017-10-12  9:48       ` Borislav Petkov
2017-10-13  1:08         ` Ricardo Neri
2017-10-13 11:37           ` Borislav Petkov
2017-10-13 18:43             ` Ricardo Neri [this message]
2017-10-17  9:35               ` Borislav Petkov
2017-10-17 20:31                 ` Ricardo Neri
2017-10-18 20:29                   ` Borislav Petkov
2017-10-19  6:30                     ` Ricardo Neri
2017-10-20  7:55                       ` Borislav Petkov
2017-10-20 18:05                         ` Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 14/29] x86/insn-eval: Add utility function to get segment descriptor Ricardo Neri
2017-10-11 14:57   ` Borislav Petkov
2017-10-12  0:45     ` Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 15/29] x86/insn-eval: Add utility functions to get segment descriptor base address and limit Ricardo Neri
2017-10-11 15:15   ` Borislav Petkov
2017-10-11 19:57     ` Ricardo Neri
2017-10-11 20:16       ` Borislav Petkov
2017-10-12  1:24         ` Ricardo Neri
2017-10-12 16:02           ` Borislav Petkov
2017-10-04  3:54 ` [PATCH v9 16/29] x86/insn-eval: Add function to get default params of code segment Ricardo Neri
2017-10-12 16:31   ` Borislav Petkov
2017-10-12 18:27     ` Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 17/29] x86/insn-eval: Indicate a 32-bit displacement if ModRM.mod is 0 and ModRM.rm is 101b Ricardo Neri
2017-10-20 15:44   ` Borislav Petkov
2017-10-20 18:07     ` Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 18/29] x86/insn-eval: Incorporate segment base in linear address computation Ricardo Neri
2017-10-20 16:08   ` Borislav Petkov
2017-10-20 18:10     ` Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 19/29] x86/insn-eval: Add support to resolve 32-bit address encodings Ricardo Neri
2017-10-20 17:12   ` Borislav Petkov
2017-10-20 18:24     ` Ricardo Neri
2017-10-20 18:38       ` Borislav Petkov
2017-10-20 19:16         ` Ricardo Neri
2017-10-20 22:04           ` Borislav Petkov
2017-10-04  3:54 ` [PATCH v9 20/29] x86/insn-eval: Add wrapper function for 32 and 64-bit addresses Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 21/29] x86/insn-eval: Handle 32-bit address encodings in virtual-8086 mode Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 22/29] x86/insn-eval: Add support to resolve 16-bit addressing encodings Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 23/29] x86/cpufeature: Add User-Mode Instruction Prevention definitions Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 24/29] x86: Add emulation code for UMIP instructions Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 25/29] x86/umip: Force a page fault when unable to copy emulated result to user Ricardo Neri
2017-10-26  7:59   ` Andy Lutomirski
2017-10-27 21:46     ` Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 26/29] x86: Enable User-Mode Instruction Prevention Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 27/29] x86/traps: Fixup general protection faults caused by UMIP Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 28/29] selftests/x86: Add tests for User-Mode Instruction Prevention Ricardo Neri
2017-10-04  3:54 ` [PATCH v9 29/29] selftests/x86: Add tests for instruction str and sldt Ricardo Neri

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=1507920223.17492.85.camel@linux.intel.com \
    --to=ricardo.neri-calderon@linux.intel.com \
    --cc=acme@redhat.com \
    --cc=adam.buchbinder@gmail.com \
    --cc=adrian.hunter@intel.com \
    --cc=akpm@linux-foundation.org \
    --cc=bp@suse.de \
    --cc=brgerst@gmail.com \
    --cc=cmetcalf@mellanox.com \
    --cc=colin.king@canonical.com \
    --cc=corbet@lwn.net \
    --cc=dave.hansen@linux.intel.com \
    --cc=dvyukov@google.com \
    --cc=hpa@zytor.com \
    --cc=jslaby@suse.cz \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lstoakes@gmail.com \
    --cc=luto@kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=mingo@redhat.com \
    --cc=mst@redhat.com \
    --cc=paul.gortmaker@windriver.com \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=qiaowei.ren@intel.com \
    --cc=ravi.v.shankar@intel.com \
    --cc=ray.huang@amd.com \
    --cc=shuah@kernel.org \
    --cc=slaoub@gmail.com \
    --cc=tglx@linutronix.de \
    --cc=thgarnie@google.com \
    --cc=vbabka@suse.cz \
    --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.