GNU/Linux >> Linux Esercitazione >  >> Linux

Comportamento predefinito di Linux rispetto alla sezione `.data`

Nel tuo codice binario manca PT_GNU_STACK . Pertanto, questa modifica sembra essere stata causata dal commit 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

Questo era presente per la prima volta nella serie 5.8. Vedi anche Autorizzazione exec imprevista da mmap quando i file assembly sono inclusi nel progetto.


Questa è solo un'ipotesi :Penso che il colpevole sia il READ_IMPLIES_EXEC personalità che veniva impostata automaticamente in assenza di un PT_GNU_STACK segmento.

Nel sorgente del kernel 5.4 possiamo trovare questo pezzo di codice:

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

Questa è l'unica cosa che può trasformare una sezione RW in una RWX. Qualsiasi altro uso di PROC_EXEC non sembrava essere cambiato o rilevante per questa domanda, per me.

Il executable_stack è impostato qui:

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;

Ma se il PT_GNU_STACK segment non è presente, quella variabile mantiene il suo valore predefinito:

int executable_stack = EXSTACK_DEFAULT;

Ora questo flusso di lavoro è identico sia nella versione 5.4 che nell'ultimo sorgente del kernel, ciò che è cambiato è la definizione di 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)

Linux più recente:

/*
 * 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)

Nota come nella versione 5.4 il elf_read_implies_exec ha restituito un valore vero se lo stack non era esplicitamente contrassegnato come non eseguibile (tramite il file PT_GNU_STACK segmento).

Nell'ultima fonte, il controllo è ora più difensivo:il elf_read_implies_exec è vero solo su eseguibile a 32 bit, nel caso in cui non ci sia PT_GNU_STACK segmento è stato trovato nel binario ELF.

Ho assemblato il tuo programma, l'ho collegato e non ho trovato PT_GNU_STACK segmento, quindi questo potrebbe essere la ragione.
Se questo è davvero il problema e se ho seguito correttamente il codice, se imposti lo stack come non eseguibile nel binario, la sua sezione dati non dovrebbe più essere mappata eseguibile (nemmeno su Linux 5.4).


Linux
  1. Come trovare l'IP del gateway predefinito in Linux

  2. Modifica della shell predefinita in Linux

  3. Cambia il monitor predefinito della console Linux

  4. I sistemi Linux necessitano di antivirus contro il ransomware?

  5. Qual è l'ordine predefinito dell'ordinamento di Linux?

Comando Dig in Linux (ricerca DNS)

Sfondi predefiniti di Ubuntu su Arch Linux

Come visualizzare una sezione specifica nelle pagine man in Linux

Come modificare il file di registro di Sudo predefinito in Linux

Ripristina le impostazioni del desktop di Gnome su Default in Linux

Come modificare la shell predefinita nel sistema Linux