GNU/Linux >> Znalost Linux >  >> Linux

Výchozí chování Linuxu vůči sekci `.data`

Ve vašem binárním souboru chybí PT_GNU_STACK . Zdá se, že tato změna byla způsobena odevzdáním 9fccc5c0c99f238aa1b0460fccbdb30a887e7036 :

From 9fccc5c0c99f238aa1b0460fccbdb30a887e7036 Mon Sep 17 00:00:00 2001
From: Kees Cook <[email protected]>
Date: Thu, 26 Mar 2020 23:48:17 -0700
Subject: x86/elf: Disable automatic READ_IMPLIES_EXEC on 64-bit

With modern x86 64-bit environments, there should never be a need for
automatic READ_IMPLIES_EXEC, as the architecture is intended to always
be execute-bit aware (as in, the default memory protection should be NX
unless a region explicitly requests to be executable).

There were very old x86_64 systems that lacked the NX bit, but for those,
the NX bit is, obviously, unenforceable, so these changes should have
no impact on them.

Suggested-by: Hector Marco-Gisbert <[email protected]>
Signed-off-by: Kees Cook <[email protected]>
Signed-off-by: Borislav Petkov <[email protected]>
Reviewed-by: Jason Gunthorpe <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]
---
 arch/x86/include/asm/elf.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index 397a1c74433ec..452beed7892bb 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -287,7 +287,7 @@ extern u32 elf_hwcap2;
  *                 CPU: | lacks NX*  | has NX, ia32     | has NX, x86_64 |
  * ELF:                 |            |                  |                |
  * ---------------------|------------|------------------|----------------|
- * missing PT_GNU_STACK | exec-all   | exec-all         | exec-all       |
+ * missing PT_GNU_STACK | exec-all   | exec-all         | exec-none      |
  * PT_GNU_STACK == RWX  | exec-stack | exec-stack       | exec-stack     |
  * PT_GNU_STACK == RW   | exec-none  | exec-none        | exec-none      |
  *
@@ -303,7 +303,7 @@ extern u32 elf_hwcap2;
  *
  */
 #define elf_read_implies_exec(ex, executable_stack)    \
-   (executable_stack == EXSTACK_DEFAULT)
+   (mmap_is_ia32() && executable_stack == EXSTACK_DEFAULT)
 
 struct task_struct;
 
-- 
cgit 1.2.3-1.el7

To bylo poprvé přítomno v sérii 5.8. Viz také Neočekávané oprávnění exec z mmap, když jsou do projektu zahrnuty soubory sestavení.


Toto je pouze odhad :Myslím, že viníkem je READ_IMPLIES_EXEC osobnost, která byla nastavena automaticky při absenci PT_GNU_STACK segmentu.

Ve zdrojovém kódu jádra 5.4 najdeme tento kousek kódu:

SET_PERSONALITY2(loc->elf_ex, &arch_state);
if (elf_read_implies_exec(loc->elf_ex, executable_stack))
    current->personality |= READ_IMPLIES_EXEC;

To je jediná věc, která dokáže přeměnit RW sekci na RWX. Jakékoli jiné použití PROC_EXEC nezdálo se, že by se to pro tuto otázku změnilo nebo že by to pro mě bylo relevantní.

executable_stack se nastavuje zde:

for (i = 0; i < loc->elf_ex.e_phnum; i++, elf_ppnt++)
    switch (elf_ppnt->p_type) {
    case PT_GNU_STACK:
        if (elf_ppnt->p_flags & PF_X)
            executable_stack = EXSTACK_ENABLE_X;
        else
            executable_stack = EXSTACK_DISABLE_X;
        break;

Ale pokud PT_GNU_STACK segment není přítomen, tato proměnná si zachová výchozí hodnotu:

int executable_stack = EXSTACK_DEFAULT;

Nyní je tento pracovní postup identický v 5.4 a nejnovějším zdrojovém kódu jádra se změnila definice elf_read_implies_exec :

Linux 5.4:

/*
 * An executable for which elf_read_implies_exec() returns TRUE will
 * have the READ_IMPLIES_EXEC personality flag set automatically.
 */
#define elf_read_implies_exec(ex, executable_stack) \
    (executable_stack != EXSTACK_DISABLE_X)

Nejnovější Linux:

/*
 * An executable for which elf_read_implies_exec() returns TRUE will
 * have the READ_IMPLIES_EXEC personality flag set automatically.
 *
 * The decision process for determining the results are:
 *
 *                 CPU: | lacks NX*  | has NX, ia32     | has NX, x86_64 |
 * ELF:                 |            |                  |                |
 * ---------------------|------------|------------------|----------------|
 * missing PT_GNU_STACK | exec-all   | exec-all         | exec-none      |
 * PT_GNU_STACK == RWX  | exec-stack | exec-stack       | exec-stack     |
 * PT_GNU_STACK == RW   | exec-none  | exec-none        | exec-none      |
 *
 *  exec-all  : all PROT_READ user mappings are executable, except when
 *              backed by files on a noexec-filesystem.
 *  exec-none : only PROT_EXEC user mappings are executable.
 *  exec-stack: only the stack and PROT_EXEC user mappings are executable.
 *
 *  *this column has no architectural effect: NX markings are ignored by
 *   hardware, but may have behavioral effects when "wants X" collides with
 *   "cannot be X" constraints in memory permission flags, as in
 *   https://lkml.kernel.org/r/[email protected]
 *
 */
#define elf_read_implies_exec(ex, executable_stack) \
    (mmap_is_ia32() && executable_stack == EXSTACK_DEFAULT)

Všimněte si, jak je ve verzi 5.4 elf_read_implies_exec vrátil skutečnou hodnotu, pokud zásobník nebyl explicitně označeno jako nespustitelné (prostřednictvím PT_GNU_STACK segment).

V nejnovějším zdroji je nyní kontrola více defenzivní:elf_read_implies_exec má hodnotu true pouze u 32bitového spustitelného souboru v případě, že žádné PT_GNU_STACK segment byl nalezen v binárce ELF.

Sestavil jsem váš program, propojil jej a nenašel žádné PT_GNU_STACK segment, takže to může být důvodem.
Pokud je to skutečně problém a pokud jsem postupoval správně podle kódu, pokud nastavíte zásobník jako nespustitelný v binárním formátu, jeho datová část by již neměla být mapována jako spustitelná (ani na Linuxu 5.4).


Linux
  1. Výchozí umístění databáze PostgreSQL v systému Linux

  2. Změňte chování tlačítka napájení Linuxu

  3. Potřebují systémy Linux antivirus proti ransomwaru?

  1. Jak nakonfiguruji Vim jako svůj výchozí editor v Linuxu

  2. Linux – odpověď na stejném rozhraní jako příchozí?

  3. Výchozí oprávnění pro domovské adresáře Linuxu

  1. Jak najít výchozí IP bránu v Linuxu

  2. Jak změnit výchozí prostředí v Linuxu

  3. Změna výchozího prostředí v Linuxu