Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tools lib traceevent: Handle new pointer processing of bprint strings

The Linux kernel printf() has some extended use cases that dereference
the pointer. This is dangerouse for tracing because the pointer that is
dereferenced can change or even be unmapped. It also causes issues when
the trace data is extracted, because user space does not have access to
the contents of the pointer even if it still exists.

To handle this, the kernel was updated to process these dereferenced
pointers at the time they are recorded, and not post processed. Now they
exist in the tracing buffer, and no dereference is needed at the time of
reading the trace.

The event parsing library needs to handle this new case.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Link: http://lkml.kernel.org/r/20180112004822.403349289@goodmis.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Steven Rostedt (VMware) and committed by
Arnaldo Carvalho de Melo
37db96bb 38d70b7c

+26
+26
tools/lib/traceevent/event-parse.c
··· 4300 4300 goto process_again; 4301 4301 case 'p': 4302 4302 ls = 1; 4303 + if (isalnum(ptr[1])) { 4304 + ptr++; 4305 + /* Check for special pointers */ 4306 + switch (*ptr) { 4307 + case 's': 4308 + case 'S': 4309 + case 'f': 4310 + case 'F': 4311 + break; 4312 + default: 4313 + /* 4314 + * Older kernels do not process 4315 + * dereferenced pointers. 4316 + * Only process if the pointer 4317 + * value is a printable. 4318 + */ 4319 + if (isprint(*(char *)bptr)) 4320 + goto process_string; 4321 + } 4322 + } 4303 4323 /* fall through */ 4304 4324 case 'd': 4305 4325 case 'u': ··· 4372 4352 4373 4353 break; 4374 4354 case 's': 4355 + process_string: 4375 4356 arg = alloc_arg(); 4376 4357 if (!arg) { 4377 4358 do_warning_event(event, "%s(%d): not enough memory!", ··· 4979 4958 4980 4959 if (isalnum(ptr[1])) 4981 4960 ptr++; 4961 + 4962 + if (arg->type == PRINT_BSTRING) { 4963 + trace_seq_puts(s, arg->string.string); 4964 + break; 4965 + } 4982 4966 4983 4967 if (*ptr == 'F' || *ptr == 'f' || 4984 4968 *ptr == 'S' || *ptr == 's') {