--- /dev/null
+From 63c49efc987afefc6b9bb7de083eb8748e0b1789 Mon Sep 17 00:00:00 2001
+From: Ihor Solodrai <ihor.solodrai@linux.dev>
+Date: Mon, 23 Feb 2026 11:07:17 -0800
+Subject: selftests/bpf: Add simple strscpy() implementation
+
+From: Ihor Solodrai <ihor.solodrai@linux.dev>
+
+commit 63c49efc987afefc6b9bb7de083eb8748e0b1789 upstream.
+
+Replace bpf_strlcpy() in bpf_util.h with a sized_strscpy(), which is a
+simplified sized_strscpy() from the kernel (lib/string.c [1]). It:
+ * takes a count (destination size) parameter
+ * guarantees NULL-termination
+ * returns the number of characters copied or -E2BIG
+
+Re-define strscpy macro similar to in-kernel implementation [2]: allow
+the count parameter to be optional.
+
+Add #ifdef-s to tools/include/linux/args.h, as they may be defined in
+other system headers (for example, __CONCAT in sys/cdefs.h).
+
+Fixup the single existing bpf_strlcpy() call in cgroup_helpers.c
+
+[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/lib/string.c?h=v6.19#n113
+[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/string.h?h=v6.19#n91
+
+Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
+Link: https://lore.kernel.org/r/20260223190736.649171-2-ihor.solodrai@linux.dev
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Cc: Shung-Hsi Yu <shung-hsi.yu@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/include/linux/args.h | 4 ++
+ tools/testing/selftests/bpf/bpf_util.h | 45 +++++++++++++++++++--------
+ tools/testing/selftests/bpf/cgroup_helpers.c | 2 -
+ 3 files changed, 37 insertions(+), 14 deletions(-)
+
+--- a/tools/include/linux/args.h
++++ b/tools/include/linux/args.h
+@@ -22,7 +22,11 @@
+ #define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
+
+ /* Concatenate two parameters, but allow them to be expanded beforehand. */
++#ifndef __CONCAT
+ #define __CONCAT(a, b) a ## b
++#endif
++#ifndef CONCATENATE
+ #define CONCATENATE(a, b) __CONCAT(a, b)
++#endif
+
+ #endif /* _LINUX_ARGS_H */
+--- a/tools/testing/selftests/bpf/bpf_util.h
++++ b/tools/testing/selftests/bpf/bpf_util.h
+@@ -8,6 +8,7 @@
+ #include <errno.h>
+ #include <syscall.h>
+ #include <bpf/libbpf.h> /* libbpf_num_possible_cpus */
++#include <linux/args.h>
+
+ static inline unsigned int bpf_num_possible_cpus(void)
+ {
+@@ -21,25 +22,43 @@ static inline unsigned int bpf_num_possi
+ return possible_cpus;
+ }
+
+-/* Copy up to sz - 1 bytes from zero-terminated src string and ensure that dst
+- * is zero-terminated string no matter what (unless sz == 0, in which case
+- * it's a no-op). It's conceptually close to FreeBSD's strlcpy(), but differs
+- * in what is returned. Given this is internal helper, it's trivial to extend
+- * this, when necessary. Use this instead of strncpy inside libbpf source code.
++/*
++ * Simplified strscpy() implementation. The kernel one is in lib/string.c
+ */
+-static inline void bpf_strlcpy(char *dst, const char *src, size_t sz)
++static inline ssize_t sized_strscpy(char *dest, const char *src, size_t count)
+ {
+- size_t i;
++ long res = 0;
+
+- if (sz == 0)
+- return;
++ if (count == 0)
++ return -E2BIG;
+
+- sz--;
+- for (i = 0; i < sz && src[i]; i++)
+- dst[i] = src[i];
+- dst[i] = '\0';
++ while (count > 1) {
++ char c;
++
++ c = src[res];
++ dest[res] = c;
++ if (!c)
++ return res;
++ res++;
++ count--;
++ }
++
++ /* Force NUL-termination. */
++ dest[res] = '\0';
++
++ /* Return E2BIG if the source didn't stop */
++ return src[res] ? -E2BIG : res;
+ }
+
++#define __strscpy0(dst, src, ...) \
++ sized_strscpy(dst, src, sizeof(dst))
++#define __strscpy1(dst, src, size) \
++ sized_strscpy(dst, src, size)
++
++#undef strscpy /* Redefine the placeholder from tools/include/linux/string.h */
++#define strscpy(dst, src, ...) \
++ CONCATENATE(__strscpy, COUNT_ARGS(__VA_ARGS__))(dst, src, __VA_ARGS__)
++
+ #define __bpf_percpu_val_align __attribute__((__aligned__(8)))
+
+ #define BPF_DECLARE_PERCPU(type, name) \
+--- a/tools/testing/selftests/bpf/cgroup_helpers.c
++++ b/tools/testing/selftests/bpf/cgroup_helpers.c
+@@ -86,7 +86,7 @@ static int __enable_controllers(const ch
+ enable[len] = 0;
+ close(fd);
+ } else {
+- bpf_strlcpy(enable, controllers, sizeof(enable));
++ strscpy(enable, controllers);
+ }
+
+ snprintf(path, sizeof(path), "%s/cgroup.subtree_control", cgroup_path);