lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20230426171749.616376240@goodmis.org>
Date:   Wed, 26 Apr 2023 13:17:06 -0400
From:   Steven Rostedt <rostedt@...dmis.org>
To:     linux-kernel@...r.kernel.org
Cc:     Masami Hiramatsu <mhiramat@...nel.org>,
        Mark Rutland <mark.rutland@....com>,
        Andrew Morton <akpm@...ux-foundation.org>,
        Doug Cook <dcook@...ux.microsoft.com>,
        Beau Belgrave <beaub@...ux.microsoft.com>
Subject: [for-next][PATCH 03/11] tracing: Fix print_fields() for __dyn_loc/__rel_loc

From: Beau Belgrave <beaub@...ux.microsoft.com>

Both print_fields() and print_array() do not handle if dynamic data ends
at the last byte of the payload for both __dyn_loc and __rel_loc field
types. For __rel_loc, the offset was off by 4 bytes, leading to
incorrect strings and data being printed out. In print_array() the
buffer pos was missed from being advanced, which results in the first
payload byte being used as the offset base instead of the field offset.

Advance __rel_loc offset by 4 to ensure correct offset and advance pos
to the field offset to ensure correct data is displayed when printing
arrays. Change >= to > when checking if data is in-bounds, since it's
valid for dynamic data to include the last byte of the payload.

Example outputs for event format:
        field:unsigned short common_type;       offset:0;       size:2; signed:0;
        field:unsigned char common_flags;       offset:2;       size:1; signed:0;
        field:unsigned char common_preempt_count;       offset:3;       size:1; signed:0;
        field:int common_pid;   offset:4;       size:4; signed:1;

        field:__rel_loc char text[];  offset:8;      size:4; signed:1;

Output before:
tp_rel_loc: text=<OVERFLOW>

Output after:
tp_rel_loc: text=Test

Link: https://lkml.kernel.org/r/20230419214140.4158-3-beaub@linux.microsoft.com

Fixes: 80a76994b2d8 ("tracing: Add "fields" option to show raw trace event fields")
Reported-by: Doug Cook <dcook@...ux.microsoft.com>
Signed-off-by: Beau Belgrave <beaub@...ux.microsoft.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@...dmis.org>
---
 kernel/trace/trace_output.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index 780c6971c944..952cc8aa8e59 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -819,13 +819,15 @@ static void print_array(struct trace_iterator *iter, void *pos,
 	len = *(int *)pos >> 16;
 
 	if (field)
-		offset += field->offset;
+		offset += field->offset + sizeof(int);
 
-	if (offset + len >= iter->ent_size) {
+	if (offset + len > iter->ent_size) {
 		trace_seq_puts(&iter->seq, "<OVERFLOW>");
 		return;
 	}
 
+	pos = (void *)iter->ent + offset;
+
 	for (i = 0; i < len; i++, pos++) {
 		if (i)
 			trace_seq_putc(&iter->seq, ',');
@@ -861,9 +863,9 @@ static void print_fields(struct trace_iterator *iter, struct trace_event_call *c
 			len = *(int *)pos >> 16;
 
 			if (field->filter_type == FILTER_RDYN_STRING)
-				offset += field->offset;
+				offset += field->offset + sizeof(int);
 
-			if (offset + len >= iter->ent_size) {
+			if (offset + len > iter->ent_size) {
 				trace_seq_puts(&iter->seq, "<OVERFLOW>");
 				break;
 			}
-- 
2.39.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ