From patchwork Tue Apr 18 08:47:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: tip-bot2 for Thomas Gleixner X-Patchwork-Id: 84686 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2687898vqo; Tue, 18 Apr 2023 01:53:33 -0700 (PDT) X-Google-Smtp-Source: AKy350buIEdUpSigCt/JmTysVfqyjjmMTG89UGU+4g9eIbFNOVowL2sU18npBJUbkZQ4KI5PtEKg X-Received: by 2002:a17:903:41c2:b0:1a6:4118:6f9e with SMTP id u2-20020a17090341c200b001a641186f9emr1593329ple.20.1681808013748; Tue, 18 Apr 2023 01:53:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1681808013; cv=none; d=google.com; s=arc-20160816; b=vVD002Rn5regM+T9YHz8avd/l3rVS/Y3Pje12modG25izSfpbfbVgyrd8buRdpy50o IKyCpHXpzeCg9aZNWUM9l52q2E8famDdOLo6jDAnOa3ZZOLf+aAbOmE/VUnYtWsZoM2X lNlIiyaEbR0cuhDNBDAbyTJXzr6kH6Lt3HR0UJJhDOMrvGvP3hwaOIf1lMn4qmvM4ald imunvhDJVcyY7k+GA1Cz2s0pCdedWTcCWVonHC2dPzI5D0GyP+2bcZjd8V8AX0ozaLb/ UzSdG2/Ozk5E3C54G6tBSC6AtTzNlqcKLibQ+cO0+/qaZgTnTWvrFUb7HoZU4bcLyC8G 4ZAA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:robot-unsubscribe :robot-id:message-id:mime-version:references:in-reply-to:cc:subject :to:reply-to:sender:from:dkim-signature:dkim-signature:date; bh=L1a7AYGEaUBTHfAe9S9XNC8RHJ7ymGg4gOus79C9NCg=; b=1JeklZ0yXya6l35xy3Sw2ewrbR+USJvVSLHCk2aASQ/a2nB4j6tFLT77BnhGpxLZsK EyrXoSJjT7bS2e0ntx5Ihl16+Gvy6vATSZetFivA7yxI8fh9ohDVZYXHX8AM5COMAi0d 7hBqeb3tYi3egHuvNj2p3JTMYHrsDCaq2NM7VzlFUkePYcBCOUTdWldd4OZ3RuyQRktB Lb+2XdPPbkMeYtVEWkFB49UzM9cdbPa/Q6Z6ljAyBXLTOa5gMMc8QgUakCZxhWtRRYNu QELc5iU2tLBv7LfuTtwKezLjFZ+MuilkzgGUj35XO0l9o6zG26/3oefobiMSsj9maNdY BS3w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=NoYv1yPR; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id g16-20020a170902869000b001a6db2bef24si4218153plo.145.2023.04.18.01.53.19; Tue, 18 Apr 2023 01:53:33 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=NoYv1yPR; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230440AbjDRIrq (ORCPT + 99 others); Tue, 18 Apr 2023 04:47:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55050 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230490AbjDRIrm (ORCPT ); Tue, 18 Apr 2023 04:47:42 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4159A35B8; Tue, 18 Apr 2023 01:47:40 -0700 (PDT) Date: Tue, 18 Apr 2023 08:47:38 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1681807658; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=L1a7AYGEaUBTHfAe9S9XNC8RHJ7ymGg4gOus79C9NCg=; b=NoYv1yPRfJjOISgdP55HKqA+dBzrv7ADWSNY68mcaCX19cDigHYdcx/Ff0Sdhbj0L3phwd ism0fDkQrljl53d06kCOOYbvTsliQHKo5lm5oa1fJVBEXCAYe9e+ZzWamh+3aRxymNZZOk RVKw225hH+JLXjf2ajCW2KzGnCRm8RKD77PTmu9BJX8vvo6+ucm0AagDeVFFKg907g3Jl0 Bzfva4Y2YfOEBtNX+hEazfRAYry8U3TxhjV+EIcZrC0Bptxy4GWf2O2yxPZ2kzVspRvPvi XVbBDT33oVjQeMLqa8GIlHZ3CBM4ckjZaCPOWKYSJhBk0z+s3Xmewp+Ubl/5Kg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1681807658; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=L1a7AYGEaUBTHfAe9S9XNC8RHJ7ymGg4gOus79C9NCg=; b=iClbgODzUDhuvd80iGgapyO4ir+cUZq8UdptEve/Plf5p05EzvsMkwDQSxJf1AnLxxX7NH vGYxFS6T7MMU5TAg== From: "tip-bot2 for Gregory Price" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: core/entry] ptrace: Provide set/get interface for syscall user dispatch Cc: Gregory Price , Thomas Gleixner , Oleg Nesterov , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20230407171834.3558-4-gregory.price@memverge.com> References: <20230407171834.3558-4-gregory.price@memverge.com> MIME-Version: 1.0 Message-ID: <168180765842.404.5393743959112706643.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1763503519839615772?= X-GMAIL-MSGID: =?utf-8?q?1763503519839615772?= The following commit has been merged into the core/entry branch of tip: Commit-ID: 3f67987cdc09778e75098f9f5168832f8f8e1f1c Gitweb: https://git.kernel.org/tip/3f67987cdc09778e75098f9f5168832f8f8e1f1c Author: Gregory Price AuthorDate: Fri, 07 Apr 2023 13:18:33 -04:00 Committer: Thomas Gleixner CommitterDate: Sun, 16 Apr 2023 14:23:07 +02:00 ptrace: Provide set/get interface for syscall user dispatch The syscall user dispatch configuration can only be set by the task itself, but lacks a ptrace set/get interface which makes it impossible to implement checkpoint/restore for it. Add the required ptrace requests and the get/set functions in the syscall user dispatch code to make that possible. Signed-off-by: Gregory Price Signed-off-by: Thomas Gleixner Reviewed-by: Oleg Nesterov Link: https://lore.kernel.org/r/20230407171834.3558-4-gregory.price@memverge.com --- Documentation/admin-guide/syscall-user-dispatch.rst | 4 +- include/linux/syscall_user_dispatch.h | 18 +++++- include/uapi/linux/ptrace.h | 30 +++++++++- kernel/entry/syscall_user_dispatch.c | 40 ++++++++++++- kernel/ptrace.c | 9 +++- 5 files changed, 101 insertions(+) diff --git a/Documentation/admin-guide/syscall-user-dispatch.rst b/Documentation/admin-guide/syscall-user-dispatch.rst index 6031495..e3cfffe 100644 --- a/Documentation/admin-guide/syscall-user-dispatch.rst +++ b/Documentation/admin-guide/syscall-user-dispatch.rst @@ -73,6 +73,10 @@ thread-wide, without the need to invoke the kernel directly. selector can be set to SYSCALL_DISPATCH_FILTER_ALLOW or SYSCALL_DISPATCH_FILTER_BLOCK. Any other value should terminate the program with a SIGSYS. +Additionally, a tasks syscall user dispatch configuration can be peeked +and poked via the PTRACE_(GET|SET)_SYSCALL_USER_DISPATCH_CONFIG ptrace +requests. This is useful for checkpoint/restart software. + Security Notes -------------- diff --git a/include/linux/syscall_user_dispatch.h b/include/linux/syscall_user_dispatch.h index a0ae443..641ca88 100644 --- a/include/linux/syscall_user_dispatch.h +++ b/include/linux/syscall_user_dispatch.h @@ -22,6 +22,12 @@ int set_syscall_user_dispatch(unsigned long mode, unsigned long offset, #define clear_syscall_work_syscall_user_dispatch(tsk) \ clear_task_syscall_work(tsk, SYSCALL_USER_DISPATCH) +int syscall_user_dispatch_get_config(struct task_struct *task, unsigned long size, + void __user *data); + +int syscall_user_dispatch_set_config(struct task_struct *task, unsigned long size, + void __user *data); + #else struct syscall_user_dispatch {}; @@ -35,6 +41,18 @@ static inline void clear_syscall_work_syscall_user_dispatch(struct task_struct * { } +static inline int syscall_user_dispatch_get_config(struct task_struct *task, + unsigned long size, void __user *data) +{ + return -EINVAL; +} + +static inline int syscall_user_dispatch_set_config(struct task_struct *task, + unsigned long size, void __user *data) +{ + return -EINVAL; +} + #endif /* CONFIG_GENERIC_ENTRY */ #endif /* _SYSCALL_USER_DISPATCH_H */ diff --git a/include/uapi/linux/ptrace.h b/include/uapi/linux/ptrace.h index 195ae64..72c038f 100644 --- a/include/uapi/linux/ptrace.h +++ b/include/uapi/linux/ptrace.h @@ -112,6 +112,36 @@ struct ptrace_rseq_configuration { __u32 pad; }; +#define PTRACE_SET_SYSCALL_USER_DISPATCH_CONFIG 0x4210 +#define PTRACE_GET_SYSCALL_USER_DISPATCH_CONFIG 0x4211 + +/* + * struct ptrace_sud_config - Per-task configuration for Syscall User Dispatch + * @mode: One of PR_SYS_DISPATCH_ON or PR_SYS_DISPATCH_OFF + * @selector: Tracees user virtual address of SUD selector + * @offset: SUD exclusion area (virtual address) + * @len: Length of SUD exclusion area + * + * Used to get/set the syscall user dispatch configuration for a tracee. + * Selector is optional (may be NULL), and if invalid will produce + * a SIGSEGV in the tracee upon first access. + * + * If mode is PR_SYS_DISPATCH_ON, syscall dispatch will be enabled. If + * PR_SYS_DISPATCH_OFF, syscall dispatch will be disabled and all other + * parameters must be 0. The value in *selector (if not null), also determines + * whether syscall dispatch will occur. + * + * The Syscall User Dispatch Exclusion area described by offset/len is the + * virtual address space from which syscalls will not produce a user + * dispatch. + */ +struct ptrace_sud_config { + __u64 mode; + __u64 selector; + __u64 offset; + __u64 len; +}; + /* * These values are stored in task->ptrace_message * by ptrace_stop to describe the current syscall-stop. diff --git a/kernel/entry/syscall_user_dispatch.c b/kernel/entry/syscall_user_dispatch.c index 7f2add4..5340c5a 100644 --- a/kernel/entry/syscall_user_dispatch.c +++ b/kernel/entry/syscall_user_dispatch.c @@ -4,6 +4,7 @@ */ #include #include +#include #include #include #include @@ -122,3 +123,42 @@ int set_syscall_user_dispatch(unsigned long mode, unsigned long offset, { return task_set_syscall_user_dispatch(current, mode, offset, len, selector); } + +int syscall_user_dispatch_get_config(struct task_struct *task, unsigned long size, + void __user *data) +{ + struct syscall_user_dispatch *sd = &task->syscall_dispatch; + struct ptrace_sud_config cfg; + + if (size != sizeof(cfg)) + return -EINVAL; + + if (test_task_syscall_work(task, SYSCALL_USER_DISPATCH)) + cfg.mode = PR_SYS_DISPATCH_ON; + else + cfg.mode = PR_SYS_DISPATCH_OFF; + + cfg.offset = sd->offset; + cfg.len = sd->len; + cfg.selector = (__u64)(uintptr_t)sd->selector; + + if (copy_to_user(data, &cfg, sizeof(cfg))) + return -EFAULT; + + return 0; +} + +int syscall_user_dispatch_set_config(struct task_struct *task, unsigned long size, + void __user *data) +{ + struct ptrace_sud_config cfg; + + if (size != sizeof(cfg)) + return -EINVAL; + + if (copy_from_user(&cfg, data, sizeof(cfg))) + return -EFAULT; + + return task_set_syscall_user_dispatch(task, cfg.mode, cfg.offset, cfg.len, + (char __user *)(uintptr_t)cfg.selector); +} diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 0786450..443057b 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -32,6 +32,7 @@ #include #include #include +#include #include /* for syscall_get_* */ @@ -1259,6 +1260,14 @@ int ptrace_request(struct task_struct *child, long request, break; #endif + case PTRACE_SET_SYSCALL_USER_DISPATCH_CONFIG: + ret = syscall_user_dispatch_set_config(child, addr, datavp); + break; + + case PTRACE_GET_SYSCALL_USER_DISPATCH_CONFIG: + ret = syscall_user_dispatch_get_config(child, addr, datavp); + break; + default: break; }