* [PATCH v3] libbpf: Replace strncpy() with strnlen()+memcpy() in skel_map_create()
@ 2026-03-24 16:16 Kees Cook
2026-03-24 16:31 ` Alexei Starovoitov
0 siblings, 1 reply; 2+ messages in thread
From: Kees Cook @ 2026-03-24 16:16 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Kees Cook, Jiri Olsa, sun jian, Andrii Nakryiko, Eduard Zingerman,
Daniel Borkmann, Martin KaFai Lau, Song Liu, Yonghong Song,
John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, bpf,
linux-kernel, linux-hardening
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 the "__loader.map" 12 character string literal). The destination
attr.map_name is char[BPF_OBJ_NAME_LEN] (16 bytes) in union bpf_attr,
ultimately passed to the bpf() syscall.
The bpf(BPF_MAP_CREATE) syscall, through bpf_obj_name_cpy(), requires a
NUL terminator within this 16-byte array, rejecting names that use all 16
bytes. Valid names are therefore at most 15 characters, but this wasn't
being checked via the skel_map_create() path. Add a matching check and
refuse 16+ character strings early, as they would be refused later by
bpf_obj_name_cpy().
The attr is pre-zeroed with memset() at the top of the function, so
the last byte of attr.map_name is always NUL, meaning the memcpy()
of just the non-NUL characters from the source will always produce a
NUL-terminated destination string.
Link: https://github.com/KSPP/linux/issues/90 [1]
Signed-off-by: Kees Cook <kees@kernel.org>
---
v3: instead of truncation, refuse the long length (test appears to have been a flake)
v2: https://lore.kernel.org/lkml/20260324053036.it.906-kees@kernel.org/
v1: https://lore.kernel.org/lkml/20260324040535.work.851-kees@kernel.org/
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: sun jian <sun.jian.kdev@gmail.com>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: Eduard Zingerman <eddyz87@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Martin KaFai Lau <martin.lau@linux.dev>
Cc: Song Liu <song@kernel.org>
Cc: Yonghong Song <yonghong.song@linux.dev>
Cc: John Fastabend <john.fastabend@gmail.com>
Cc: KP Singh <kpsingh@kernel.org>
Cc: Stanislav Fomichev <sdf@fomichev.me>
Cc: Hao Luo <haoluo@google.com>
Cc: <bpf@vger.kernel.org>
---
tools/lib/bpf/skel_internal.h | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/tools/lib/bpf/skel_internal.h b/tools/lib/bpf/skel_internal.h
index 6a8f5c7a02eb..2d38c387f43c 100644
--- a/tools/lib/bpf/skel_internal.h
+++ b/tools/lib/bpf/skel_internal.h
@@ -236,6 +236,7 @@ static inline int skel_map_create(enum bpf_map_type map_type,
{
const size_t attr_sz = offsetofend(union bpf_attr, excl_prog_hash_size);
union bpf_attr attr;
+ size_t map_name_len;
memset(&attr, 0, attr_sz);
@@ -243,7 +244,12 @@ 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));
+ /* attr.map_name must be NUL-terminated, like bpf_obj_name_cpy() */
+ map_name_len = strnlen(map_name, sizeof(attr.map_name));
+ if (map_name_len == sizeof(attr.map_name))
+ return -EINVAL;
+ memcpy(attr.map_name, map_name, map_name_len);
+
attr.key_size = key_size;
attr.value_size = value_size;
attr.max_entries = max_entries;
--
2.34.1
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH v3] libbpf: Replace strncpy() with strnlen()+memcpy() in skel_map_create()
2026-03-24 16:16 [PATCH v3] libbpf: Replace strncpy() with strnlen()+memcpy() in skel_map_create() Kees Cook
@ 2026-03-24 16:31 ` Alexei Starovoitov
0 siblings, 0 replies; 2+ messages in thread
From: Alexei Starovoitov @ 2026-03-24 16:31 UTC (permalink / raw)
To: Kees Cook
Cc: Alexei Starovoitov, Jiri Olsa, sun jian, Andrii Nakryiko,
Eduard Zingerman, Daniel Borkmann, Martin KaFai Lau, Song Liu,
Yonghong Song, John Fastabend, KP Singh, Stanislav Fomichev,
Hao Luo, bpf, LKML, linux-hardening
On Tue, Mar 24, 2026 at 9:16 AM Kees Cook <kees@kernel.org> wrote:
>
> 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 the "__loader.map" 12 character string literal). The destination
> attr.map_name is char[BPF_OBJ_NAME_LEN] (16 bytes) in union bpf_attr,
> ultimately passed to the bpf() syscall.
>
> The bpf(BPF_MAP_CREATE) syscall, through bpf_obj_name_cpy(), requires a
> NUL terminator within this 16-byte array, rejecting names that use all 16
> bytes. Valid names are therefore at most 15 characters, but this wasn't
> being checked via the skel_map_create() path. Add a matching check and
> refuse 16+ character strings early, as they would be refused later by
> bpf_obj_name_cpy().
>
> The attr is pre-zeroed with memset() at the top of the function, so
> the last byte of attr.map_name is always NUL, meaning the memcpy()
> of just the non-NUL characters from the source will always produce a
> NUL-terminated destination string.
>
> Link: https://github.com/KSPP/linux/issues/90 [1]
> Signed-off-by: Kees Cook <kees@kernel.org>
> ---
> v3: instead of truncation, refuse the long length (test appears to have been a flake)
> v2: https://lore.kernel.org/lkml/20260324053036.it.906-kees@kernel.org/
> v1: https://lore.kernel.org/lkml/20260324040535.work.851-kees@kernel.org/
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: Jiri Olsa <jolsa@kernel.org>
> Cc: sun jian <sun.jian.kdev@gmail.com>
> Cc: Andrii Nakryiko <andrii@kernel.org>
> Cc: Eduard Zingerman <eddyz87@gmail.com>
> Cc: Daniel Borkmann <daniel@iogearbox.net>
> Cc: Martin KaFai Lau <martin.lau@linux.dev>
> Cc: Song Liu <song@kernel.org>
> Cc: Yonghong Song <yonghong.song@linux.dev>
> Cc: John Fastabend <john.fastabend@gmail.com>
> Cc: KP Singh <kpsingh@kernel.org>
> Cc: Stanislav Fomichev <sdf@fomichev.me>
> Cc: Hao Luo <haoluo@google.com>
> Cc: <bpf@vger.kernel.org>
> ---
> tools/lib/bpf/skel_internal.h | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/tools/lib/bpf/skel_internal.h b/tools/lib/bpf/skel_internal.h
> index 6a8f5c7a02eb..2d38c387f43c 100644
> --- a/tools/lib/bpf/skel_internal.h
> +++ b/tools/lib/bpf/skel_internal.h
> @@ -236,6 +236,7 @@ static inline int skel_map_create(enum bpf_map_type map_type,
> {
> const size_t attr_sz = offsetofend(union bpf_attr, excl_prog_hash_size);
> union bpf_attr attr;
> + size_t map_name_len;
>
> memset(&attr, 0, attr_sz);
>
> @@ -243,7 +244,12 @@ 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));
> + /* attr.map_name must be NUL-terminated, like bpf_obj_name_cpy() */
> + map_name_len = strnlen(map_name, sizeof(attr.map_name));
> + if (map_name_len == sizeof(attr.map_name))
> + return -EINVAL;
> + memcpy(attr.map_name, map_name, map_name_len);
and now you keep spamming without waiting for replies.
nack.
pw-bot: cr
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-03-24 16:32 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-24 16:16 [PATCH v3] libbpf: Replace strncpy() with strnlen()+memcpy() in skel_map_create() Kees Cook
2026-03-24 16:31 ` Alexei Starovoitov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox