linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Rick Edgecombe <rick.p.edgecombe@intel.com>
To: akpm@linux-foundation.org, jeyu@kernel.org, bpf@vger.kernel.org,
	ast@kernel.org, daniel@iogearbox.net, luto@kernel.org,
	dave.hansen@linux.intel.com, peterz@infradead.org,
	x86@kernel.org, rppt@kernel.org, linux-mm@kvack.org,
	linux-kernel@vger.kernel.org, dan.j.williams@intel.com
Cc: elena.reshetova@intel.com, ira.weiny@intel.com,
	Rick Edgecombe <rick.p.edgecombe@intel.com>
Subject: [PATCH RFC 05/10] x86/modules: Use real perm_allocations
Date: Fri, 20 Nov 2020 12:24:21 -0800	[thread overview]
Message-ID: <20201120202426.18009-6-rick.p.edgecombe@intel.com> (raw)
In-Reply-To: <20201120202426.18009-1-rick.p.edgecombe@intel.com>

x86 relocations require all of the text sections to be within 2GB of
eachother. So as long as the allocations are somewhere in the module area,
relocations can be applied. So relax the restriction of having the module
regions for a module core or init area be virtually contiguous.

Also, apply relocations at the writable address of the perm_allocation to
support a future implementation that has the writable address in a
different allocation.

Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
---
 arch/x86/kernel/module.c | 84 +++++++++++++++++++++++++++++++++-------
 1 file changed, 71 insertions(+), 13 deletions(-)

diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index 34b153cbd4ac..7b369f5ffdb7 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -85,6 +85,58 @@ void *module_alloc(unsigned long size)
 	return p;
 }
 
+bool module_perm_alloc(struct module_layout *layout)
+{
+	unsigned long vstart = MODULES_VADDR + get_module_load_offset();
+	unsigned long vend = MODULES_END;
+	unsigned int text_page_cnt = PAGE_ALIGN(layout->text.size) >> PAGE_SHIFT;
+	unsigned int ro_page_cnt = PAGE_ALIGN(layout->ro.size) >> PAGE_SHIFT;
+	unsigned int ro_after_init_page_cnt = PAGE_ALIGN(layout->ro_after_init.size) >> PAGE_SHIFT;
+	unsigned int rw_page_cnt = PAGE_ALIGN(layout->rw.size) >> PAGE_SHIFT;
+
+	layout->text.alloc = NULL;
+	layout->ro.alloc = NULL;
+	layout->ro_after_init.alloc = NULL;
+	layout->rw.alloc = NULL;
+
+	layout->text.alloc = perm_alloc(vstart, vend, text_page_cnt, PERM_RX);
+	if (!layout->text.alloc && layout->text.size)
+		goto out;
+
+	layout->ro.alloc = perm_alloc(vstart, vend, ro_page_cnt, PERM_R);
+	if (!layout->ro.alloc && layout->ro.size)
+		goto text_free_out;
+
+	layout->ro_after_init.alloc = perm_alloc(vstart, vend, ro_after_init_page_cnt, PERM_RW);
+	if (!layout->ro_after_init.alloc && layout->ro_after_init.size)
+		goto ro_free_out;
+
+	layout->rw.alloc = perm_alloc(vstart, vend, rw_page_cnt, PERM_RW);
+	if (!layout->rw.alloc && layout->rw.size)
+		goto ro_after_init_out;
+
+	return true;
+ro_after_init_out:
+	perm_free(layout->ro_after_init.alloc);
+	layout->ro_after_init.alloc = NULL;
+ro_free_out:
+	perm_free(layout->ro.alloc);
+	layout->ro.alloc = NULL;
+text_free_out:
+	perm_free(layout->text.alloc);
+	layout->text.alloc = NULL;
+out:
+	return false;
+}
+
+void module_perm_free(struct module_layout *layout)
+{
+	perm_free(layout->text.alloc);
+	perm_free(layout->ro.alloc);
+	perm_free(layout->ro_after_init.alloc);
+	perm_free(layout->rw.alloc);
+}
+
 #ifdef CONFIG_X86_32
 int apply_relocate(Elf32_Shdr *sechdrs,
 		   const char *strtab,
@@ -134,9 +186,11 @@ static int __apply_relocate_add(Elf64_Shdr *sechdrs,
 		   void *(*write)(void *dest, const void *src, size_t len))
 {
 	unsigned int i;
+	struct perm_allocation *alloc;
 	Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
 	Elf64_Sym *sym;
 	void *loc;
+	void *writable_loc;
 	u64 val;
 
 	DEBUGP("Applying relocate section %u to %u\n",
@@ -146,6 +200,9 @@ static int __apply_relocate_add(Elf64_Shdr *sechdrs,
 		loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
 			+ rel[i].r_offset;
 
+		alloc = module_get_allocation(me, (unsigned long)loc);
+		writable_loc = (void *)perm_writable_addr(alloc, (unsigned long)loc);
+
 		/* This is the symbol it is referring to.  Note that all
 		   undefined symbols have been resolved.  */
 		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
@@ -161,40 +218,40 @@ static int __apply_relocate_add(Elf64_Shdr *sechdrs,
 		case R_X86_64_NONE:
 			break;
 		case R_X86_64_64:
-			if (*(u64 *)loc != 0)
+			if (*(u64 *)writable_loc != 0)
 				goto invalid_relocation;
-			write(loc, &val, 8);
+			write(writable_loc, &val, 8);
 			break;
 		case R_X86_64_32:
-			if (*(u32 *)loc != 0)
+			if (*(u32 *)writable_loc != 0)
 				goto invalid_relocation;
-			write(loc, &val, 4);
-			if (val != *(u32 *)loc)
+			write(writable_loc, &val, 4);
+			if (val != *(u32 *)writable_loc)
 				goto overflow;
 			break;
 		case R_X86_64_32S:
-			if (*(s32 *)loc != 0)
+			if (*(s32 *)writable_loc != 0)
 				goto invalid_relocation;
-			write(loc, &val, 4);
-			if ((s64)val != *(s32 *)loc)
+			write(writable_loc, &val, 4);
+			if ((s64)val != *(s32 *)writable_loc)
 				goto overflow;
 			break;
 		case R_X86_64_PC32:
 		case R_X86_64_PLT32:
-			if (*(u32 *)loc != 0)
+			if (*(u32 *)writable_loc != 0)
 				goto invalid_relocation;
 			val -= (u64)loc;
-			write(loc, &val, 4);
+			write(writable_loc, &val, 4);
 #if 0
-			if ((s64)val != *(s32 *)loc)
+			if ((s64)val != *(s32 *)writable_loc)
 				goto overflow;
 #endif
 			break;
 		case R_X86_64_PC64:
-			if (*(u64 *)loc != 0)
+			if (*(u64 *)writable_loc != 0)
 				goto invalid_relocation;
 			val -= (u64)loc;
-			write(loc, &val, 8);
+			write(writable_loc, &val, 8);
 			break;
 		default:
 			pr_err("%s: Unknown rela relocation: %llu\n",
@@ -273,6 +330,7 @@ int module_finalize(const Elf_Ehdr *hdr,
 		void *aseg = (void *)alt->sh_addr;
 		apply_alternatives(aseg, aseg + alt->sh_size);
 	}
+
 	if (locks && text) {
 		void *lseg = (void *)locks->sh_addr;
 		void *tseg = (void *)text->sh_addr;
-- 
2.20.1


  parent reply	other threads:[~2020-11-20 20:31 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-20 20:24 [PATCH RFC 00/10] New permission vmalloc interface Rick Edgecombe
2020-11-20 20:24 ` [PATCH RFC 01/10] vmalloc: Add basic perm alloc implementation Rick Edgecombe
2020-11-22  4:10   ` Andy Lutomirski
2020-11-23  0:01     ` Edgecombe, Rick P
2020-11-24 10:16       ` Christoph Hellwig
2020-11-24 20:00         ` Edgecombe, Rick P
2020-11-23  9:00   ` Christoph Hellwig
2020-11-23 20:44     ` Edgecombe, Rick P
2020-11-24 10:19       ` hch
2020-11-24 19:59         ` Edgecombe, Rick P
2020-12-04 23:24   ` Sean Christopherson
2020-12-07 23:55     ` Edgecombe, Rick P
2020-11-20 20:24 ` [PATCH RFC 02/10] bpf: Use perm_alloc() for BPF JIT filters Rick Edgecombe
2020-11-20 20:24 ` [PATCH RFC 03/10] module: Use perm_alloc() for modules Rick Edgecombe
2020-11-20 20:24 ` [PATCH RFC 04/10] module: Support separate writable allocation Rick Edgecombe
2020-11-20 20:24 ` Rick Edgecombe [this message]
2020-11-20 20:24 ` [PATCH RFC 06/10] x86/alternatives: Handle perm_allocs for modules Rick Edgecombe
2020-11-20 20:24 ` [PATCH RFC 07/10] x86/unwind: Unwind orc at module writable address Rick Edgecombe
2020-11-20 20:24 ` [PATCH RFC 08/10] jump_label: Handle " Rick Edgecombe
2020-11-20 20:24 ` [PATCH RFC 09/10] ftrace: Use " Rick Edgecombe
2020-11-20 20:24 ` [PATCH RFC 10/10] vmalloc: Add perm_alloc x86 implementation Rick Edgecombe
2020-11-22 15:29   ` [vmalloc] 377647beed: WARNING:at_arch/x86/kernel/ftrace.c:#ftrace_verify_code kernel test robot

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=20201120202426.18009-6-rick.p.edgecombe@intel.com \
    --to=rick.p.edgecombe@intel.com \
    --cc=akpm@linux-foundation.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=dan.j.williams@intel.com \
    --cc=daniel@iogearbox.net \
    --cc=dave.hansen@linux.intel.com \
    --cc=elena.reshetova@intel.com \
    --cc=ira.weiny@intel.com \
    --cc=jeyu@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=luto@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rppt@kernel.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 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).