linux-security-module.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Nadav Amit <namit@vmware.com>
Cc: Ingo Molnar <mingo@redhat.com>,
	linux-kernel@vger.kernel.org, x86@kernel.org,
	"H. Peter Anvin" <hpa@zytor.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Borislav Petkov <bp@alien8.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	linux_dti@icloud.com, linux-integrity@vger.kernel.org,
	linux-security-module@vger.kernel.org
Subject: Re: [PATCH v5 00/10] x86/alternative: text_poke() fixes
Date: Tue, 20 Nov 2018 13:42:32 +0100	[thread overview]
Message-ID: <20181120124232.GK2131@hirez.programming.kicks-ass.net> (raw)
In-Reply-To: <20181113130730.44844-1-namit@vmware.com>

On Tue, Nov 13, 2018 at 05:07:20AM -0800, Nadav Amit wrote:
> v4->v5:
> - Fix Xen breakage [Damian Tometzki]
> - BUG_ON() when poking_mm initialization fails [PeterZ]
> - Better comments on "x86/mm: temporary mm struct"
> - Cleaner removal of the custom poker

I'll re-iterate my position: it is impossible for the text not to match,
and if it somehow does not match, something went sideways in an
unrecoverably fashion.

text_poke() must not fail, ever. If it does, our text is inconsistent
and we must abort/panic/bug.

The only way I will accept anything else is if someone can come up with
a sensible scenario of text_poke() failing and recovering from it.
AFAICT there is no possible way to gracefully recover.

Consider a jump label with multiple patch sites; we patch the first,
then fail. In order to restore to a sane state, we must undo the
patching of the first, but undoing text_poke() fails again. Then
what?

Allowing text_poke() to fail only creates an unfixable mess. Esp. since
there is no sane scenario under which is can fail.

---


--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -695,7 +695,7 @@ void __init_or_module text_poke_early(vo
 __ro_after_init struct mm_struct *poking_mm;
 __ro_after_init unsigned long poking_addr;
 
-static int __text_poke(void *addr, const void *opcode, size_t len)
+static void __text_poke(void *addr, const void *opcode, size_t len)
 {
 	bool cross_page_boundary = offset_in_page(addr) + len > PAGE_SIZE;
 	temporary_mm_state_t prev;
@@ -731,13 +731,10 @@ static int __text_poke(void *addr, const
 	 * The lock is not really needed, but this allows to avoid open-coding.
 	 */
 	ptep = get_locked_pte(poking_mm, poking_addr, &ptl);
-
 	/*
-	 * If we failed to allocate a PTE, fail. This should *never* happen,
-	 * since we preallocate the PTE.
+	 * This must not fail; preallocated in poking_init().
 	 */
-	if (WARN_ON_ONCE(!ptep))
-		goto out;
+	VM_BUG_ON(!ptep)
 
 	pte = mk_pte(pages[0], PAGE_KERNEL);
 	set_pte_at(poking_mm, poking_addr, ptep, pte);
@@ -795,12 +792,14 @@ static int __text_poke(void *addr, const
 	unuse_temporary_mm(prev);
 
 	pte_unmap_unlock(ptep, ptl);
-out:
-	if (memcmp(addr, opcode, len))
-		r = -EFAULT;
+
+	/*
+	 * If the text doesn't match what we just wrote; something is
+	 * fundamentally screwy, there's nothing we can really do about that.
+	 */
+	BUG_ON(memcmp(addr, opcode, len));
 
 	local_irq_restore(flags);
-	return r;
 }
 
 /**
@@ -814,21 +813,10 @@ static int __text_poke(void *addr, const
  * in a way that permits an atomic write. It also makes sure we fit on a single
  * page.
  */
-int text_poke(void *addr, const void *opcode, size_t len)
+void text_poke(void *addr, const void *opcode, size_t len)
 {
-	int r;
-
 	lockdep_assert_held(&text_mutex);
-
-	r = __text_poke(addr, opcode, len);
-
-	/*
-	 * TODO: change the callers to consider the return value and remove this
-	 *       historical assertion.
-	 */
-	BUG_ON(r);
-
-	return r;
+	__text_poke(addr, opcode, len);
 }
 
 /**
@@ -847,7 +835,7 @@ int text_poke(void *addr, const void *op
  */
 int text_poke_kgdb(void *addr, const void *opcode, size_t len)
 {
-	return __text_poke(addr, opcode, len);
+	__text_poke(addr, opcode, len);
 }
 
 static void do_sync_core(void *info)
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -767,10 +767,8 @@ int kgdb_arch_set_breakpoint(struct kgdb
 	 */
 	if (mutex_is_locked(&text_mutex))
 		return -EBUSY;
-	err = text_poke_kgdb((void *)bpt->bpt_addr, arch_kgdb_ops.gdb_bpt_instr,
+	text_poke_kgdb((void *)bpt->bpt_addr, arch_kgdb_ops.gdb_bpt_instr,
 			     BREAK_INSTR_SIZE);
-	if (err)
-		return err;
 	bpt->type = BP_POKE_BREAKPOINT;
 
 	return err;
@@ -788,11 +786,8 @@ int kgdb_arch_remove_breakpoint(struct k
 	 */
 	if (mutex_is_locked(&text_mutex))
 		goto knl_write;
-	err = text_poke_kgdb((void *)bpt->bpt_addr, bpt->saved_instr,
-			     BREAK_INSTR_SIZE);
-	if (err)
-		goto knl_write;
-	return err;
+	text_poke_kgdb((void *)bpt->bpt_addr, bpt->saved_instr, BREAK_INSTR_SIZE);
+	return 0;
 
 knl_write:
 	return probe_kernel_write((char *)bpt->bpt_addr,

  parent reply	other threads:[~2018-11-20 12:43 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-13 13:07 [PATCH v5 00/10] x86/alternative: text_poke() fixes Nadav Amit
2018-11-13 13:07 ` [PATCH v5 01/10] Fix "x86/alternatives: Lockdep-enforce text_mutex in text_poke*()" Nadav Amit
2018-11-13 13:07 ` [PATCH v5 02/10] x86/jump_label: Use text_poke_early() during early init Nadav Amit
2018-11-20 18:10   ` H. Peter Anvin
2018-11-20 18:18     ` Peter Zijlstra
2018-11-20 18:23       ` H. Peter Anvin
2018-11-20 18:47         ` Nadav Amit
2018-11-13 13:07 ` [PATCH v5 03/10] x86/mm: temporary mm struct Nadav Amit
2018-11-13 13:07 ` [PATCH v5 04/10] fork: provide a function for copying init_mm Nadav Amit
2018-11-13 13:07 ` [PATCH v5 05/10] x86/alternative: initializing temporary mm for patching Nadav Amit
2018-11-13 13:07 ` [PATCH v5 06/10] x86/alternative: use temporary mm for text poking Nadav Amit
2018-11-13 13:07 ` [PATCH v5 07/10] x86/kgdb: avoid redundant comparison of patched code Nadav Amit
2018-11-13 13:07 ` [PATCH v5 08/10] x86: avoid W^X being broken during modules loading Nadav Amit
2018-11-13 13:07 ` [PATCH v5 09/10] x86/jump-label: remove support for custom poker Nadav Amit
2018-11-13 13:07 ` [PATCH v5 10/10] x86/alternative: remove the return value of text_poke_*() Nadav Amit
2018-11-20 12:42 ` Peter Zijlstra [this message]
2018-11-20 18:52   ` [PATCH v5 00/10] x86/alternative: text_poke() fixes Nadav Amit

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=20181120124232.GK2131@hirez.programming.kicks-ass.net \
    --to=peterz@infradead.org \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=hpa@zytor.com \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=linux_dti@icloud.com \
    --cc=mingo@redhat.com \
    --cc=namit@vmware.com \
    --cc=tglx@linutronix.de \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).