* [PATCH v2 0/2] tracing/user_events: validate dynamic field bounds @ 2026-11-03 2:45 Yifan Zhang 2026-11-03 2:45 ` [PATCH v2 1/2] tracing/user_events: validate dynamic cpumask size Yifan Zhang 2026-11-03 2:45 ` [PATCH v2 2/2] tracing/user_events: reject overflowing field offsets Yifan Zhang 0 siblings, 2 replies; 4+ messages in thread From: Yifan Zhang @ 2026-11-03 2:45 UTC (permalink / raw) To: Steven Rostedt, Masami Hiramatsu, linux-trace-kernel Cc: Mathieu Desnoyers, Beau Belgrave, linux-kernel These patches validate the size assumptions used by dynamic cpumask fields and prevent explicit structure sizes from wrapping field offsets. Changes in v2: - parse explicit structure sizes into a u32 and reject values above INT_MAX before assigning them to the signed size variable Patch 1 is unchanged. Yifan Zhang (2): tracing/user_events: validate dynamic cpumask size tracing/user_events: reject overflowing field offsets kernel/trace/trace_events_user.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) -- 2.39.5 (Apple Git-154) ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 1/2] tracing/user_events: validate dynamic cpumask size 2026-11-03 2:45 [PATCH v2 0/2] tracing/user_events: validate dynamic field bounds Yifan Zhang @ 2026-11-03 2:45 ` Yifan Zhang 2026-11-04 21:39 ` Beau Belgrave 2026-11-03 2:45 ` [PATCH v2 2/2] tracing/user_events: reject overflowing field offsets Yifan Zhang 1 sibling, 1 reply; 4+ messages in thread From: Yifan Zhang @ 2026-11-03 2:45 UTC (permalink / raw) To: Steven Rostedt, Masami Hiramatsu, linux-trace-kernel Cc: Mathieu Desnoyers, Beau Belgrave, linux-kernel user_event_validate() checks that a dynamic field lies inside the event but does not verify the minimum size required by its filter type. A one-byte dynamic cpumask can therefore reach filter_pred_cpumask(), which consumes cpumask_size() bytes beyond the event buffer. KASAN reports: BUG: KASAN: slab-use-after-free in filter_match_preds Read of size 8 filter_match_preds trace_event_buffer_commit user_event_ftrace user_events_write_core Mark dynamic cpumask fields and reject locations shorter than cpumask_size(). The patched kernel rejects the short event and accepts a full-size control event without a KASAN report. Fixes: 2467cda1b5c9 ("user_events: Validate user payloads for size and null termination") Signed-off-by: Yifan Zhang <yfzhang23@stu.pku.edu.cn> --- kernel/trace/trace_events_user.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c index f658c3a77aa7a..85938b45b7618 100644 --- a/kernel/trace/trace_events_user.c +++ b/kernel/trace/trace_events_user.c @@ -170,6 +170,7 @@ struct user_event_file_info { #define VALIDATOR_ENSURE_NULL (1 << 0) #define VALIDATOR_REL (1 << 1) +#define VALIDATOR_CPUMASK BIT(2) struct user_event_validator { struct list_head user_event_link; @@ -1159,6 +1160,9 @@ static int user_event_add_field(struct user_event *user, const char *type, if (strstr(type, "char") != NULL) validator_flags |= VALIDATOR_ENSURE_NULL; + if (strstr(type, "cpumask_t")) + validator_flags |= VALIDATOR_CPUMASK; + validator = kmalloc_obj(*validator, GFP_KERNEL_ACCOUNT); if (!validator) { @@ -1598,6 +1602,10 @@ static int user_event_validate(struct user_event *user, void *data, int len) offset = loc & 0xffff; size = loc >> 16; + if (unlikely((validator->flags & VALIDATOR_CPUMASK) && + size < cpumask_size())) + return -EFAULT; + if (likely(validator->flags & VALIDATOR_REL)) pos += offset + sizeof(loc); else -- 2.39.5 (Apple Git-154) ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v2 1/2] tracing/user_events: validate dynamic cpumask size 2026-11-03 2:45 ` [PATCH v2 1/2] tracing/user_events: validate dynamic cpumask size Yifan Zhang @ 2026-11-04 21:39 ` Beau Belgrave 0 siblings, 0 replies; 4+ messages in thread From: Beau Belgrave @ 2026-11-04 21:39 UTC (permalink / raw) To: Yifan Zhang Cc: Steven Rostedt, Masami Hiramatsu, linux-trace-kernel, Mathieu Desnoyers, linux-kernel On Tue, Nov 03, 2026 at 10:45:19AM +0800, Yifan Zhang wrote: > user_event_validate() checks that a dynamic field lies inside the event but > does not verify the minimum size required by its filter type. A one-byte > dynamic cpumask can therefore reach filter_pred_cpumask(), which consumes > cpumask_size() bytes beyond the event buffer. > > KASAN reports: > > BUG: KASAN: slab-use-after-free in filter_match_preds > Read of size 8 > filter_match_preds Hey Yifan, In the V1 there was a repro case where this value was a __data_loc, which defines where the actual data (and it's size) is in the payload. There isn't a type min-size requirement when __data_loc is used, this seems like the bug resides possibly in filter_match_preds for __data_loc cases? See comments futher down. Steve, do you think this is the case? If not, then I guess we would have to validate min-size requirements of all types in the dynamic case, and I hope we could do that centrally to avoid fixing these in various spots. > trace_event_buffer_commit > user_event_ftrace > user_events_write_core > > Mark dynamic cpumask fields and reject locations shorter than > cpumask_size(). > > The patched kernel rejects the short event and accepts a full-size control > event without a KASAN report. > > Fixes: 2467cda1b5c9 ("user_events: Validate user payloads for size and null termination") > Signed-off-by: Yifan Zhang <yfzhang23@stu.pku.edu.cn> > --- > kernel/trace/trace_events_user.c | 8 ++++++++ > 1 file changed, 8 insertions(+) > > diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c > index f658c3a77aa7a..85938b45b7618 100644 > --- a/kernel/trace/trace_events_user.c > +++ b/kernel/trace/trace_events_user.c > @@ -170,6 +170,7 @@ struct user_event_file_info { > > #define VALIDATOR_ENSURE_NULL (1 << 0) > #define VALIDATOR_REL (1 << 1) > +#define VALIDATOR_CPUMASK BIT(2) > > struct user_event_validator { > struct list_head user_event_link; > @@ -1159,6 +1160,9 @@ static int user_event_add_field(struct user_event *user, const char *type, > if (strstr(type, "char") != NULL) > validator_flags |= VALIDATOR_ENSURE_NULL; > > + if (strstr(type, "cpumask_t")) > + validator_flags |= VALIDATOR_CPUMASK; > + You can only get to this case if you put struct, __rel_loc, or __data_loc. Those have their own size requirements and are dynamic in nature, IE: Each write describes the actual size in the __rel_loc and __data_loc cases, and statically for the struct case. user_field_size() checks if a type name has a known size, if not, it gets rejected. The only time this isn't the case is if you put struct in front and then have to give a size that's expected. The other case is if you put __data_loc or __rel_loc, both require the payload to dynamically have a size associated. In the dynamic case, the filter should be ensuring these values are minimally sized. > validator = kmalloc_obj(*validator, GFP_KERNEL_ACCOUNT); > > if (!validator) { > @@ -1598,6 +1602,10 @@ static int user_event_validate(struct user_event *user, void *data, int len) > offset = loc & 0xffff; > size = loc >> 16; > > + if (unlikely((validator->flags & VALIDATOR_CPUMASK) && > + size < cpumask_size())) > + return -EFAULT; > + > if (likely(validator->flags & VALIDATOR_REL)) > pos += offset + sizeof(loc); > else > -- > 2.39.5 (Apple Git-154) Thanks, -Beau ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 2/2] tracing/user_events: reject overflowing field offsets 2026-11-03 2:45 [PATCH v2 0/2] tracing/user_events: validate dynamic field bounds Yifan Zhang 2026-11-03 2:45 ` [PATCH v2 1/2] tracing/user_events: validate dynamic cpumask size Yifan Zhang @ 2026-11-03 2:45 ` Yifan Zhang 1 sibling, 0 replies; 4+ messages in thread From: Yifan Zhang @ 2026-11-03 2:45 UTC (permalink / raw) To: Steven Rostedt, Masami Hiramatsu, linux-trace-kernel Cc: Mathieu Desnoyers, Beau Belgrave, linux-kernel user_event_parse_field() accepts large structure sizes but accumulates field offsets in a u32 before storing them in signed int fields. A declaration can wrap the recorded minimum event size while a fixed-width field retains an offset outside the accepted record. A short write is then accepted and a field filter reads beyond the event buffer. KASAN reports: BUG: KASAN: slab-use-after-free in filter_match_preds Read of size 8 filter_match_preds trace_event_buffer_commit user_event_ftrace user_events_write_core Parse an explicit structure size into a u32, reject values greater than INT_MAX before converting them to int, and use checked addition for the resulting field offset. This prevents both signed conversion and offset overflow from bypassing the downstream bounds checks. Fixes: 7f5a08c79df3 ("user_events: Add minimal support for trace_event into ftrace") Signed-off-by: Yifan Zhang <yfzhang23@stu.pku.edu.cn> --- kernel/trace/trace_events_user.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c index 85938b45b7618..04eef4865490b 100644 --- a/kernel/trace/trace_events_user.c +++ b/kernel/trace/trace_events_user.c @@ -1207,6 +1207,7 @@ static int user_event_parse_field(char *field, struct user_event *user, { char *part, *type, *name; u32 depth = 0, saved_offset = *offset; + u32 new_offset, struct_size; int len, size = -EINVAL; bool is_struct = false; @@ -1267,8 +1268,11 @@ static int user_event_parse_field(char *field, struct user_event *user, if (!is_struct) return -EINVAL; - if (kstrtou32(part, 10, &size)) + if (kstrtou32(part, 10, &struct_size)) return -EINVAL; + if (struct_size > INT_MAX) + return -E2BIG; + size = struct_size; break; default: return -EINVAL; @@ -1287,7 +1291,11 @@ static int user_event_parse_field(char *field, struct user_event *user, if (size < 0) return size; - *offset = saved_offset + size; + if (check_add_overflow(saved_offset, (u32)size, &new_offset) || + new_offset > INT_MAX) + return -E2BIG; + + *offset = new_offset; return user_event_add_field(user, type, name, saved_offset, size, type[0] != 'u', FILTER_OTHER); -- 2.39.5 (Apple Git-154) ^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-11-04 21:39 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-11-03 2:45 [PATCH v2 0/2] tracing/user_events: validate dynamic field bounds Yifan Zhang 2026-11-03 2:45 ` [PATCH v2 1/2] tracing/user_events: validate dynamic cpumask size Yifan Zhang 2026-11-04 21:39 ` Beau Belgrave 2026-11-03 2:45 ` [PATCH v2 2/2] tracing/user_events: reject overflowing field offsets Yifan Zhang
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.