Skip to content

Commit 0adab2b

Browse files
committed
tools/nolibc: add support for uname(2)
All supported kernels are assumed to use struct new_utsname. This is validated in test_uname(). uname(2) can for example be used in ksft_min_kernel_version() from the kernels selftest framework. Link: https://lore.kernel.org/lkml/20240412123536.GA32444@redhat.com/ Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> Acked-by: Willy Tarreau <w@1wt.eu>
1 parent e93b912 commit 0adab2b

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

tools/include/nolibc/sys.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/stat.h> /* for statx() */
2323
#include <linux/prctl.h>
2424
#include <linux/resource.h>
25+
#include <linux/utsname.h>
2526

2627
#include "arch.h"
2728
#include "errno.h"
@@ -1139,6 +1140,32 @@ int umount2(const char *path, int flags)
11391140
}
11401141

11411142

1143+
/*
1144+
* int uname(struct utsname *buf);
1145+
*/
1146+
1147+
struct utsname {
1148+
char sysname[65];
1149+
char nodename[65];
1150+
char release[65];
1151+
char version[65];
1152+
char machine[65];
1153+
char domainname[65];
1154+
};
1155+
1156+
static __attribute__((unused))
1157+
int sys_uname(struct utsname *buf)
1158+
{
1159+
return my_syscall1(__NR_uname, buf);
1160+
}
1161+
1162+
static __attribute__((unused))
1163+
int uname(struct utsname *buf)
1164+
{
1165+
return __sysret(sys_uname(buf));
1166+
}
1167+
1168+
11421169
/*
11431170
* int unlink(const char *path);
11441171
*/

tools/testing/selftests/nolibc/nolibc-test.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <sys/syscall.h>
2828
#include <sys/sysmacros.h>
2929
#include <sys/time.h>
30+
#include <sys/utsname.h>
3031
#include <sys/wait.h>
3132
#include <dirent.h>
3233
#include <errno.h>
@@ -780,6 +781,45 @@ int test_stat_timestamps(void)
780781
return 0;
781782
}
782783

784+
int test_uname(void)
785+
{
786+
struct utsname buf;
787+
char osrelease[sizeof(buf.release)];
788+
ssize_t r;
789+
int fd;
790+
791+
memset(&buf.domainname, 'P', sizeof(buf.domainname));
792+
793+
if (uname(&buf))
794+
return 1;
795+
796+
if (strncmp("Linux", buf.sysname, sizeof(buf.sysname)))
797+
return 1;
798+
799+
fd = open("/proc/sys/kernel/osrelease", O_RDONLY);
800+
if (fd == -1)
801+
return 1;
802+
803+
r = read(fd, osrelease, sizeof(osrelease));
804+
if (r == -1)
805+
return 1;
806+
807+
close(fd);
808+
809+
if (osrelease[r - 1] == '\n')
810+
r--;
811+
812+
/* Validate one of the later fields to ensure field sizes are correct */
813+
if (strncmp(osrelease, buf.release, r))
814+
return 1;
815+
816+
/* Ensure the field domainname is set, it is missing from struct old_utsname */
817+
if (strnlen(buf.domainname, sizeof(buf.domainname)) == sizeof(buf.domainname))
818+
return 1;
819+
820+
return 0;
821+
}
822+
783823
int test_mmap_munmap(void)
784824
{
785825
int ret, fd, i, page_size;
@@ -985,6 +1025,8 @@ int run_syscall(int min, int max)
9851025
CASE_TEST(stat_fault); EXPECT_SYSER(1, stat(NULL, &stat_buf), -1, EFAULT); break;
9861026
CASE_TEST(stat_timestamps); EXPECT_SYSZR(1, test_stat_timestamps()); break;
9871027
CASE_TEST(symlink_root); EXPECT_SYSER(1, symlink("/", "/"), -1, EEXIST); break;
1028+
CASE_TEST(uname); EXPECT_SYSZR(proc, test_uname()); break;
1029+
CASE_TEST(uname_fault); EXPECT_SYSER(1, uname(NULL), -1, EFAULT); break;
9881030
CASE_TEST(unlink_root); EXPECT_SYSER(1, unlink("/"), -1, EISDIR); break;
9891031
CASE_TEST(unlink_blah); EXPECT_SYSER(1, unlink("/proc/self/blah"), -1, ENOENT); break;
9901032
CASE_TEST(wait_child); EXPECT_SYSER(1, wait(&tmp), -1, ECHILD); break;

0 commit comments

Comments
 (0)