From patchwork Tue Apr 11 21:17:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Beau Belgrave X-Patchwork-Id: 82195 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2869235vqo; Tue, 11 Apr 2023 14:35:21 -0700 (PDT) X-Google-Smtp-Source: AKy350bZWh3x23RhASucbQF6QhYDzGSyM5WqrC9iEBcpjk6UYZXh1wTv8Ij56g1De1sAfIQgLbOy X-Received: by 2002:a17:902:e846:b0:199:4be8:be48 with SMTP id t6-20020a170902e84600b001994be8be48mr631044plg.19.1681248921359; Tue, 11 Apr 2023 14:35:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1681248921; cv=none; d=google.com; s=arc-20160816; b=TsI6hM2I5if0aqxGaVNOtz50XPy56yiSuVgGMVEDXtruHjqYFgIu217jF5x+j+2v9e JP6U5ZVP/2Q5mNHFUPuSajhElPRWWKXg9ZRb0w9YK8TXWfwX0VJR8Hw4YPlEOwlKeS7I hXHXNTjLGyHJFAkLuQMdF/EknW199A40rHHTIqpy+LeS0J4MYspZZOMAle5GmUWOEyPO j0lJN3ubz3z1RMrihoU7D/f3EDPUwLWEPh1yk7CH5B8oX5VpnKoR7Ann12c77KPxo8Uu CVZb3PTtK9PAHjpOviQULEsZQTD+NdNIJPgtqy7jWKrTqwvYXusrZHTbSCtk1aHwm2C1 qt6g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:dkim-filter; bh=5c4d3BEotzSKMJMtgcr0S62whYX8qPpisF7gsoBkDkw=; b=TVOqfTgJnr1fEzGV/lQo96T+rsa4w0uuIAKpw+ktMij+dtx/1iybrdY/bMpHhb7QDd dYHy7y+WsajD43CkdhHetU/QmBW2mZLuQ7QRYHE1UEiW8V+Rp2O+JCJoD+6Xnep09Vbj m2Bwgnia63BEiivNDSwxEgjLlMmrbLvBR/mWgaYUOIdfw+iNVlsWhBE1P0xqe+TEtIgK RXWC7krhD1vxk6qkM9W7tcjS5S7yIkX7Kd3aE9lyxbVWHxrxr5g3Q3z2TxOyJsOvdwG1 rxNMzUNYV3FomId0Qc6UfbAJvD6PC6ggloDJ6JHQUijPyz1zeEHZmjZzaFEm+1y4Ak0C k1+w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.microsoft.com header.s=default header.b=WkUcKuIB; 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=NONE dis=NONE) header.from=linux.microsoft.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id x6-20020a170902b40600b00194a5108613si14484584plr.177.2023.04.11.14.35.07; Tue, 11 Apr 2023 14:35:21 -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=@linux.microsoft.com header.s=default header.b=WkUcKuIB; 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=NONE dis=NONE) header.from=linux.microsoft.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229811AbjDKVRZ (ORCPT + 99 others); Tue, 11 Apr 2023 17:17:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38740 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229752AbjDKVRR (ORCPT ); Tue, 11 Apr 2023 17:17:17 -0400 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 3C7CF449A; Tue, 11 Apr 2023 14:17:16 -0700 (PDT) Received: from W11-BEAU-MD.localdomain (unknown [76.135.27.212]) by linux.microsoft.com (Postfix) with ESMTPSA id 9C6E521779A8; Tue, 11 Apr 2023 14:17:15 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 9C6E521779A8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1681247835; bh=5c4d3BEotzSKMJMtgcr0S62whYX8qPpisF7gsoBkDkw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WkUcKuIBuTCbVj31WezZoCtuMd/DBX5L//tgE+SDhh9YZhmSUfXIp6LevIyc30PV1 T0DSgumpETd3O1BwU6FNAFnmC3gZnZ7xWCEUdhzF6bs9XsxfGnhCmz7+kTq0aXtn84 B+7D/Q5CLdiHg+Q9QKQ1Emd7lEfInE8R81jTrVjc= From: Beau Belgrave To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, dcook@linux.microsoft.com, alanau@linux.microsoft.com Cc: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Subject: [PATCH 3/3] tracing/user_events: Prevent same address and bit per process Date: Tue, 11 Apr 2023 14:17:09 -0700 Message-Id: <20230411211709.15018-4-beaub@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230411211709.15018-1-beaub@linux.microsoft.com> References: <20230411211709.15018-1-beaub@linux.microsoft.com> MIME-Version: 1.0 X-Spam-Status: No, score=-19.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,ENV_AND_HDR_SPF_MATCH,RCVD_IN_DNSWL_MED, SPF_HELO_PASS,SPF_PASS,USER_IN_DEF_DKIM_WL,USER_IN_DEF_SPF_WL 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?1762917268929018414?= X-GMAIL-MSGID: =?utf-8?q?1762917268929018414?= User processes register an address and bit pair for events. If the same address and bit pair are registered multiple times in the same process, it can cause undefined behavior when events are enabled/disabled. When more than one are used, the bit could be turned off by another event being disabled, while the original event is still enabled. Prevent undefined behavior by checking the current mm to see if any event has already been registered for the address and bit pair. Return EADDRINUSE back to the user process if it's already being used. Update ftrace self-test to ensure this occurs properly. Suggested-by: Doug Cook Signed-off-by: Beau Belgrave --- kernel/trace/trace_events_user.c | 40 +++++++++++++++++++ .../selftests/user_events/ftrace_test.c | 9 ++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c index eb195d697177..ce5357019113 100644 --- a/kernel/trace/trace_events_user.c +++ b/kernel/trace/trace_events_user.c @@ -419,6 +419,20 @@ static int user_event_enabler_write(struct user_event_mm *mm, return 0; } +static bool user_event_enabler_exists(struct user_event_mm *mm, + unsigned long uaddr, unsigned char bit) +{ + struct user_event_enabler *enabler; + struct user_event_enabler *next; + + list_for_each_entry_safe(enabler, next, &mm->enablers, link) + if (enabler->addr == uaddr && + (enabler->values & ENABLE_VAL_BIT_MASK) == bit) + return true; + + return false; +} + static void user_event_enabler_update(struct user_event *user) { struct user_event_enabler *enabler; @@ -657,6 +671,22 @@ void user_event_mm_dup(struct task_struct *t, struct user_event_mm *old_mm) user_event_mm_remove(t); } +static bool current_user_event_enabler_exists(unsigned long uaddr, + unsigned char bit) +{ + struct user_event_mm *user_mm = current_user_event_mm(); + bool exists; + + if (!user_mm) + return false; + + exists = user_event_enabler_exists(user_mm, uaddr, bit); + + user_event_mm_put(user_mm); + + return exists; +} + static struct user_event_enabler *user_event_enabler_create(struct user_reg *reg, struct user_event *user, int *write_result) @@ -2045,6 +2075,16 @@ static long user_events_ioctl_reg(struct user_event_file_info *info, if (ret) return ret; + /* + * Prevent users from using the same address and bit multiple times + * within the same mm address space. This can cause unexpected behavior + * for user processes that is far easier to debug if this is explictly + * an error upon registering. + */ + if (current_user_event_enabler_exists((unsigned long)reg.enable_addr, + reg.enable_bit)) + return -EADDRINUSE; + name = strndup_user((const char __user *)(uintptr_t)reg.name_args, MAX_EVENT_DESC); diff --git a/tools/testing/selftests/user_events/ftrace_test.c b/tools/testing/selftests/user_events/ftrace_test.c index 91272f9d6fce..7c99cef94a65 100644 --- a/tools/testing/selftests/user_events/ftrace_test.c +++ b/tools/testing/selftests/user_events/ftrace_test.c @@ -219,7 +219,12 @@ TEST_F(user, register_events) { ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, ®)); ASSERT_EQ(0, reg.write_index); - /* Multiple registers should result in same index */ + /* Multiple registers to the same addr + bit should fail */ + ASSERT_EQ(-1, ioctl(self->data_fd, DIAG_IOCSREG, ®)); + ASSERT_EQ(EADDRINUSE, errno); + + /* Multiple registers to same name should result in same index */ + reg.enable_bit = 30; ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, ®)); ASSERT_EQ(0, reg.write_index); @@ -242,6 +247,8 @@ TEST_F(user, register_events) { /* Unregister */ ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSUNREG, &unreg)); + unreg.disable_bit = 30; + ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSUNREG, &unreg)); /* Delete should work only after close and unregister */ close(self->data_fd);