Replace the deprecated[1] strncpy() with strnlen() on the source
followed by memcpy(). Normally strscpy() would be used in this case,
but skel_internal.h is shared between kernel and userspace tools, and
strscpy() is not available in the userspace build context.

The source map_name is a NUL-terminated C string (the only caller
passes a 12 character string literal). The destination attr.map_name is
char[BPF_OBJ_NAME_LEN] (16 bytes) in union bpf_attr, passed to the bpf()
syscall. The kernel's bpf_obj_name_cpy() requires a NUL terminator within
the 16-byte field, rejecting names that use all 16 bytes. Valid names
are therefore at most 15 characters.

The attr is pre-zeroed with memset() at the top of the function,
so the byte at position 15 is always NUL. The copy is bounded to
sizeof(attr.map_name) - 1 (15 bytes) to guarantee NUL-termination is
preserved. This is safe because the kernel would reject a 16-byte
unterminated name anyway, and the only in-tree caller passes
"__loader.map" (12 characters).

While the original strncpy() would have copied a full 16 bytes from an
overlong name (producing an unterminated field that the syscall rejects),
but this wasn't a reachable state. This replacement will instead always
truncate to 15 bytes and keeps the NUL terminator, which should have no
behavioral changes with the present code and avoids potential issues
with future over-long string literals.

Link: https://github.com/KSPP/linux/issues/90 [1]
Signed-off-by: Kees Cook <[email protected]>
---
Cc: Andrii Nakryiko <[email protected]>
Cc: Eduard Zingerman <[email protected]>
Cc: Alexei Starovoitov <[email protected]>
Cc: Daniel Borkmann <[email protected]>
Cc: Martin KaFai Lau <[email protected]>
Cc: Song Liu <[email protected]>
Cc: Yonghong Song <[email protected]>
Cc: John Fastabend <[email protected]>
Cc: KP Singh <[email protected]>
Cc: Stanislav Fomichev <[email protected]>
Cc: Hao Luo <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: <[email protected]>
---
 tools/lib/bpf/skel_internal.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/lib/bpf/skel_internal.h b/tools/lib/bpf/skel_internal.h
index 6a8f5c7a02eb..137da935f478 100644
--- a/tools/lib/bpf/skel_internal.h
+++ b/tools/lib/bpf/skel_internal.h
@@ -243,7 +243,8 @@ static inline int skel_map_create(enum bpf_map_type 
map_type,
        attr.excl_prog_hash = (unsigned long) excl_prog_hash;
        attr.excl_prog_hash_size = excl_prog_hash_sz;
 
-       strncpy(attr.map_name, map_name, sizeof(attr.map_name));
+       memcpy(attr.map_name, map_name,
+              strnlen(map_name, sizeof(attr.map_name) - 1));
        attr.key_size = key_size;
        attr.value_size = value_size;
        attr.max_entries = max_entries;
-- 
2.34.1


Reply via email to