1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines  Corp., 2001
4f08c3bdfSopenharmony_ci * Copyright (c) 2018 Xiao Yang <yangx.jy@cn.fujitsu.com>
5f08c3bdfSopenharmony_ci * Copyright (c) 2019 SUSE.  All Rights Reserved.
6f08c3bdfSopenharmony_ci */
7f08c3bdfSopenharmony_ci
8f08c3bdfSopenharmony_ci/*
9f08c3bdfSopenharmony_ci * DESCRIPTION:
10f08c3bdfSopenharmony_ci * Testcase for testing the basic functionality of sysctl(2) system call.
11f08c3bdfSopenharmony_ci * This testcase attempts to read the kernel parameters by using
12f08c3bdfSopenharmony_ci * sysctl({CTL_KERN, KERN_* }, ...) and compares it with the known values.
13f08c3bdfSopenharmony_ci */
14f08c3bdfSopenharmony_ci
15f08c3bdfSopenharmony_ci#include <errno.h>
16f08c3bdfSopenharmony_ci#include <stdio.h>
17f08c3bdfSopenharmony_ci#include <string.h>
18f08c3bdfSopenharmony_ci#include <linux/version.h>
19f08c3bdfSopenharmony_ci#include <sys/utsname.h>
20f08c3bdfSopenharmony_ci#include <linux/unistd.h>
21f08c3bdfSopenharmony_ci#include <linux/sysctl.h>
22f08c3bdfSopenharmony_ci
23f08c3bdfSopenharmony_ci#include "tst_test.h"
24f08c3bdfSopenharmony_ci#include "lapi/syscalls.h"
25f08c3bdfSopenharmony_ci
26f08c3bdfSopenharmony_cistatic struct utsname buf;
27f08c3bdfSopenharmony_ci
28f08c3bdfSopenharmony_cistatic struct tcase {
29f08c3bdfSopenharmony_ci	char *desc;
30f08c3bdfSopenharmony_ci	int name[2];
31f08c3bdfSopenharmony_ci	char *cmp_str;
32f08c3bdfSopenharmony_ci} tcases[] = {
33f08c3bdfSopenharmony_ci	{"KERN_OSTYPE", {CTL_KERN, KERN_OSTYPE}, buf.sysname},
34f08c3bdfSopenharmony_ci	{"KERN_OSRELEASE", {CTL_KERN, KERN_OSRELEASE}, buf.release},
35f08c3bdfSopenharmony_ci	{"KERN_VERSION", {CTL_KERN, KERN_VERSION}, buf.version},
36f08c3bdfSopenharmony_ci};
37f08c3bdfSopenharmony_ci
38f08c3bdfSopenharmony_cistatic void verify_sysctl(unsigned int n)
39f08c3bdfSopenharmony_ci{
40f08c3bdfSopenharmony_ci	char osname[BUFSIZ];
41f08c3bdfSopenharmony_ci	size_t length = BUFSIZ;
42f08c3bdfSopenharmony_ci	struct tcase *tc = &tcases[n];
43f08c3bdfSopenharmony_ci
44f08c3bdfSopenharmony_ci	memset(osname, 0, BUFSIZ);
45f08c3bdfSopenharmony_ci
46f08c3bdfSopenharmony_ci	struct __sysctl_args args = {
47f08c3bdfSopenharmony_ci		.name = tc->name,
48f08c3bdfSopenharmony_ci		.nlen = ARRAY_SIZE(tc->name),
49f08c3bdfSopenharmony_ci		.oldval = osname,
50f08c3bdfSopenharmony_ci		.oldlenp = &length,
51f08c3bdfSopenharmony_ci	};
52f08c3bdfSopenharmony_ci
53f08c3bdfSopenharmony_ci	TEST(tst_syscall(__NR__sysctl, &args));
54f08c3bdfSopenharmony_ci	if (TST_RET != 0) {
55f08c3bdfSopenharmony_ci		tst_res(TFAIL | TTERRNO, "sysctl() failed unexpectedly");
56f08c3bdfSopenharmony_ci		return;
57f08c3bdfSopenharmony_ci	}
58f08c3bdfSopenharmony_ci
59f08c3bdfSopenharmony_ci	if (strcmp(osname, tc->cmp_str)) {
60f08c3bdfSopenharmony_ci		tst_res(TFAIL, "Strings don't match %s : %s",
61f08c3bdfSopenharmony_ci			osname, tc->cmp_str);
62f08c3bdfSopenharmony_ci	} else {
63f08c3bdfSopenharmony_ci		tst_res(TPASS, "Test for %s is correct", tc->desc);
64f08c3bdfSopenharmony_ci	}
65f08c3bdfSopenharmony_ci}
66f08c3bdfSopenharmony_ci
67f08c3bdfSopenharmony_cistatic void setup(void)
68f08c3bdfSopenharmony_ci{
69f08c3bdfSopenharmony_ci	/* get kernel name and information */
70f08c3bdfSopenharmony_ci	if (uname(&buf) == -1)
71f08c3bdfSopenharmony_ci		tst_brk(TBROK | TERRNO, "uname() failed");
72f08c3bdfSopenharmony_ci
73f08c3bdfSopenharmony_ci	/* revert uname change in case of kGraft/livepatch */
74f08c3bdfSopenharmony_ci	char *klp_tag;
75f08c3bdfSopenharmony_ci	char *right_brace;
76f08c3bdfSopenharmony_ci
77f08c3bdfSopenharmony_ci	klp_tag = strstr(buf.version, "/kGraft-");
78f08c3bdfSopenharmony_ci	if (!klp_tag)
79f08c3bdfSopenharmony_ci		klp_tag = strstr(buf.version, "/lp-");
80f08c3bdfSopenharmony_ci	if (klp_tag) {
81f08c3bdfSopenharmony_ci		right_brace = strchr(klp_tag, ')');
82f08c3bdfSopenharmony_ci		if (right_brace)
83f08c3bdfSopenharmony_ci			memmove(klp_tag, right_brace, strlen(right_brace)+1);
84f08c3bdfSopenharmony_ci	}
85f08c3bdfSopenharmony_ci}
86f08c3bdfSopenharmony_ci
87f08c3bdfSopenharmony_cistatic struct tst_test test = {
88f08c3bdfSopenharmony_ci	.setup = setup,
89f08c3bdfSopenharmony_ci	.tcnt = ARRAY_SIZE(tcases),
90f08c3bdfSopenharmony_ci	.test = verify_sysctl,
91f08c3bdfSopenharmony_ci};
92