Pull perf fixes from Ingo Molnar: "Misc fixlets" * 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: perf: Fix error return code ftrace: Fix strncpy() use, use strlcpy() instead of strncpy() perf: Fix strncpy() use, use strlcpy() instead of strncpy() perf: Fix strncpy() use, always make sure it's NUL terminated perf: Fix ring_buffer perf_output_space() boundary calculation perf/x86: Fix uninitialized pt_regs in intel_pmu_drain_bts_buffer()
Unified · Split
| @@ -314,10 +314,11 @@ int intel_pmu_drain_bts_buffer(void) · 313 unmodified lines | ||
| 314 | 314 | if (top <= at) |
| 315 | 315 | return 0; |
| 316 | 316 | |
| 317 | + memset(®s, 0, sizeof(regs)); | |
| 318 | + | |
| 317 | 319 | ds->bts_index = ds->bts_buffer_base; |
| 318 | 320 | |
| 319 | 321 | perf_sample_data_init(&data, 0, event->hw.last_period); |
| 320 | − regs.ip = 0; | |
| 321 | 322 | |
| 322 | 323 | /* |
| 323 | 324 | * Prepare a generic sample, i.e. fill in the invariant fields. |
| @@ -4737,7 +4737,8 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) · 4736 unmodified lines | ||
| 4737 | 4737 | } else { |
| 4738 | 4738 | if (arch_vma_name(mmap_event->vma)) { |
| 4739 | 4739 | name = strncpy(tmp, arch_vma_name(mmap_event->vma), |
| 4740 | − sizeof(tmp)); | |
| 4740 | + sizeof(tmp) - 1); | |
| 4741 | + tmp[sizeof(tmp) - 1] = '\0'; | |
| 4741 | 4742 | goto got_name; |
| 4742 | 4743 | } |
| 4743 | 4744 | |
| @@ -5986,6 +5987,7 @@ skip_type: · 1242 unmodified lines | ||
| 5986 | 5987 | if (pmu->pmu_cpu_context) |
| 5987 | 5988 | goto got_cpu_context; |
| 5988 | 5989 | |
| 5990 | + ret = -ENOMEM; | |
| 5989 | 5991 | pmu->pmu_cpu_context = alloc_percpu(struct perf_cpu_context); |
| 5990 | 5992 | if (!pmu->pmu_cpu_context) |
| 5991 | 5993 | goto free_dev; |
| @@ -16,7 +16,7 @@ struct ring_buffer { · 15 unmodified lines | ||
| 16 | 16 | int page_order; /* allocation order */ |
| 17 | 17 | #endif |
| 18 | 18 | int nr_pages; /* nr of data pages */ |
| 19 | − int writable; /* are we writable */ | |
| 19 | + int overwrite; /* can overwrite itself */ | |
| 20 | 20 | |
| 21 | 21 | atomic_t poll; /* POLL_ for wakeups */ |
| 22 | 22 | |
| @@ -18,12 +18,24 @@ · 17 unmodified lines | ||
| 18 | 18 | static bool perf_output_space(struct ring_buffer *rb, unsigned long tail, |
| 19 | 19 | unsigned long offset, unsigned long head) |
| 20 | 20 | { |
| 21 | − unsigned long mask; | |
| 21 | + unsigned long sz = perf_data_size(rb); | |
| 22 | + unsigned long mask = sz - 1; | |
| 22 | 23 | |
| 23 | − if (!rb->writable) | |
| 24 | + /* | |
| 25 | + * check if user-writable | |
| 26 | + * overwrite : over-write its own tail | |
| 27 | + * !overwrite: buffer possibly drops events. | |
| 28 | + */ | |
| 29 | + if (rb->overwrite) | |
| 24 | 30 | return true; |
| 25 | 31 | |
| 26 | − mask = perf_data_size(rb) - 1; | |
| 32 | + /* | |
| 33 | + * verify that payload is not bigger than buffer | |
| 34 | + * otherwise masking logic may fail to detect | |
| 35 | + * the "not enough space" condition | |
| 36 | + */ | |
| 37 | + if ((head - offset) > sz) | |
| 38 | + return false; | |
| 27 | 39 | |
| 28 | 40 | offset = (offset - tail) & mask; |
| 29 | 41 | head = (head - tail) & mask; |
| @@ -212,7 +224,9 @@ ring_buffer_init(struct ring_buffer *rb, long watermark, int flags) · 182 unmodified lines | ||
| 212 | 224 | rb->watermark = max_size / 2; |
| 213 | 225 | |
| 214 | 226 | if (flags & RING_BUFFER_WRITABLE) |
| 215 | − rb->writable = 1; | |
| 227 | + rb->overwrite = 0; | |
| 228 | + else | |
| 229 | + rb->overwrite = 1; | |
| 216 | 230 | |
| 217 | 231 | atomic_set(&rb->refcount, 1); |
| 218 | 232 | |
| @@ -3440,14 +3440,14 @@ static char ftrace_filter_buf[FTRACE_FILTER_SIZE] __initdata; · 3439 unmodified lines | ||
| 3440 | 3440 | |
| 3441 | 3441 | static int __init set_ftrace_notrace(char *str) |
| 3442 | 3442 | { |
| 3443 | − strncpy(ftrace_notrace_buf, str, FTRACE_FILTER_SIZE); | |
| 3443 | + strlcpy(ftrace_notrace_buf, str, FTRACE_FILTER_SIZE); | |
| 3444 | 3444 | return 1; |
| 3445 | 3445 | } |
| 3446 | 3446 | __setup("ftrace_notrace=", set_ftrace_notrace); |
| 3447 | 3447 | |
| 3448 | 3448 | static int __init set_ftrace_filter(char *str) |
| 3449 | 3449 | { |
| 3450 | − strncpy(ftrace_filter_buf, str, FTRACE_FILTER_SIZE); | |
| 3450 | + strlcpy(ftrace_filter_buf, str, FTRACE_FILTER_SIZE); | |
| 3451 | 3451 | return 1; |
| 3452 | 3452 | } |
| 3453 | 3453 | __setup("ftrace_filter=", set_ftrace_filter); |
| @@ -132,7 +132,7 @@ static char *default_bootup_tracer; · 131 unmodified lines | ||
| 132 | 132 | |
| 133 | 133 | static int __init set_cmdline_ftrace(char *str) |
| 134 | 134 | { |
| 135 | − strncpy(bootup_tracer_buf, str, MAX_TRACER_SIZE); | |
| 135 | + strlcpy(bootup_tracer_buf, str, MAX_TRACER_SIZE); | |
| 136 | 136 | default_bootup_tracer = bootup_tracer_buf; |
| 137 | 137 | /* We are using ftrace early, expand it */ |
| 138 | 138 | ring_buffer_expanded = 1; |
| @@ -162,7 +162,7 @@ static char *trace_boot_options __initdata; · 23 unmodified lines | ||
| 162 | 162 | |
| 163 | 163 | static int __init set_trace_boot_options(char *str) |
| 164 | 164 | { |
| 165 | − strncpy(trace_boot_options_buf, str, MAX_TRACER_SIZE); | |
| 165 | + strlcpy(trace_boot_options_buf, str, MAX_TRACER_SIZE); | |
| 166 | 166 | trace_boot_options = trace_boot_options_buf; |
| 167 | 167 | return 0; |
| 168 | 168 | } |