Received: by 2002:a05:6a10:2726:0:0:0:0 with SMTP id ib38csp985535pxb; Wed, 6 Apr 2022 06:04:18 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxsxlsPt8AND96h270dJH3ruGr9pUCE4xCVvARQJZg78+w3AaQdkm8wCNvQjVlHDTN9kxOf X-Received: by 2002:a92:d704:0:b0:2c7:9ca5:3f5a with SMTP id m4-20020a92d704000000b002c79ca53f5amr3882121iln.190.1649250258589; Wed, 06 Apr 2022 06:04:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1649250258; cv=none; d=google.com; s=arc-20160816; b=WdtMi4SGoAgZwRFMhLh/ge3HEXX2fm65eDG1zGkFCok9DFL+aXudDy36PeVE0JMLrF M2lbgoVmRTy+2kNNW951x2LkqBbN2tFlX9NZ/Bu71U6kfpUa33UbvMuq16hVKV+TvUls O0k+Ydr23cS4dgvfZkClhw2tpwv4NqGXgxahWcgwJt9z0cdZYnZtZwlauOyuBiY4XtHb ve7L6vB+rC6pGXP611vi8/4tlXj9PL+RKZOoKlNrsvvmBjof8FoJKZ48HJkhizsDEXum eCwhy3plF/2oZfpOeV9rLeHDb+EMOD53Fee5YoinExaWr5ry/WtB6X8zHkk59LBmB4Y0 Geng== 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=b5MIxuukPn4diC7cKDwEr7v3mE1QTYfTPV2BbqDLDo8=; b=qgjR/Aj9ZasNKM7S60VN5qf+o3D8SmTEylpTjhvNqLVsZnDgO/t/7VcWvBdWs5VhyS uKaz1aCKqt8mg0ahbqPfM2XggObtOq7KNbL3iUu4KmWXnx2azZjIOcblzi56xrq4ZVTu hLYvArQSNFpt1Z+kH67n9iwF+b8Y4UDubGhq1s0rCEVhUryEiHjqZV5ScOsyk5wDOmZs rUDdMKg/SVdeGTKrsXmtjlNVUU4P5sAQ/tlOEtKq3V0LIrkz7zmAB4+KBvck322l2too NGjmhnjJfsrfYw4AiL8zCD8YT85/JRxHS+2Hf9AFIkCuEdXo/yW5DgIFysMK6sWK7tYj OOxw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=DOz1cXl2; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 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 lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id w134-20020a022a8c000000b00321237f463csi7734728jaw.162.2022.04.06.06.04.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Apr 2022 06:04:18 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) client-ip=2620:137:e000::1:18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=DOz1cXl2; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 8ACA36695D4; Wed, 6 Apr 2022 03:25:05 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1452683AbiDEWcP (ORCPT + 99 others); Tue, 5 Apr 2022 18:32:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36196 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1354448AbiDEKOQ (ORCPT ); Tue, 5 Apr 2022 06:14:16 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3F7906A00F; Tue, 5 Apr 2022 03:00:07 -0700 (PDT) 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 dfw.source.kernel.org (Postfix) with ESMTPS id AFA8861673; Tue, 5 Apr 2022 10:00:06 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B7F42C385A2; Tue, 5 Apr 2022 10:00:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1649152806; bh=fDZBkgfQJbLSlDY1z2xrIeM592mx6ZfxBOfycW6/WwU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DOz1cXl2/4EmmL5b9ykMcCgBTedlE65/UwZnyDBpZJLBcMzZxOy9BfVinN6LTHowm XBet6zPyCHP8y56758+c9j4KIWyha8avwN4QdDfKBU+3ZMiBM1guQQjDVOhXWichgQ 5XE91sjEPvs/fZ4C+X0eOWvCxvpSIW1iDM6e2p8o= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Marc Zyngier , Sven Schnelle , "Steven Rostedt (Google)" Subject: [PATCH 5.15 870/913] tracing: Have type enum modifications copy the strings Date: Tue, 5 Apr 2022 09:32:12 +0200 Message-Id: <20220405070405.902546505@linuxfoundation.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220405070339.801210740@linuxfoundation.org> References: <20220405070339.801210740@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=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=no 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 (Google) commit 795301d3c28996219d555023ac6863401b6076bc upstream. When an enum is used in the visible parts of a trace event that is exported to user space, the user space applications like perf and trace-cmd do not have a way to know what the value of the enum is. To solve this, at boot up (or module load) the printk formats are modified to replace the enum with their numeric value in the string output. Array fields of the event are defined by [] in the type portion of the format file so that the user space parsers can correctly parse the array into the appropriate size chunks. But in some trace events, an enum is used in defining the size of the array, which once again breaks the parsing of user space tooling. This was solved the same way as the print formats were, but it modified the type strings of the trace event. This caused crashes in some architectures because, as supposed to the print string, is a const string value. This was not detected on x86, as it appears that const strings are still writable (at least in boot up), but other architectures this is not the case, and writing to a const string will cause a kernel fault. To fix this, use kstrdup() to copy the type before modifying it. If the trace event is for the core kernel there's no need to free it because the string will be in use for the life of the machine being on line. For modules, create a link list to store all the strings being allocated for modules and when the module is removed, free them. Link: https://lore.kernel.org/all/yt9dr1706b4i.fsf@linux.ibm.com/ Link: https://lkml.kernel.org/r/20220318153432.3984b871@gandalf.local.home Tested-by: Marc Zyngier Tested-by: Sven Schnelle Reported-by: Sven Schnelle Fixes: b3bc8547d3be ("tracing: Have TRACE_DEFINE_ENUM affect trace event types as well") Signed-off-by: Steven Rostedt (Google) Signed-off-by: Greg Kroah-Hartman --- kernel/trace/trace_events.c | 62 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -40,6 +40,14 @@ static LIST_HEAD(ftrace_generic_fields); static LIST_HEAD(ftrace_common_fields); static bool eventdir_initialized; +static LIST_HEAD(module_strings); + +struct module_string { + struct list_head next; + struct module *module; + char *str; +}; + #define GFP_TRACE (GFP_KERNEL | __GFP_ZERO) static struct kmem_cache *field_cachep; @@ -2637,14 +2645,40 @@ static void update_event_printk(struct t } } +static void add_str_to_module(struct module *module, char *str) +{ + struct module_string *modstr; + + modstr = kmalloc(sizeof(*modstr), GFP_KERNEL); + + /* + * If we failed to allocate memory here, then we'll just + * let the str memory leak when the module is removed. + * If this fails to allocate, there's worse problems than + * a leaked string on module removal. + */ + if (WARN_ON_ONCE(!modstr)) + return; + + modstr->module = module; + modstr->str = str; + + list_add(&modstr->next, &module_strings); +} + static void update_event_fields(struct trace_event_call *call, struct trace_eval_map *map) { struct ftrace_event_field *field; struct list_head *head; char *ptr; + char *str; int len = strlen(map->eval_string); + /* Dynamic events should never have field maps */ + if (WARN_ON_ONCE(call->flags & TRACE_EVENT_FL_DYNAMIC)) + return; + head = trace_get_fields(call); list_for_each_entry(field, head, link) { ptr = strchr(field->type, '['); @@ -2658,9 +2692,26 @@ static void update_event_fields(struct t if (strncmp(map->eval_string, ptr, len) != 0) continue; + str = kstrdup(field->type, GFP_KERNEL); + if (WARN_ON_ONCE(!str)) + return; + ptr = str + (ptr - field->type); ptr = eval_replace(ptr, map, len); /* enum/sizeof string smaller than value */ - WARN_ON_ONCE(!ptr); + if (WARN_ON_ONCE(!ptr)) { + kfree(str); + continue; + } + + /* + * If the event is part of a module, then we need to free the string + * when the module is removed. Otherwise, it will stay allocated + * until a reboot. + */ + if (call->module) + add_str_to_module(call->module, str); + + field->type = str; } } @@ -2883,6 +2934,7 @@ static void trace_module_add_events(stru static void trace_module_remove_events(struct module *mod) { struct trace_event_call *call, *p; + struct module_string *modstr, *m; down_write(&trace_event_sem); list_for_each_entry_safe(call, p, &ftrace_events, list) { @@ -2891,6 +2943,14 @@ static void trace_module_remove_events(s if (call->module == mod) __trace_remove_event_call(call); } + /* Check for any strings allocade for this module */ + list_for_each_entry_safe(modstr, m, &module_strings, next) { + if (modstr->module != mod) + continue; + list_del(&modstr->next); + kfree(modstr->str); + kfree(modstr); + } up_write(&trace_event_sem); /*