1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) 2019 SUSE LLC
4f08c3bdfSopenharmony_ci * Author: Christian Amann <camann@suse.com>
5f08c3bdfSopenharmony_ci */
6f08c3bdfSopenharmony_ci/* Test for CVE-2016-9793
7f08c3bdfSopenharmony_ci *
8f08c3bdfSopenharmony_ci * With kernels between version 3.11 and 4.8 missing commit b98b0bc8 it
9f08c3bdfSopenharmony_ci * is possible to pass a very high unsigned integer as send buffer size
10f08c3bdfSopenharmony_ci * to a socket which is then interpreted as a negative value.
11f08c3bdfSopenharmony_ci *
12f08c3bdfSopenharmony_ci * This can be used to escalate privileges by every user that has the
13f08c3bdfSopenharmony_ci * CAP_NET_ADMIN capability.
14f08c3bdfSopenharmony_ci *
15f08c3bdfSopenharmony_ci * For additional information about this CVE see:
16f08c3bdfSopenharmony_ci * https://www.suse.com/security/cve/CVE-2016-9793/
17f08c3bdfSopenharmony_ci */
18f08c3bdfSopenharmony_ci
19f08c3bdfSopenharmony_ci#include <sys/socket.h>
20f08c3bdfSopenharmony_ci#include "tst_test.h"
21f08c3bdfSopenharmony_ci#include "tst_safe_net.h"
22f08c3bdfSopenharmony_ci
23f08c3bdfSopenharmony_ci#define SNDBUF	(0xffffff00)
24f08c3bdfSopenharmony_ci
25f08c3bdfSopenharmony_cistatic int sockfd;
26f08c3bdfSopenharmony_ci
27f08c3bdfSopenharmony_cistatic void run(void)
28f08c3bdfSopenharmony_ci{
29f08c3bdfSopenharmony_ci	unsigned int sndbuf, rec_sndbuf;
30f08c3bdfSopenharmony_ci	socklen_t optlen;
31f08c3bdfSopenharmony_ci
32f08c3bdfSopenharmony_ci	sndbuf = SNDBUF;
33f08c3bdfSopenharmony_ci	rec_sndbuf = 0;
34f08c3bdfSopenharmony_ci	optlen = sizeof(sndbuf);
35f08c3bdfSopenharmony_ci
36f08c3bdfSopenharmony_ci	SAFE_SETSOCKOPT(sockfd, SOL_SOCKET, SO_SNDBUFFORCE, &sndbuf, optlen);
37f08c3bdfSopenharmony_ci	SAFE_GETSOCKOPT(sockfd, SOL_SOCKET, SO_SNDBUF, &rec_sndbuf, &optlen);
38f08c3bdfSopenharmony_ci
39f08c3bdfSopenharmony_ci	tst_res(TINFO, "Try to set send buffer size to: %u", sndbuf);
40f08c3bdfSopenharmony_ci	tst_res(TINFO, "Send buffer size was set to: %d", rec_sndbuf);
41f08c3bdfSopenharmony_ci
42f08c3bdfSopenharmony_ci	if ((int)rec_sndbuf < 0)
43f08c3bdfSopenharmony_ci		tst_res(TFAIL, "Was able to set negative send buffer size!");
44f08c3bdfSopenharmony_ci	else
45f08c3bdfSopenharmony_ci		tst_res(TPASS, "Was unable to set negative send buffer size!");
46f08c3bdfSopenharmony_ci}
47f08c3bdfSopenharmony_ci
48f08c3bdfSopenharmony_cistatic void setup(void)
49f08c3bdfSopenharmony_ci{
50f08c3bdfSopenharmony_ci	sockfd = SAFE_SOCKET(AF_INET, SOCK_DGRAM, 0);
51f08c3bdfSopenharmony_ci}
52f08c3bdfSopenharmony_ci
53f08c3bdfSopenharmony_cistatic void cleanup(void)
54f08c3bdfSopenharmony_ci{
55f08c3bdfSopenharmony_ci	if (sockfd > 0)
56f08c3bdfSopenharmony_ci		SAFE_CLOSE(sockfd);
57f08c3bdfSopenharmony_ci}
58f08c3bdfSopenharmony_ci
59f08c3bdfSopenharmony_cistatic struct tst_test test = {
60f08c3bdfSopenharmony_ci	.test_all = run,
61f08c3bdfSopenharmony_ci	.setup = setup,
62f08c3bdfSopenharmony_ci	.cleanup = cleanup,
63f08c3bdfSopenharmony_ci	.needs_root = 1,
64f08c3bdfSopenharmony_ci	.tags = (const struct tst_tag[]) {
65f08c3bdfSopenharmony_ci		{"linux-git", "b98b0bc8c431"},
66f08c3bdfSopenharmony_ci		{"CVE", "2016-9793"},
67f08c3bdfSopenharmony_ci		{}
68f08c3bdfSopenharmony_ci	}
69f08c3bdfSopenharmony_ci};
70