Received: by 2002:a05:6a10:413:0:0:0:0 with SMTP id 19csp1797324pxp; Mon, 7 Mar 2022 02:34:01 -0800 (PST) X-Google-Smtp-Source: ABdhPJwk5ahEpAxFDGx7Oql+kXS9BERDVAH+rar2wdBVyR2cs4Dly67n4T5nC9nrQVdehYd/TkbC X-Received: by 2002:a05:6a00:228d:b0:4f6:4ea6:851f with SMTP id f13-20020a056a00228d00b004f64ea6851fmr12167679pfe.37.1646649240950; Mon, 07 Mar 2022 02:34:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1646649240; cv=none; d=google.com; s=arc-20160816; b=O6cfwsZamDdghTH/QqewP+jg8uXhQdHXV79sL5F/kFnd64QgRFOOPIEVSYdYLvn6+1 DT6Lb6eLNkve7PvfcteKkRyIru1BPi78Kj3F11oErDMbcdeeHOmm7Lmc9y72wZGNRWZS 8/JmwM+p21uJFgPQUpD3O3o9eMPa2WSAHJZRsIM3V4PKITNILgI3NJ8sn2ca6i2+T2nQ jNFpxnGyMBtFeDdr35lgwU2VHAdeV+dHKREQ1NxKKF4nm9P9wFRBfTdjFt+3CGim56Jw dHgP3WRhDuSoCyrdXAIQlD8y5WpmzCQ75az3i/rG6oKqZwUcdt2wnIyu8IMypA8SI5kQ UFoQ== 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 :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=ItVYYjNdaJ8etu8vr55WxXKNmrk3OOkhdlhtzpeFjwA=; b=p9aiErd52a4nDU0XjQZewTBjA2KI8E3MFJ5j/BEXarJltZHg9CmhYEjKKWBatRL/L6 7bPuhEoRcsGzQrtJg2L7gHKLhRiXNI6N/gUFjS9UESo9QbKDjzQ0OuvbqFgTlNnKVm+f rYPhUWURmdhEt0uRLnTz2en7ww1fICMqKElEdSvt/6yPvv8OWsR9XiNkJ3dh5jW0QspS Hmk0tDgafUrK5q3ykUiwl8rDuk25ut8DKGYoPGn/JFAe4JrcFohts207UH/TP1gklvFu t37fo+dKSPh2CGLjjlJU6U7XI4etAMSxkd7oAHglz6rQUFCPHvlVkymHH6a01nVTrfDH hXtg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=rjLeFdem; 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=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b10-20020a6541ca000000b0037ff6915ad0si7023990pgq.120.2022.03.07.02.33.46; Mon, 07 Mar 2022 02:34:00 -0800 (PST) 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=@linuxfoundation.org header.s=korg header.b=rjLeFdem; 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=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235610AbiCGKGk (ORCPT + 99 others); Mon, 7 Mar 2022 05:06:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57926 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238446AbiCGJqh (ORCPT ); Mon, 7 Mar 2022 04:46:37 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 54D40694A6; Mon, 7 Mar 2022 01:42:11 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 7A008B80E70; Mon, 7 Mar 2022 09:37:08 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id DF8B3C340E9; Mon, 7 Mar 2022 09:37:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1646645827; bh=H62Pa9TB5DcGbjeRngxOfMiTImh+GHsLdwD6eP3n3iw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rjLeFdemughK/SezbBlzaaaXHpkQxA3wzW+fzX2o82n2aUT2ck1bcumBHHIPYO7m7 xZNMHUtBJf+/Gi5YdkR2hSSvejEd75G0D65G5phJllsPhCLpAEdVOZRUfXZwdiNtq3 OOmCN6cGDY76S7RqX/PiR/4dWxxugkIkemYTkf+0= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Sven Schnelle , Steven Rostedt , Sasha Levin Subject: [PATCH 5.15 041/262] tracing: Add ustring operation to filtering string pointers Date: Mon, 7 Mar 2022 10:16:25 +0100 Message-Id: <20220307091703.683855708@linuxfoundation.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220307091702.378509770@linuxfoundation.org> References: <20220307091702.378509770@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,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 lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Steven Rostedt [ Upstream commit f37c3bbc635994eda203a6da4ba0f9d05165a8d6 ] Since referencing user space pointers is special, if the user wants to filter on a field that is a pointer to user space, then they need to specify it. Add a ".ustring" attribute to the field name for filters to state that the field is pointing to user space such that the kernel can take the appropriate action to read that pointer. Link: https://lore.kernel.org/all/yt9d8rvmt2jq.fsf@linux.ibm.com/ Fixes: 77360f9bbc7e ("tracing: Add test for user space strings when filtering on string pointers") Tested-by: Sven Schnelle Signed-off-by: Steven Rostedt Signed-off-by: Sasha Levin --- Documentation/trace/events.rst | 9 ++++ kernel/trace/trace_events_filter.c | 81 +++++++++++++++++++++--------- 2 files changed, 66 insertions(+), 24 deletions(-) diff --git a/Documentation/trace/events.rst b/Documentation/trace/events.rst index 45e66a60a816a..c47f381d0c002 100644 --- a/Documentation/trace/events.rst +++ b/Documentation/trace/events.rst @@ -198,6 +198,15 @@ The glob (~) accepts a wild card character (\*,?) and character classes prev_comm ~ "*sh*" prev_comm ~ "ba*sh" +If the field is a pointer that points into user space (for example +"filename" from sys_enter_openat), then you have to append ".ustring" to the +field name:: + + filename.ustring ~ "password" + +As the kernel will have to know how to retrieve the memory that the pointer +is at from user space. + 5.2 Setting filters ------------------- diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index d3eb3c630f601..06d6318ee5377 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -665,6 +665,23 @@ struct ustring_buffer { static __percpu struct ustring_buffer *ustring_per_cpu; static __always_inline char *test_string(char *str) +{ + struct ustring_buffer *ubuf; + char *kstr; + + if (!ustring_per_cpu) + return NULL; + + ubuf = this_cpu_ptr(ustring_per_cpu); + kstr = ubuf->buffer; + + /* For safety, do not trust the string pointer */ + if (!strncpy_from_kernel_nofault(kstr, str, USTRING_BUF_SIZE)) + return NULL; + return kstr; +} + +static __always_inline char *test_ustring(char *str) { struct ustring_buffer *ubuf; char __user *ustr; @@ -676,23 +693,11 @@ static __always_inline char *test_string(char *str) ubuf = this_cpu_ptr(ustring_per_cpu); kstr = ubuf->buffer; - /* - * We use TASK_SIZE to denote user or kernel space, but this will - * not work for all architectures. If it picks the wrong one, it may - * just fail the filter (but will not bug). - * - * TODO: Have a way to properly denote which one this is for. - */ - if (likely((unsigned long)str >= TASK_SIZE)) { - /* For safety, do not trust the string pointer */ - if (!strncpy_from_kernel_nofault(kstr, str, USTRING_BUF_SIZE)) - return NULL; - } else { - /* user space address? */ - ustr = (char __user *)str; - if (!strncpy_from_user_nofault(kstr, ustr, USTRING_BUF_SIZE)) - return NULL; - } + /* user space address? */ + ustr = (char __user *)str; + if (!strncpy_from_user_nofault(kstr, ustr, USTRING_BUF_SIZE)) + return NULL; + return kstr; } @@ -709,24 +714,42 @@ static int filter_pred_string(struct filter_pred *pred, void *event) return match; } +static __always_inline int filter_pchar(struct filter_pred *pred, char *str) +{ + int cmp, match; + int len; + + len = strlen(str) + 1; /* including tailing '\0' */ + cmp = pred->regex.match(str, &pred->regex, len); + + match = cmp ^ pred->not; + + return match; +} /* Filter predicate for char * pointers */ static int filter_pred_pchar(struct filter_pred *pred, void *event) { char **addr = (char **)(event + pred->offset); char *str; - int cmp, match; - int len; str = test_string(*addr); if (!str) return 0; - len = strlen(str) + 1; /* including tailing '\0' */ - cmp = pred->regex.match(str, &pred->regex, len); + return filter_pchar(pred, str); +} - match = cmp ^ pred->not; +/* Filter predicate for char * pointers in user space*/ +static int filter_pred_pchar_user(struct filter_pred *pred, void *event) +{ + char **addr = (char **)(event + pred->offset); + char *str; - return match; + str = test_ustring(*addr); + if (!str) + return 0; + + return filter_pchar(pred, str); } /* @@ -1206,6 +1229,7 @@ static int parse_pred(const char *str, void *data, struct filter_pred *pred = NULL; char num_buf[24]; /* Big enough to hold an address */ char *field_name; + bool ustring = false; char q; u64 val; int len; @@ -1240,6 +1264,12 @@ static int parse_pred(const char *str, void *data, return -EINVAL; } + /* See if the field is a user space string */ + if ((len = str_has_prefix(str + i, ".ustring"))) { + ustring = true; + i += len; + } + while (isspace(str[i])) i++; @@ -1377,7 +1407,10 @@ static int parse_pred(const char *str, void *data, goto err_mem; } - pred->fn = filter_pred_pchar; + if (ustring) + pred->fn = filter_pred_pchar_user; + else + pred->fn = filter_pred_pchar; } /* go past the last quote */ i++; -- 2.34.1