Skip to content

Commit bcba8d4

Browse files
committed
ring-buffer: Use kaslr address instead of text delta
Instead of saving off the text and data pointers and using them to compare with the current boot's text and data pointers, just save off the KASLR offset. Then that can be used to figure out how to read the previous boots buffer. The last_boot_info will now show this offset, but only if it is for a previous boot: ~# cat instances/boot_mapped/last_boot_info 39000000 [kernel] ~# echo function > instances/boot_mapped/current_tracer ~# cat instances/boot_mapped/last_boot_info # Current If the KASLR offset saved is for the current boot, the last_boot_info will show the value of "current". Cc: Mark Rutland <[email protected]> Cc: Mathieu Desnoyers <[email protected]> Cc: Andrew Morton <[email protected]> Link: https://lore.kernel.org/[email protected] Reviewed-by: Masami Hiramatsu (Google) <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent c73f0b6 commit bcba8d4

File tree

4 files changed

+39
-34
lines changed

4 files changed

+39
-34
lines changed

include/linux/ring_buffer.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,7 @@ struct trace_buffer *__ring_buffer_alloc_range(unsigned long size, unsigned flag
9494
unsigned long range_size,
9595
struct lock_class_key *key);
9696

97-
bool ring_buffer_last_boot_delta(struct trace_buffer *buffer, long *text,
98-
long *data);
97+
bool ring_buffer_last_boot_delta(struct trace_buffer *buffer, unsigned long *kaslr_addr);
9998

10099
/*
101100
* Because the ring buffer is generic, if other users of the ring buffer get

kernel/trace/ring_buffer.c

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
#include <asm/local64.h>
3333
#include <asm/local.h>
34+
#include <asm/setup.h>
3435

3536
#include "trace.h"
3637

@@ -49,8 +50,7 @@ static void update_pages_handler(struct work_struct *work);
4950
struct ring_buffer_meta {
5051
int magic;
5152
int struct_size;
52-
unsigned long text_addr;
53-
unsigned long data_addr;
53+
unsigned long kaslr_addr;
5454
unsigned long first_buffer;
5555
unsigned long head_buffer;
5656
unsigned long commit_buffer;
@@ -550,8 +550,7 @@ struct trace_buffer {
550550
unsigned long range_addr_start;
551551
unsigned long range_addr_end;
552552

553-
long last_text_delta;
554-
long last_data_delta;
553+
unsigned long kaslr_addr;
555554

556555
unsigned int subbuf_size;
557556
unsigned int subbuf_order;
@@ -1891,16 +1890,13 @@ static void rb_meta_validate_events(struct ring_buffer_per_cpu *cpu_buffer)
18911890
}
18921891
}
18931892

1894-
/* Used to calculate data delta */
1895-
static char rb_data_ptr[] = "";
1896-
1897-
#define THIS_TEXT_PTR ((unsigned long)rb_meta_init_text_addr)
1898-
#define THIS_DATA_PTR ((unsigned long)rb_data_ptr)
1899-
19001893
static void rb_meta_init_text_addr(struct ring_buffer_meta *meta)
19011894
{
1902-
meta->text_addr = THIS_TEXT_PTR;
1903-
meta->data_addr = THIS_DATA_PTR;
1895+
#ifdef CONFIG_RANDOMIZE_BASE
1896+
meta->kaslr_addr = kaslr_offset();
1897+
#else
1898+
meta->kaslr_addr = 0;
1899+
#endif
19041900
}
19051901

19061902
static void rb_range_meta_init(struct trace_buffer *buffer, int nr_pages)
@@ -1928,8 +1924,7 @@ static void rb_range_meta_init(struct trace_buffer *buffer, int nr_pages)
19281924
meta->first_buffer += delta;
19291925
meta->head_buffer += delta;
19301926
meta->commit_buffer += delta;
1931-
buffer->last_text_delta = THIS_TEXT_PTR - meta->text_addr;
1932-
buffer->last_data_delta = THIS_DATA_PTR - meta->data_addr;
1927+
buffer->kaslr_addr = meta->kaslr_addr;
19331928
continue;
19341929
}
19351930

@@ -2482,17 +2477,15 @@ struct trace_buffer *__ring_buffer_alloc_range(unsigned long size, unsigned flag
24822477
*
24832478
* Returns: The true if the delta is non zero
24842479
*/
2485-
bool ring_buffer_last_boot_delta(struct trace_buffer *buffer, long *text,
2486-
long *data)
2480+
bool ring_buffer_last_boot_delta(struct trace_buffer *buffer, unsigned long *kaslr_addr)
24872481
{
24882482
if (!buffer)
24892483
return false;
24902484

2491-
if (!buffer->last_text_delta)
2485+
if (!buffer->kaslr_addr)
24922486
return false;
24932487

2494-
*text = buffer->last_text_delta;
2495-
*data = buffer->last_data_delta;
2488+
*kaslr_addr = buffer->kaslr_addr;
24962489

24972490
return true;
24982491
}

kernel/trace/trace.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
#include <linux/irq_work.h>
5151
#include <linux/workqueue.h>
5252

53-
#include <asm/setup.h> /* COMMAND_LINE_SIZE */
53+
#include <asm/setup.h> /* COMMAND_LINE_SIZE and kaslr_offset() */
5454

5555
#include "trace.h"
5656
#include "trace_output.h"
@@ -4193,7 +4193,7 @@ static enum print_line_t print_trace_fmt(struct trace_iterator *iter)
41934193
* safe to use if the array has delta offsets
41944194
* Force printing via the fields.
41954195
*/
4196-
if ((tr->text_delta || tr->data_delta) &&
4196+
if ((tr->text_delta) &&
41974197
event->type > __TRACE_LAST_TYPE)
41984198
return print_event_fields(iter, event);
41994199

@@ -5990,7 +5990,7 @@ ssize_t tracing_resize_ring_buffer(struct trace_array *tr,
59905990

59915991
static void update_last_data(struct trace_array *tr)
59925992
{
5993-
if (!tr->text_delta && !tr->data_delta)
5993+
if (!(tr->flags & TRACE_ARRAY_FL_LAST_BOOT))
59945994
return;
59955995

59965996
/*
@@ -6003,7 +6003,8 @@ static void update_last_data(struct trace_array *tr)
60036003

60046004
/* Using current data now */
60056005
tr->text_delta = 0;
6006-
tr->data_delta = 0;
6006+
6007+
tr->flags &= ~TRACE_ARRAY_FL_LAST_BOOT;
60076008
}
60086009

60096010
/**
@@ -6821,8 +6822,17 @@ tracing_last_boot_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t
68216822

68226823
seq_buf_init(&seq, buf, 64);
68236824

6824-
seq_buf_printf(&seq, "text delta:\t%ld\n", tr->text_delta);
6825-
seq_buf_printf(&seq, "data delta:\t%ld\n", tr->data_delta);
6825+
/*
6826+
* Do not leak KASLR address. This only shows the KASLR address of
6827+
* the last boot. When the ring buffer is started, the LAST_BOOT
6828+
* flag gets cleared, and this should only report "current".
6829+
* Otherwise it shows the KASLR address from the previous boot which
6830+
* should not be the same as the current boot.
6831+
*/
6832+
if (tr->flags & TRACE_ARRAY_FL_LAST_BOOT)
6833+
seq_buf_printf(&seq, "%lx\t[kernel]\n", tr->kaslr_addr);
6834+
else
6835+
seq_buf_puts(&seq, "# Current\n");
68266836

68276837
return simple_read_from_buffer(ubuf, cnt, ppos, buf, seq_buf_used(&seq));
68286838
}
@@ -9210,8 +9220,10 @@ allocate_trace_buffer(struct trace_array *tr, struct array_buffer *buf, int size
92109220
tr->range_addr_start,
92119221
tr->range_addr_size);
92129222

9213-
ring_buffer_last_boot_delta(buf->buffer,
9214-
&tr->text_delta, &tr->data_delta);
9223+
#ifdef CONFIG_RANDOMIZE_BASE
9224+
if (ring_buffer_last_boot_delta(buf->buffer, &tr->kaslr_addr))
9225+
tr->text_delta = kaslr_offset() - tr->kaslr_addr;
9226+
#endif
92159227
/*
92169228
* This is basically the same as a mapped buffer,
92179229
* with the same restrictions.
@@ -10459,7 +10471,7 @@ __init static void enable_instances(void)
1045910471
* to it.
1046010472
*/
1046110473
if (start) {
10462-
tr->flags |= TRACE_ARRAY_FL_BOOT;
10474+
tr->flags |= TRACE_ARRAY_FL_BOOT | TRACE_ARRAY_FL_LAST_BOOT;
1046310475
tr->ref++;
1046410476
}
1046510477

kernel/trace/trace.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,8 @@ struct trace_array {
348348
unsigned int mapped;
349349
unsigned long range_addr_start;
350350
unsigned long range_addr_size;
351+
unsigned long kaslr_addr;
351352
long text_delta;
352-
long data_delta;
353353

354354
struct trace_pid_list __rcu *filtered_pids;
355355
struct trace_pid_list __rcu *filtered_no_pids;
@@ -433,9 +433,10 @@ struct trace_array {
433433
};
434434

435435
enum {
436-
TRACE_ARRAY_FL_GLOBAL = BIT(0),
437-
TRACE_ARRAY_FL_BOOT = BIT(1),
438-
TRACE_ARRAY_FL_MOD_INIT = BIT(2),
436+
TRACE_ARRAY_FL_GLOBAL = BIT(0),
437+
TRACE_ARRAY_FL_BOOT = BIT(1),
438+
TRACE_ARRAY_FL_LAST_BOOT = BIT(2),
439+
TRACE_ARRAY_FL_MOD_INIT = BIT(3),
439440
};
440441

441442
#ifdef CONFIG_MODULES

0 commit comments

Comments
 (0)