From patchwork Wed Jul 31 20:02:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 1967280 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=bMaR6W0B; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WZ3261SRdz1yYq for ; Thu, 1 Aug 2024 06:03:41 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0E0CA3858C35 for ; Wed, 31 Jul 2024 20:03:40 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by sourceware.org (Postfix) with ESMTPS id 224013858C78 for ; Wed, 31 Jul 2024 20:03:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 224013858C78 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 224013858C78 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::629 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722456196; cv=none; b=ZwcSh2rjS8/124H0+SJmjw8T7a/NayeImowNbFZu8oBC24laMWDjGm+mqOhJhGxtAtLPg7nZWlBSa+IdnD3HwKK5X0kEiEc8TRBFazNxYPmAxE9bFSzzx5mOnt6QqOPWSv1jhveahFQv06IEON4ixdWxsLVjfU3sbfoIfryA4Hg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722456196; c=relaxed/simple; bh=H8FueidP3uPrMtxaXrJspo1YID9tTS35q4u+RycRBFU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=UcLn/sE5MOb22LitkE14sUVmAEg+/mHQ34p7SNWsvm60e2F5ENqtpA/rL63aOWCLqlMduDPem0VtyyGWB1YJB+YV3WeAa6j+5i59g1t3Yt9StImR1tQ4qnLnY/AbjENytY5KLLhOfLvCOEBpCQELMbKUDNzksKLormPFL75gBuk= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x629.google.com with SMTP id d9443c01a7336-1fc52394c92so53797555ad.1 for ; Wed, 31 Jul 2024 13:03:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1722456192; x=1723060992; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=DgVKcCcdx00juTetpOuZDt+p7Gwz8UPznRnhmOP8scQ=; b=bMaR6W0BH5wAbCE0NwLC6odrrrAkksYgSVawtUOPAeBZ2dp6di1MrMEOlnGiB0srzH DOE+mJupNbUBA+r0QQFYYiMMhUY3W+hAd+/9pjvNiqs95Ig6kX4qtYC4kFU8BmFmZdyG HRa5trDdQS7oNrUZNj4XoMqeC9nyPt48Tf2TJmYar0BGXEKaE6MJpS99Q2bXSaFp8I/s 9PWhymRETpEIPWdcRd87Jh2rqhBluFbZPJVAn+smBOlkzlQ1x6BwQL0GjJT0l1buxnf5 ftylZiFiyytvAolgF238rR/XQcdm09u8mRHS67REws9QDD9Or7wRG+31+qG4u6oW22l7 /7Tw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722456192; x=1723060992; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=DgVKcCcdx00juTetpOuZDt+p7Gwz8UPznRnhmOP8scQ=; b=r5594UZPSqiL3cEgjP+yhEzJ+qgHtTbnaR1DNVNznq1CYpy8Q17AemPYzj/uT2c378 dpPBL85FfhNo39aMoNC4/tOWRYMAkXTohXNpUH6lKFHGtMyair38WWe+bIRISGD0FYk8 /0WvnDjtDMnu40TVLzU7v2cfwTx1T23Ml1tASQREH6fUHypA1/lExPnz2kdxwCKOQeQS QTUcTXEGBSFyPmfxF2qKGDVZOLjphGvDo5q2YVq07ehQH2YmcaIw0y8WAgN1MF+uwQeD 8IjWaqfUSfhh4OEZ/+V7c/10mA/DVX6DJFqFrppcmA1LIVkhFKMWhCucIZWGWRcQ1y7k /QdQ== X-Gm-Message-State: AOJu0YwSm9BbP1SUhImDVHLULccmpF2rSYH0qCPnvnvA2WlJkjEU24Er BYU/h1maqDP2cFIwbtd0wXoYTeeW8DKVEYaNGxQ+YB8b6SEhrHBMziCHLxgrCsenx2we0abDOQ1 D X-Google-Smtp-Source: AGHT+IGlc5YJ/UcFR84Hd9gOtlvFge4u4vpZ4NuDrtBMqo/xesAFASyGUi8Rl9vniuPlHJMAt8Cz/Q== X-Received: by 2002:a17:902:c94d:b0:1fb:a1cb:cb25 with SMTP id d9443c01a7336-1ff4d2363ebmr5169465ad.40.1722456192355; Wed, 31 Jul 2024 13:03:12 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c1:1944:b913:6070:fef0:3852]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1fed7fbd8d4sm124106725ad.271.2024.07.31.13.03.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 31 Jul 2024 13:03:11 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Stephen Roettger , Jeff Xu , Florian Weimer , Mike Hommey Subject: [PATCH v2 0/5] Add support for memory sealing Date: Wed, 31 Jul 2024 17:02:03 -0300 Message-ID: <20240731200307.2269811-1-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-Spam-Status: No, score=-6.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org The Linux 6.10 (8be7258aad44b5e25977a98db136f677fa6f4370) added the mseal syscall that allows blocking some memory operations on the VMA range: * Unmapping, moving to another location, extending or shrinking the size, munmap, and mremap. * Moving or expanding a different VMA into the current location, via mremap. * Modifying the memory range with mmap along with flag MAP_FIXED. * Expanding the size with mremap. * Change the protection flags with mprotect or pkey_mprotect. * Destructive behaviors on anonymous memory, such as madvice with MADV_DONTNEED. Memory sealing might be useful as a hardening mechanism to avoid either remapping the memory segments or changing the memory protection segments layout by the dynamic loader (for instance, the RELRO hardening). A similar hardening is done by OpenBSD with the mimmutable syscall [1]. The first patch expands the use of RTLD_NODELETE for objects that should not be deallocated during process execution.  The flag will be used later to decide whether to seal the link_map: * on dlopen dependencies for objects opened with RTLD_NODELETE * For the main map executable. * For the main map DT_NEEDED dependencies. * On __libc_unwind_link_get for libgcc_s.so (used for backtrace and unwind). The second patch adds the mseal support for Linux. Although most programs will not use it directly, some specific ones, like Chrome, intend to use it. The third patch adds memory sealing in multiple places where the memory is supposed to be immutable over program execution: * All shared library dependencies from the binary, including the read-only segments after PT_GNU_RELRO setup. * The binary itself, including dynamic and static links. In both cases, it is up either to binary or the loader to set up the sealing. * Any preload libraries. * Any library loaded with dlopen with RTLD_NODELETE flag (including libgcc.so loaded to enable process unwind and thread cancellation). * Audit modules. * The loader bump allocator. For binary dependencies, the RTLD_NODELETE signals the link_map should be sealed. It also makes dlopen objects with the flag sealed as well. The sealing is also controlled by a new tunable, glibc.rtld.seal, with three different states: 0. Disabled, where no memory sealing is done. 1. Enabled, where the loader will issue the mseal syscall on the memory mappings, and any failure is ignored. This is the default. 2. Enforce, similar to Enabled and any failure from the mseal terminates the process. The final patch adds support for GNU_PROPERTY_NO_MEMORY_SEAL, where the binary can be marked to avoid sealing (i.e., on Firefox hack to bypass the dynamic loader and enable DT_RELR on older glibc [3]). In this case, it is up to the module to apply memory sealing itself. I have a patch to binutils to add -Wl,-z,no-memory-seal option to enable it. This patchset does not delay RELRO activation until after their ELF constructors have been executed, as suggested on the previous RFC for mseal support. It is not strictly required, and it requires extensive changes on_dl_start_user to either make _dl_init call RELRO/sealing setup after ctor/initarray is done, or call it after _dl_init. There is also the question of whether to apply RELRO/sealing per module after dtor/initarray or in bulk after _dt_init. I tested on both x86_64-linux-gnu and aarch64-linux-gnu with Linux 6.11-rc1, along with some testing on a powerpc64le-linux-gnu VM. I also enabled glibc.rtld.seal=2 to check for possible mseal failures. [1] https://man.openbsd.org/mimmutable.2 [2] https://docs.google.com/document/d/1O2jwK4dxI3nRcOJuPYkonhTkNQfbmwdvxQMyXgeaRHo/edit#heading=h.bvaojj9fu6hc [3] https://glandium.org/blog/?p=4297 Adhemerval Zanella (5): elf: Use RTLD_NODELETE is more places linux: Add mseal syscall support elf: Add support to memory sealing elf: Also parse gnu properties for static linked binaries elf: Add support for GNU_PROPERTY_NO_MEMORY_SEAL NEWS | 15 + configure | 35 +++ configure.ac | 5 + elf/dl-load.c | 4 + elf/dl-map-segments.h | 5 + elf/dl-minimal-malloc.c | 2 + elf/dl-mseal-mode.h | 29 ++ elf/dl-open.c | 7 +- elf/dl-reloc.c | 47 +++ elf/dl-support.c | 20 ++ elf/dl-tunables.list | 6 + elf/elf.h | 2 + elf/rtld.c | 13 +- elf/setup-vdso.h | 2 + elf/tst-rtld-list-tunables.exp | 1 + include/dlfcn.h | 2 + include/link.h | 7 + manual/memory.texi | 66 +++++ manual/tunables.texi | 42 +++ misc/unwind-link.c | 5 +- sysdeps/aarch64/dl-prop.h | 5 + sysdeps/generic/dl-mseal.h | 23 ++ sysdeps/generic/dl-prop-mseal.h | 38 +++ sysdeps/generic/dl-prop.h | 5 + sysdeps/generic/ldsodefs.h | 9 + sysdeps/unix/sysv/linux/Makefile | 94 ++++++ sysdeps/unix/sysv/linux/Versions | 3 + sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 1 + sysdeps/unix/sysv/linux/arc/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/le/libc.abilist | 1 + sysdeps/unix/sysv/linux/bits/mman-shared.h | 8 + sysdeps/unix/sysv/linux/csky/libc.abilist | 1 + sysdeps/unix/sysv/linux/dl-mseal.c | 51 ++++ sysdeps/unix/sysv/linux/dl-mseal.h | 27 ++ sysdeps/unix/sysv/linux/hppa/libc.abilist | 1 + sysdeps/unix/sysv/linux/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/kernel-features.h | 8 + .../sysv/linux/loongarch/lp64/libc.abilist | 1 + .../sysv/linux/m68k/coldfire/libc.abilist | 1 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 1 + .../sysv/linux/microblaze/be/libc.abilist | 1 + .../sysv/linux/microblaze/le/libc.abilist | 1 + .../sysv/linux/mips/mips32/fpu/libc.abilist | 1 + .../sysv/linux/mips/mips64/n32/libc.abilist | 1 + .../sysv/linux/mips/mips64/n64/libc.abilist | 1 + sysdeps/unix/sysv/linux/nios2/libc.abilist | 1 + sysdeps/unix/sysv/linux/or1k/libc.abilist | 1 + .../linux/powerpc/powerpc32/fpu/libc.abilist | 1 + .../powerpc/powerpc32/nofpu/libc.abilist | 1 + .../linux/powerpc/powerpc64/be/libc.abilist | 1 + .../linux/powerpc/powerpc64/le/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv32/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv64/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-32/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-64/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/le/libc.abilist | 1 + .../sysv/linux/sparc/sparc32/libc.abilist | 1 + .../sysv/linux/sparc/sparc64/libc.abilist | 1 + sysdeps/unix/sysv/linux/syscalls.list | 1 + .../unix/sysv/linux/tst-dl_mseal-auditmod.c | 23 ++ .../unix/sysv/linux/tst-dl_mseal-dlopen-1-1.c | 19 ++ .../unix/sysv/linux/tst-dl_mseal-dlopen-1.c | 19 ++ .../unix/sysv/linux/tst-dl_mseal-dlopen-2-1.c | 19 ++ .../unix/sysv/linux/tst-dl_mseal-dlopen-2.c | 19 ++ .../tst-dl_mseal-dlopen-no-memory-seal-2-1.c | 19 ++ .../tst-dl_mseal-dlopen-no-memory-seal-2.c | 19 ++ sysdeps/unix/sysv/linux/tst-dl_mseal-mod-1.c | 19 ++ sysdeps/unix/sysv/linux/tst-dl_mseal-mod-2.c | 19 ++ .../linux/tst-dl_mseal-mod-no-memory-seal-1.c | 19 ++ .../linux/tst-dl_mseal-mod-no-memory-seal-2.c | 19 ++ .../tst-dl_mseal-no-memory-seal-auditmod.c | 1 + .../tst-dl_mseal-no-memory-seal-preload.c | 1 + .../sysv/linux/tst-dl_mseal-no-memory-seal.c | 65 +++++ .../unix/sysv/linux/tst-dl_mseal-preload.c | 19 ++ .../unix/sysv/linux/tst-dl_mseal-skeleton.c | 272 ++++++++++++++++++ .../tst-dl_mseal-static-no-memory-seal.c | 38 +++ sysdeps/unix/sysv/linux/tst-dl_mseal-static.c | 36 +++ sysdeps/unix/sysv/linux/tst-dl_mseal.c | 67 +++++ sysdeps/unix/sysv/linux/tst-mseal.c | 67 +++++ .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + sysdeps/x86/dl-prop.h | 4 + 85 files changed, 1396 insertions(+), 6 deletions(-) create mode 100644 elf/dl-mseal-mode.h create mode 100644 sysdeps/generic/dl-mseal.h create mode 100644 sysdeps/generic/dl-prop-mseal.h create mode 100644 sysdeps/unix/sysv/linux/dl-mseal.c create mode 100644 sysdeps/unix/sysv/linux/dl-mseal.h create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-auditmod.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-1-1.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-1.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2-1.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-2.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-no-memory-seal-2-1.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-dlopen-no-memory-seal-2.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-mod-1.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-mod-2.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-mod-no-memory-seal-1.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-mod-no-memory-seal-2.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-no-memory-seal-auditmod.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-no-memory-seal-preload.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-no-memory-seal.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-preload.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-skeleton.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-static-no-memory-seal.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal-static.c create mode 100644 sysdeps/unix/sysv/linux/tst-dl_mseal.c create mode 100644 sysdeps/unix/sysv/linux/tst-mseal.c