From patchwork Tue Jun 25 12:24:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dev Jain X-Patchwork-Id: 13711044 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7B6CEC30653 for ; Tue, 25 Jun 2024 12:26:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=YcLf1ORZA67yLIr0YiEzGKDoXaeV8NHAzHm7DIJrzgI=; b=An5vEBZ8KibzdksJA9th9zKTdF ks19sFIVSOApkDQ/tdxHtdJ2M7hJv0APct6xJ3C6KN2aEO5Eoea8WfhFHc9/La6/diXAWT48iFPzJ Uv1t73p/+9Q/gz3yiOkFihowEnstqn8fb0H0N2dphoWzlNv53P875T64wic0ajjAvyJ7A3pv7cDFi anxKMyfyER6V9ttLMUKwTbs6bdv6CCk/MwnaXbXbvGXaBTaaMnlNUarI11U1HfUuv99y22T5e/tjn vxOiGGOOJ6I48eCwxJ8w2B0U802sZpOSLtkQAjs0QMJvBtYEUdItAunBSlSd+Qc+jBebN1yq4VgcY oAD425JA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sM5FD-00000002kFK-3kXg; Tue, 25 Jun 2024 12:25:55 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sM5EU-00000002jhy-399n for linux-arm-kernel@lists.infradead.org; Tue, 25 Jun 2024 12:25:12 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 40833339; Tue, 25 Jun 2024 05:25:35 -0700 (PDT) Received: from e116581.blr.arm.com (e116581.arm.com [10.162.41.12]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 898A83F766; Tue, 25 Jun 2024 05:25:05 -0700 (PDT) From: Dev Jain To: shuah@kernel.org, linux-arm-kernel@lists.infradead.org, linux-kselftest@vger.kernel.org, Catalin.Marinas@arm.com, will@kernel.org Cc: broonie@kernel.org, ryan.roberts@arm.com, rob.herring@arm.com, mark.rutland@arm.com, linux@armlinux.org.uk, suzuki.poulose@arm.com, Anshuman.Khandual@arm.com, aneesh.kumar@kernel.org, linux-kernel@vger.kernel.org, Dev Jain Subject: [PATCH v3 7/9] selftests/arm: Add ptrace test Date: Tue, 25 Jun 2024 17:54:06 +0530 Message-Id: <20240625122408.1439097-8-dev.jain@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240625122408.1439097-1-dev.jain@arm.com> References: <20240625122408.1439097-1-dev.jain@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240625_052510_980448_3F383FE7 X-CRM114-Status: GOOD ( 15.74 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org For a 32-bit parent debugging a 32-bit child, add tests for reading the TLS registers, and mangling with the mode bits in CPSR. Signed-off-by: Dev Jain --- tools/testing/selftests/arm/abi/ptrace.c | 82 ++++++++++++++++++++++++ tools/testing/selftests/arm/abi/ptrace.h | 57 ++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 tools/testing/selftests/arm/abi/ptrace.c create mode 100644 tools/testing/selftests/arm/abi/ptrace.h diff --git a/tools/testing/selftests/arm/abi/ptrace.c b/tools/testing/selftests/arm/abi/ptrace.c new file mode 100644 index 000000000000..2079065c48fd --- /dev/null +++ b/tools/testing/selftests/arm/abi/ptrace.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024 ARM Limited. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ptrace.h" +#include "../../kselftest.h" + +#define EXPECTED_TESTS 6 +#define NUM_TLS_REGS 2 + +static void test_tpidr(pid_t child) +{ + unsigned long read_val[NUM_TLS_REGS]; + struct iovec read_iov; + int ret; + + read_iov.iov_base = read_val; + + /* TLS registers must not be accessible */ + read_iov.iov_len = 2 * sizeof(unsigned long); + ret = ptrace(PTRACE_GETREGSET, child, NT_ARM_TLS, &read_iov); + ksft_test_result(ret != 0, "cannot read TLS\n"); +} + +static void run_tests(pid_t child) +{ + test_tpidr(child); + test_user_regs(child); +} + +static int do_child(void) +{ + if (ptrace(PTRACE_TRACEME, -1, NULL, NULL)) + ksft_exit_fail_perror("PTRACE_TRACEME"); + + if (raise(SIGSTOP)) + ksft_exit_fail_perror("raise(SIGSTOP)"); + + if (raise(SIGSTOP)) + ksft_exit_fail_perror("raise(SIGSTOP)"); + + return EXIT_SUCCESS; +} + +int main(void) +{ + int ret = EXIT_SUCCESS; + pid_t child; + + srandom(getpid()); + + ksft_print_header(); + + ksft_set_plan(EXPECTED_TESTS); + + child = fork(); + if (!child) + return do_child(); + + if (do_parent(child)) + ret = EXIT_FAILURE; + + ksft_print_cnts(); + + return ret; +} diff --git a/tools/testing/selftests/arm/abi/ptrace.h b/tools/testing/selftests/arm/abi/ptrace.h new file mode 100644 index 000000000000..17ba8aa32726 --- /dev/null +++ b/tools/testing/selftests/arm/abi/ptrace.h @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include "../../arm64/abi/ptrace.h" + +/* Do not pull from asm/ptrace.h since the macro names change for 32-bit */ +#define PSR_MODE32_BIT 0x00000010 +#define PSR_MODE_EL1t 0x00000004 + +static void test_user_regs(pid_t child) +{ + unsigned int read_val[18]; + struct iovec read_iov; + int status; + int ret; + + read_iov.iov_base = read_val; + read_iov.iov_len = 18 * sizeof(unsigned int); + + ret = ptrace(PTRACE_GETREGSET, child, NT_PRSTATUS, &read_iov); + ksft_test_result(!ret, "read general-purpose registers\n"); + + /* Change a random user register */ + read_val[2] = read_val[2] + 1; + ret = ptrace(PTRACE_SETREGSET, child, NT_PRSTATUS, &read_iov); + ksft_test_result(!ret, "set user register\n"); + + /* 16th register is the CPSR */ + read_val[16] &= (~PSR_MODE32_BIT); + + ret = ptrace(PTRACE_SETREGSET, child, NT_PRSTATUS, &read_iov); + ksft_test_result(ret, "cannot toggle MODE32 bit\n"); + + ret = ptrace(PTRACE_CONT, child, NULL, 0); + if (ret) { + perror("ptrace"); + goto error; + } + + if (wait(&status) == -1) { + perror("wait"); + goto error; + } + + read_val[16] = 0; + + ret = ptrace(PTRACE_GETREGSET, child, NT_PRSTATUS, &read_iov); + ksft_test_result(!ret, "read general-purpose registers again\n"); + + read_val[16] |= PSR_MODE_EL1t; + ret = ptrace(PTRACE_SETREGSET, child, NT_PRSTATUS, &read_iov); + ksft_test_result(ret, "cannot escalate privilege\n"); + return; + +error: + kill(child, SIGKILL); +} + +