1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) 2017 Richard Palethorpe <rpalethorpe@suse.com>
4f08c3bdfSopenharmony_ci * Copyright (c) 2012, Kees Cook <keescook@chromium.org>
5f08c3bdfSopenharmony_ci */
6f08c3bdfSopenharmony_ci/*
7f08c3bdfSopenharmony_ci * Check that memory after the string terminator in all the utsname fields has
8f08c3bdfSopenharmony_ci * been zeroed. cve-2012-0957 leaked kernel memory through the release field
9f08c3bdfSopenharmony_ci * when the UNAME26 personality was set.
10f08c3bdfSopenharmony_ci *
11f08c3bdfSopenharmony_ci * Thanks to Kees Cook for the original proof of concept:
12f08c3bdfSopenharmony_ci * http://www.securityfocus.com/bid/55855/info
13f08c3bdfSopenharmony_ci */
14f08c3bdfSopenharmony_ci
15f08c3bdfSopenharmony_ci#include <string.h>
16f08c3bdfSopenharmony_ci#include <sys/utsname.h>
17f08c3bdfSopenharmony_ci#include "tst_test.h"
18f08c3bdfSopenharmony_ci#include "lapi/personality.h"
19f08c3bdfSopenharmony_ci
20f08c3bdfSopenharmony_cistatic struct utsname saved_buf;
21f08c3bdfSopenharmony_ci
22f08c3bdfSopenharmony_cistatic int check_field(char *bytes, char *saved_bytes, size_t length,
23f08c3bdfSopenharmony_ci		       char *field)
24f08c3bdfSopenharmony_ci{
25f08c3bdfSopenharmony_ci	size_t i = strlen(bytes) + 1;
26f08c3bdfSopenharmony_ci
27f08c3bdfSopenharmony_ci	for (; i < length; i++) {
28f08c3bdfSopenharmony_ci		if (bytes[i] && (bytes[i] != saved_bytes[i])) {
29f08c3bdfSopenharmony_ci			tst_res(TFAIL, "Bytes leaked in %s!", field);
30f08c3bdfSopenharmony_ci			return 1;
31f08c3bdfSopenharmony_ci		}
32f08c3bdfSopenharmony_ci	}
33f08c3bdfSopenharmony_ci	return 0;
34f08c3bdfSopenharmony_ci}
35f08c3bdfSopenharmony_ci
36f08c3bdfSopenharmony_ci
37f08c3bdfSopenharmony_cistatic void try_leak_bytes(unsigned int test_nr)
38f08c3bdfSopenharmony_ci{
39f08c3bdfSopenharmony_ci	struct utsname buf;
40f08c3bdfSopenharmony_ci
41f08c3bdfSopenharmony_ci	memset(&buf, 0, sizeof(buf));
42f08c3bdfSopenharmony_ci
43f08c3bdfSopenharmony_ci	if (uname(&buf))
44f08c3bdfSopenharmony_ci		tst_brk(TBROK | TERRNO, "Call to uname failed");
45f08c3bdfSopenharmony_ci
46f08c3bdfSopenharmony_ci	if (!test_nr)
47f08c3bdfSopenharmony_ci		memcpy(&saved_buf, &buf, sizeof(saved_buf));
48f08c3bdfSopenharmony_ci
49f08c3bdfSopenharmony_ci#define CHECK_FIELD(field_name) \
50f08c3bdfSopenharmony_ci	(check_field(buf.field_name, saved_buf.field_name, \
51f08c3bdfSopenharmony_ci		     ARRAY_SIZE(buf.field_name), #field_name))
52f08c3bdfSopenharmony_ci
53f08c3bdfSopenharmony_ci	if (!(CHECK_FIELD(release) |
54f08c3bdfSopenharmony_ci	    CHECK_FIELD(sysname) |
55f08c3bdfSopenharmony_ci	    CHECK_FIELD(nodename) |
56f08c3bdfSopenharmony_ci	    CHECK_FIELD(version) |
57f08c3bdfSopenharmony_ci	    CHECK_FIELD(machine) |
58f08c3bdfSopenharmony_ci#ifdef HAVE_STRUCT_UTSNAME_DOMAINNAME
59f08c3bdfSopenharmony_ci	    CHECK_FIELD(domainname) |
60f08c3bdfSopenharmony_ci#endif
61f08c3bdfSopenharmony_ci		    0)) {
62f08c3bdfSopenharmony_ci		tst_res(TPASS, "No bytes leaked");
63f08c3bdfSopenharmony_ci	}
64f08c3bdfSopenharmony_ci#undef CHECK_FIELD
65f08c3bdfSopenharmony_ci}
66f08c3bdfSopenharmony_ci
67f08c3bdfSopenharmony_cistatic void run(unsigned int test_nr)
68f08c3bdfSopenharmony_ci{
69f08c3bdfSopenharmony_ci	if (!test_nr) {
70f08c3bdfSopenharmony_ci		tst_res(TINFO, "Calling uname with default personality");
71f08c3bdfSopenharmony_ci	} else {
72f08c3bdfSopenharmony_ci		SAFE_PERSONALITY(PER_LINUX | UNAME26);
73f08c3bdfSopenharmony_ci		tst_res(TINFO, "Calling uname with UNAME26 personality");
74f08c3bdfSopenharmony_ci	}
75f08c3bdfSopenharmony_ci
76f08c3bdfSopenharmony_ci	try_leak_bytes(test_nr);
77f08c3bdfSopenharmony_ci}
78f08c3bdfSopenharmony_ci
79f08c3bdfSopenharmony_cistatic struct tst_test test = {
80f08c3bdfSopenharmony_ci	.test = run,
81f08c3bdfSopenharmony_ci	.tcnt = 2,
82f08c3bdfSopenharmony_ci	.tags = (const struct tst_tag[]) {
83f08c3bdfSopenharmony_ci		{"CVE", "2012-0957"},
84f08c3bdfSopenharmony_ci		{}
85f08c3bdfSopenharmony_ci	}
86f08c3bdfSopenharmony_ci};
87