From patchwork Fri Jan 12 18:19:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 1886207 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=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=SdeejMHv; 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 4TBVFN6WPXz1yPf for ; Sat, 13 Jan 2024 05:20:08 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7059F3858285 for ; Fri, 12 Jan 2024 18:20:06 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by sourceware.org (Postfix) with ESMTPS id 379C93858285 for ; Fri, 12 Jan 2024 18:19:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 379C93858285 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 379C93858285 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::635 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1705083587; cv=none; b=YjaTSEYOwVyyTPgYcenyRMQN35PbgA8NOPGU2/ImD5Gw5HZh7Fq8VRyCsRV6gba4vZogVldEZWjDYhSo42Mr4ro93LjqVkX3BKAP8dsCqhuko4/KDLrGx+HvmINoGRskgBLcKrQgDCyWGlCbUkNglo53wBgHmKQRNv5MIo1Yt+w= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1705083587; c=relaxed/simple; bh=KvN4WAGjwFkBZ+yU0RPIK5NMC6d7BBhpj59WL2i7jYw=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=hsfXxc6Neu3wCggeLKqY/jg+vIoTWev/I4sDuGkJGbIViSDYj12da9ffql89rKRJ6mCTZ/eFBkQR05AKi6s0AI58rvRDy4Uy+FsOw+jx55jWoOPcc8O/HmCMYzpw4nV/fmNiFLIwACJwWZ034nFBoRMWOi5gCmJfYlf0x/TAdAY= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x635.google.com with SMTP id d9443c01a7336-1d3f8af8297so39372955ad.2 for ; Fri, 12 Jan 2024 10:19:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1705083584; x=1705688384; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=Eowng1zdokKmoFdJB+kxHx1IgnoEGh7ozaWHSpTX3Ws=; b=SdeejMHvFZhNubT++jpskvJ8JLckziCyo7xIHgjFGJer0TCsGGJK6Qs4lTongaJ7a2 8n+f97wQlLNdig7RN7YOVcdn6J1tAeZKnwb/KGSTbi3QDdijhcC8cDnCSwuR0Ac+wXV2 vZltPi21xOg8aPag/fVY8qBioZwIoWoujMYi3LiHNqE8NJVQ2T/riyFDu48wppJzEQ0Y PV0oPorrOoh7Rf/92ppFfvBzTjzevFfghoJb6fu9Gsl/VayfM4eU9L61fu0DVdueopha iSRIO3XgnlUu0TbPDIUZHCDzddSj87+8uJon9o/Jfp6vGx5JHpyC4eUja/7iJXmKH/IA TqiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1705083584; x=1705688384; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Eowng1zdokKmoFdJB+kxHx1IgnoEGh7ozaWHSpTX3Ws=; b=QuDxNBU0MmGdbKlJsnwS8O0S/DGwCskeQ34EqzbvlcBKg7rmFLB7UzBKHokw5WD1sd 6StFqAFrmdR73csa6Ed+dFQBrJUChjDgDn1HfSQzOuCf5aVOcOZZ4Ae3brPsf8BW8GXj jIswjOUzwJUtJ6koVRiW8s8zijk77p3Q49uyYnU19JXgoyjwgoW0N+YZ+p+y50KifZFb DQkqn4jEErMkkD9/8PlnjZzlL/hF175klWCIKRiKpdxzYCKP5cIJ9OQ4cwoggBXnSWKv wmCbU9Gu0M95I+niKJibSY6d2r9y/wA6EDi7N+bXjQK1bhfmyiOfAG0iKRWuELrf4F1k 4aNw== X-Gm-Message-State: AOJu0YyS0G59jetrWc8D1kOmF5Jkz4f0HcEPkGlLy5UVoWkkKkos8zN2 tBMWv6gV7rSeZIbpTGOL5ATrQLwHPME= X-Google-Smtp-Source: AGHT+IFqnRr5wn5MW5BJEIJaRRh7sN+aQtPPWXqp8snp+8wqaENYCm12HBSVWfZ8X0vwcisXM+U6wA== X-Received: by 2002:a17:902:780b:b0:1d4:f32f:16bc with SMTP id p11-20020a170902780b00b001d4f32f16bcmr994098pll.123.1705083583841; Fri, 12 Jan 2024 10:19:43 -0800 (PST) Received: from gnu-cfl-3.localdomain ([172.56.168.9]) by smtp.gmail.com with ESMTPSA id r3-20020a1709028bc300b001c9db5e2929sm3436960plo.93.2024.01.12.10.19.42 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Jan 2024 10:19:43 -0800 (PST) Received: from gnu-cfl-3.. (localhost [IPv6:::1]) by gnu-cfl-3.localdomain (Postfix) with ESMTP id A12DA740375 for ; Fri, 12 Jan 2024 10:19:41 -0800 (PST) From: "H.J. Lu" To: libc-alpha@sourceware.org Subject: [PATCH v2] x86-64: Check if mprotect works before rewriting PLT Date: Fri, 12 Jan 2024 10:19:41 -0800 Message-ID: <20240112181941.3536012-1-hjl.tools@gmail.com> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-Spam-Status: No, score=-3020.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_ABUSEAT, RCVD_IN_DNSWL_NONE, RCVD_IN_SBL_CSS, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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 Systemd execution environment configuration may prohibit changing a memory mapping to become executable: MemoryDenyWriteExecute= Takes a boolean argument. If set, attempts to create memory mappings that are writable and executable at the same time, or to change existing memory mappings to become executable, or mapping shared memory segments as executable, are prohibited. When it is set, systemd service stops working if PLT rewrite is enabled. Check if mprotect works before rewriting PLT. This fixes BZ #31230. This also works with SELinux when deny_execmem is on. Reviewed-by: Carlos O'Donell --- .../unix/sysv/linux/x86_64/dl-plt-rewrite.h | 43 +++++++++++++++++++ sysdeps/x86/cpu-features.c | 8 +++- sysdeps/x86_64/dl-plt-rewrite.h | 25 +++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 sysdeps/unix/sysv/linux/x86_64/dl-plt-rewrite.h create mode 100644 sysdeps/x86_64/dl-plt-rewrite.h diff --git a/sysdeps/unix/sysv/linux/x86_64/dl-plt-rewrite.h b/sysdeps/unix/sysv/linux/x86_64/dl-plt-rewrite.h new file mode 100644 index 0000000000..ad637df930 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86_64/dl-plt-rewrite.h @@ -0,0 +1,43 @@ +/* PLT rewrite helper function. Linux/x86-64 version. + Copyright (C) 2024 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +static __always_inline bool +dl_plt_rewrite_supported (void) +{ + /* PLT rewrite is enabled. Check if mprotect works. */ + void *plt = (void *) INTERNAL_SYSCALL_CALL (mmap, NULL, 4096, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + if (__glibc_unlikely (plt == MAP_FAILED)) + return false; + + /* Touch the PROT_READ | PROT_WRITE page. */ + *(int32_t *) plt = 1; + + /* If the updated PROT_READ | PROT_WRITE page can be changed to + PROT_EXEC | PROT_READ, rewrite PLT. */ + bool status = (INTERNAL_SYSCALL_CALL (mprotect, plt, 4096, + PROT_EXEC | PROT_READ) == 0); + + INTERNAL_SYSCALL_CALL (munmap, plt, 4096); + + return status; +} diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c index 46bdaffbc2..25e6622a79 100644 --- a/sysdeps/x86/cpu-features.c +++ b/sysdeps/x86/cpu-features.c @@ -28,10 +28,16 @@ extern void TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *) attribute_hidden; #if defined SHARED && defined __x86_64__ +# include + static void TUNABLE_CALLBACK (set_plt_rewrite) (tunable_val_t *valp) { - if (valp->numval != 0) + /* We must be careful about where we put the call to + dl_plt_rewrite_supported() since it may generate + spurious SELinux log entries. It should only be + attempted if the user requested a PLT rewrite. */ + if (valp->numval != 0 && dl_plt_rewrite_supported ()) { /* Use JMPABS only on APX processors. */ const struct cpu_features *cpu_features = __get_cpu_features (); diff --git a/sysdeps/x86_64/dl-plt-rewrite.h b/sysdeps/x86_64/dl-plt-rewrite.h new file mode 100644 index 0000000000..cab6fe75ea --- /dev/null +++ b/sysdeps/x86_64/dl-plt-rewrite.h @@ -0,0 +1,25 @@ +/* PLT rewrite helper function. x86-64 version. + Copyright (C) 2024 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +static __always_inline bool +dl_plt_rewrite_supported (void) +{ + return true; +}