From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D89A62744F for ; Wed, 29 Jul 2026 00:05:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785283524; cv=none; b=iNAzwk1x32vXCDoc9xqLznPxsKejKtrHyq2hB4+p4Azn4dWMkqXcaLok7XgvxifADKPvDl2C6C5phudWpIzyHPdvVXzODAC8UIwKsDulQ/rchkKDtSMwpjw3KhJwAVdT7YkASfAAnJUiF8IXHfyxdQULdSZ+HM46EsrLB60d3KQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785283524; c=relaxed/simple; bh=BuwkhOu9AyA9TkJtCD1B7McB+/0BCpq3CLCMmsaYbaA=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=P5e25Hzn20Es9T1s535ghOcFGY+nmVCcyZKl8z1VSWRS9Nj507HcJvWyYBL7u9wG44UBIjrg2EA6BV91CHMN37Rsw2mV9Oseys3gjypSBg9clO4oDJG89YcW/PZ3vzMUcz+3YTAdAFr6GC1QcXvytk7kp+PI8ZjZ0sS7nyl2TyA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Qp440KWu; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Qp440KWu" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F02381F00ACF; Wed, 29 Jul 2026 00:05:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1785283522; bh=MHiRnUGcjJ6cExOoynXq0enLnjXBYFENcCehl40DMnQ=; h=Date:From:To:Cc:Subject:References; b=Qp440KWuMz4gSfTVKaVLvdE9FcqxEkDqM8G/XP3GsZT3xZiCdg9bVLWtri7JG0ck4 OpzD7OZ9r9KNUS86Y6bdRom+y2A8ynFQSmO56Otfh/teqRVWKhfoFX2rT3dqRu2Md6 fxKscLMITKWCga9HjL7zizzpCJ2724LWGwfdh647vkdthyIn2vxVOw8XKpr73zc9B4 CAsTE5OgdwuZgvqa006OIUQpZiOBTkySZDGvB0OTGRjOlSAiTmqFG1sppp1X5AMbUW O1Jvfro2G3goLmHWbeUd4fxTyYyW4j3UHhfTfS51UpwowGaYDz3t3Wf/XIn4YLD9VR WNHrNQYCSoSWw== Received: from rostedt by gandalf with local (Exim 4.99.4) (envelope-from ) id 1woro4-00000006Udg-2Ypl; Tue, 28 Jul 2026 20:05:56 -0400 Message-ID: <20260729000556.468637730@kernel.org> User-Agent: quilt/0.69 Date: Tue, 28 Jul 2026 20:05:31 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Pengpeng Hou Subject: [for-next][PATCH 08/16] tracing: Bound histogram expression strings with seq_buf References: <20260729000523.093060274@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 From: Pengpeng Hou expr_str() allocates a fixed MAX_FILTER_STR_VAL buffer and then builds expression names with a series of raw strcat() appends. Nested operands, constants, field flags, and generated field names can push the rendered string past that fixed limit before the name is attached to the hist field. Build expression strings with seq_buf and return -E2BIG when the rendered name would exceed MAX_FILTER_STR_VAL. This keeps the existing tracing-side limit while replacing the raw append logic with bounded construction. Link: https://patch.msgid.link/20260611055945.22348-4-pengpeng@iscas.ac.cn Signed-off-by: Pengpeng Hou Signed-off-by: Steven Rostedt --- kernel/trace/trace_events_hist.c | 57 ++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index dee2710da66e..893bd8b0e48a 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -94,7 +94,6 @@ typedef u64 (*hist_field_fn_t) (struct hist_field *field, #define HIST_FIELD_OPERANDS_MAX 2 #define HIST_FIELDS_MAX (TRACING_MAP_FIELDS_MAX + TRACING_MAP_VARS_MAX) #define HIST_ACTIONS_MAX 8 -#define HIST_CONST_DIGITS_MAX 21 #define HIST_DIV_SHIFT 20 /* For optimizing division by constants */ enum field_op_id { @@ -1733,33 +1732,36 @@ static const char *get_hist_field_flags(struct hist_field *hist_field) return flags_str; } -static void expr_field_str(struct hist_field *field, char *expr) +static bool expr_field_str(struct hist_field *field, struct seq_buf *s) { + const char *field_name; + if (field->flags & HIST_FIELD_FL_VAR_REF) { if (!field->system) - strcat(expr, "$"); - } else if (field->flags & HIST_FIELD_FL_CONST) { - char str[HIST_CONST_DIGITS_MAX]; + seq_buf_putc(s, '$'); + } else if (field->flags & HIST_FIELD_FL_CONST) + seq_buf_printf(s, "%llu", field->constant); - snprintf(str, HIST_CONST_DIGITS_MAX, "%llu", field->constant); - strcat(expr, str); - } + field_name = hist_field_name(field, 0); + if (!field_name) + return false; - strcat(expr, hist_field_name(field, 0)); + seq_buf_puts(s, field_name); if (field->flags && !(field->flags & HIST_FIELD_FL_VAR_REF)) { const char *flags_str = get_hist_field_flags(field); - if (flags_str) { - strcat(expr, "."); - strcat(expr, flags_str); - } + if (flags_str) + seq_buf_printf(s, ".%s", flags_str); } + + return !seq_buf_has_overflowed(s); } static char *expr_str(struct hist_field *field, unsigned int level) { char *expr __free(kfree) = NULL; + struct seq_buf s; if (level > 1) return ERR_PTR(-EINVAL); @@ -1768,47 +1770,54 @@ static char *expr_str(struct hist_field *field, unsigned int level) if (!expr) return ERR_PTR(-ENOMEM); + seq_buf_init(&s, expr, MAX_FILTER_STR_VAL); + if (!field->operands[0]) { - expr_field_str(field, expr); + if (!expr_field_str(field, &s)) + return ERR_PTR(-E2BIG); + return_ptr(expr); } if (field->operator == FIELD_OP_UNARY_MINUS) { char *subexpr; - strcat(expr, "-("); subexpr = expr_str(field->operands[0], ++level); if (IS_ERR(subexpr)) return subexpr; - strcat(expr, subexpr); - strcat(expr, ")"); - + seq_buf_printf(&s, "-(%s)", subexpr); kfree(subexpr); + if (seq_buf_has_overflowed(&s)) + return ERR_PTR(-E2BIG); + return_ptr(expr); } - expr_field_str(field->operands[0], expr); + if (!expr_field_str(field->operands[0], &s)) + return ERR_PTR(-E2BIG); switch (field->operator) { case FIELD_OP_MINUS: - strcat(expr, "-"); + seq_buf_putc(&s, '-'); break; case FIELD_OP_PLUS: - strcat(expr, "+"); + seq_buf_putc(&s, '+'); break; case FIELD_OP_DIV: - strcat(expr, "/"); + seq_buf_putc(&s, '/'); break; case FIELD_OP_MULT: - strcat(expr, "*"); + seq_buf_putc(&s, '*'); break; default: return ERR_PTR(-EINVAL); } - expr_field_str(field->operands[1], expr); + if (seq_buf_has_overflowed(&s) || + !expr_field_str(field->operands[1], &s)) + return ERR_PTR(-E2BIG); return_ptr(expr); } -- 2.53.0