When bpf_sysctl_set_new_value is called in cgroup/sysctl handler, updated "new_len" is provided back to proc_sys_call_handler. But proc_sys_call_handler expects this value NOT to include \0 symbol, e.g. if user do: open("/proc/sys/net/ipv4/ip_local_reserved_ports", ...) write(fd, "11111", sizeof("22222")) or echo -n "11111" > /proc/sys/net/ipv4/ip_local_reserved_ports or sysctl -w net.ipv4.ip_local_reserved_ports=11111 proc_sys_call_handler receives count equal to `5`. if BPF handler code doesn't account for that, new value will be rejected by proc_sys_call_handler with EINVAL error. To make behavior consistent for bpf_sysctl_set_new_value, this change adjust `new_len` with `-1`, if `\0` passed as last character. Alternatively, using `sizeof("11111") - 1` in BPF handler should work, but it might not be obvious and spark confusion. Signed-off-by: Raman Shukhau <ramasha@xxxxxxxx> --- kernel/bpf/cgroup.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index bfc36e7ca6f6..23736aed1b53 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -1742,7 +1742,10 @@ int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head, if (ret == 0 && ctx.new_updated) { kfree(*buf); *buf = ctx.new_val; - *pcount = ctx.new_len; + if (!(*buf)[ctx.new_len]) + *pcount = ctx.new_len - 1; + else + *pcount = ctx.new_len; } else { kfree(ctx.new_val); } -- 2.43.0