GNU/Linux >> Linux の 問題 >  >> Linux

`.data` セクションに対する Linux のデフォルトの動作

バイナリに PT_GNU_STACK がありません .そのため、この変更はコミット 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

これは 5.8 シリーズで初めて登場しました。プロジェクトにアセンブリ ファイルが含まれている場合、mmap からの予期しない exec 権限も参照してください。


これは単なる推測です :犯人は READ_IMPLIES_EXEC だと思います PT_GNU_STACK がない場合に自動的に設定されていたパーソナリティ

5.4 カーネル ソースには、次のコードがあります:

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

RW セクションを RWX セクションに変換できるのはこれだけです。 PROC_EXEC のその他の使用 私には、変更されていないようにも、この質問に関連しているようにも見えませんでした.

executable_stack ここで設定されます:

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;

PT_GNU_STACK の場合 セグメントが存在しない場合、その変数はデフォルト値を保持します:

int executable_stack = EXSTACK_DEFAULT;

これで、このワークフローは同一になりました 5.4 と最新のカーネル ソースの両方で、変更されたのは 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:

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

5.4 バージョンで elf_read_implies_exec スタックが明示的でない場合に真の値を返しました 実行不可としてマークされます (PT_GNU_STACK 経由) セグメント)

最新のソースでは、チェックはより防御的になりました:elf_read_implies_exec PT_GNU_STACK がない場合、32 ビットの実行可能ファイルでのみ true です。 セグメントが ELF バイナリで見つかりました。

あなたのプログラムをアセンブルしてリンクしましたが、PT_GNU_STACK が見つかりませんでした セグメントなので、これは 可能性があります 理由になります。
これが実際に問題であり、コードに正しく従った場合、スタックをバイナリで実行不可として設定すると、そのデータ セクションは実行可能にマップされなくなります (Linux 5.4 でも)。


Linux
  1. Linux –着信と同じインターフェースで応答しますか?

  2. Linux でデフォルトのシェルを変更する方法

  3. Linux 上の PostgreSQL データベースのデフォルトの場所

  1. LinuxでVimをデフォルトのエディターとして設定する方法

  2. Linux でのデフォルト シェルの変更

  3. Linux コンソールのデフォルト モニターを変更する

  1. LinuxでデフォルトゲートウェイIPを見つける方法

  2. Linux の電源ボタンの動作を変更する

  3. Linux システムには、ランサムウェアに対するウイルス対策が必要ですか?