Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

selftests/bpf: Add simple strscpy() implementation

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>

authored by

Ihor Solodrai and committed by
Alexei Starovoitov
63c49efc 7dff99b3

+37 -14
+4
tools/include/linux/args.h
··· 22 22 #define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) 23 23 24 24 /* Concatenate two parameters, but allow them to be expanded beforehand. */ 25 + #ifndef __CONCAT 25 26 #define __CONCAT(a, b) a ## b 27 + #endif 28 + #ifndef CONCATENATE 26 29 #define CONCATENATE(a, b) __CONCAT(a, b) 30 + #endif 27 31 28 32 #endif /* _LINUX_ARGS_H */
+32 -13
tools/testing/selftests/bpf/bpf_util.h
··· 8 8 #include <errno.h> 9 9 #include <syscall.h> 10 10 #include <bpf/libbpf.h> /* libbpf_num_possible_cpus */ 11 + #include <linux/args.h> 11 12 12 13 static inline unsigned int bpf_num_possible_cpus(void) 13 14 { ··· 22 21 return possible_cpus; 23 22 } 24 23 25 - /* Copy up to sz - 1 bytes from zero-terminated src string and ensure that dst 26 - * is zero-terminated string no matter what (unless sz == 0, in which case 27 - * it's a no-op). It's conceptually close to FreeBSD's strlcpy(), but differs 28 - * in what is returned. Given this is internal helper, it's trivial to extend 29 - * this, when necessary. Use this instead of strncpy inside libbpf source code. 24 + /* 25 + * Simplified strscpy() implementation. The kernel one is in lib/string.c 30 26 */ 31 - static inline void bpf_strlcpy(char *dst, const char *src, size_t sz) 27 + static inline ssize_t sized_strscpy(char *dest, const char *src, size_t count) 32 28 { 33 - size_t i; 29 + long res = 0; 34 30 35 - if (sz == 0) 36 - return; 31 + if (count == 0) 32 + return -E2BIG; 37 33 38 - sz--; 39 - for (i = 0; i < sz && src[i]; i++) 40 - dst[i] = src[i]; 41 - dst[i] = '\0'; 34 + while (count > 1) { 35 + char c; 36 + 37 + c = src[res]; 38 + dest[res] = c; 39 + if (!c) 40 + return res; 41 + res++; 42 + count--; 43 + } 44 + 45 + /* Force NUL-termination. */ 46 + dest[res] = '\0'; 47 + 48 + /* Return E2BIG if the source didn't stop */ 49 + return src[res] ? -E2BIG : res; 42 50 } 51 + 52 + #define __strscpy0(dst, src, ...) \ 53 + sized_strscpy(dst, src, sizeof(dst)) 54 + #define __strscpy1(dst, src, size) \ 55 + sized_strscpy(dst, src, size) 56 + 57 + #undef strscpy /* Redefine the placeholder from tools/include/linux/string.h */ 58 + #define strscpy(dst, src, ...) \ 59 + CONCATENATE(__strscpy, COUNT_ARGS(__VA_ARGS__))(dst, src, __VA_ARGS__) 43 60 44 61 #define __bpf_percpu_val_align __attribute__((__aligned__(8))) 45 62
+1 -1
tools/testing/selftests/bpf/cgroup_helpers.c
··· 86 86 enable[len] = 0; 87 87 close(fd); 88 88 } else { 89 - bpf_strlcpy(enable, controllers, sizeof(enable)); 89 + strscpy(enable, controllers); 90 90 } 91 91 92 92 snprintf(path, sizeof(path), "%s/cgroup.subtree_control", cgroup_path);