1172106Srwatson/*-
2172106Srwatson * Copyright (c) 2007 Robert M. M. Watson
3172106Srwatson * All rights reserved.
4172106Srwatson *
5172106Srwatson * This software was developed by Robert N. M. Watson for the TrustedBSD
6172106Srwatson * Project.
7172106Srwatson *
8172106Srwatson * Redistribution and use in source and binary forms, with or without
9172106Srwatson * modification, are permitted provided that the following conditions
10172106Srwatson * are met:
11172106Srwatson * 1. Redistributions of source code must retain the above copyright
12172106Srwatson *    notice, this list of conditions and the following disclaimer.
13172106Srwatson * 2. Redistributions in binary form must reproduce the above copyright
14172106Srwatson *    notice, this list of conditions and the following disclaimer in the
15172106Srwatson *    documentation and/or other materials provided with the distribution.
16172106Srwatson *
17172106Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18172106Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19172106Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20172106Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY,
21172106Srwatson * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22172106Srwatson * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
23172106Srwatson * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24172106Srwatson * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25172106Srwatson * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26172106Srwatson * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27172106Srwatson * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28172106Srwatson *
29172106Srwatson * $FreeBSD: releng/10.3/tools/regression/priv/priv_msgbuf.c 172106 2007-09-09 23:08:39Z rwatson $
30172106Srwatson */
31172106Srwatson
32172106Srwatson/*
33172106Srwatson * Confirm that when security.bsd.unprivileged_read_msgbuf is set to 0,
34172106Srwatson * privilege is required to read the kernel message buffer.
35172106Srwatson */
36172106Srwatson
37172106Srwatson#include <sys/types.h>
38172106Srwatson#include <sys/sysctl.h>
39172106Srwatson
40172106Srwatson#include <err.h>
41172106Srwatson#include <errno.h>
42172106Srwatson#include <stdio.h>
43172106Srwatson
44172106Srwatson#include "main.h"
45172106Srwatson
46172106Srwatson#define	MSGBUF_CONTROL_NAME	"security.bsd.unprivileged_read_msgbuf"
47172106Srwatson#define	MSGBUF_NAME		"kern.msgbuf"
48172106Srwatson
49172106Srwatson/*
50172106Srwatson * We must query and save the original value, then restore it when done.
51172106Srwatson */
52172106Srwatsonstatic int unprivileged_read_msgbuf;
53172106Srwatsonstatic int unprivileged_read_msgbuf_initialized;
54172106Srwatson
55172106Srwatsonint
56172106Srwatsonpriv_msgbuf_privonly_setup(int asroot, int injail, struct test *test)
57172106Srwatson{
58172106Srwatson	size_t len;
59172106Srwatson	int newval;
60172106Srwatson
61172106Srwatson	/*
62172106Srwatson	 * Separately query and set to make debugging easier.
63172106Srwatson	 */
64172106Srwatson	len = sizeof(unprivileged_read_msgbuf);
65172106Srwatson	if (sysctlbyname(MSGBUF_CONTROL_NAME, &unprivileged_read_msgbuf,
66172106Srwatson	    &len, NULL, 0) < 0) {
67172106Srwatson		warn("priv_msgbuf_privonly_setup: sysctlbyname query");
68172106Srwatson		return (-1);
69172106Srwatson	}
70172106Srwatson	newval = 0;
71172106Srwatson	if (sysctlbyname(MSGBUF_CONTROL_NAME, NULL, NULL, &newval,
72172106Srwatson	    sizeof(newval)) < 0) {
73172106Srwatson		warn("priv_msgbuf_privonly_setup: sysctlbyname set");
74172106Srwatson		return (-1);
75172106Srwatson	}
76172106Srwatson	unprivileged_read_msgbuf_initialized = 1;
77172106Srwatson	return (0);
78172106Srwatson}
79172106Srwatson
80172106Srwatsonvoid
81172106Srwatsonpriv_msgbuf_privonly(int asroot, int injail, struct test *test)
82172106Srwatson{
83172106Srwatson	size_t len;
84172106Srwatson	int error;
85172106Srwatson
86172106Srwatson	error = sysctlbyname(MSGBUF_NAME, NULL, &len, NULL, 0);
87172106Srwatson	if (asroot && injail)
88172106Srwatson		expect("priv_msgbuf_privonly(asroot, injail)", error, -1,
89172106Srwatson		    EPERM);
90172106Srwatson	if (asroot && !injail)
91172106Srwatson		expect("priv_msgbuf_privonly(asroot, !injail)", error, 0, 0);
92172106Srwatson	if (!asroot && injail)
93172106Srwatson		expect("priv_msgbuf_privonly(!asroot, injail)", error, -1,
94172106Srwatson		    EPERM);
95172106Srwatson	if (!asroot && !injail)
96172106Srwatson		expect("priv_msgbuf_privonly(!asroot, !injail)", error, -1,
97172106Srwatson		    EPERM);
98172106Srwatson}
99172106Srwatson
100172106Srwatsonint
101172106Srwatsonpriv_msgbuf_unprivok_setup(int asroot, int injail, struct test *test)
102172106Srwatson{
103172106Srwatson	size_t len;
104172106Srwatson	int newval;
105172106Srwatson
106172106Srwatson	/*
107172106Srwatson	 * Separately query and set to make debugging easier.
108172106Srwatson	 */
109172106Srwatson	len = sizeof(unprivileged_read_msgbuf);
110172106Srwatson	if (sysctlbyname(MSGBUF_CONTROL_NAME, &unprivileged_read_msgbuf, &len,
111172106Srwatson	    NULL, 0) < 0) {
112172106Srwatson		warn("priv_msgbuf_unprivok_setup: sysctlbyname query");
113172106Srwatson		return (-1);
114172106Srwatson	}
115172106Srwatson	newval = 1;
116172106Srwatson	if (sysctlbyname(MSGBUF_CONTROL_NAME, NULL, NULL, &newval,
117172106Srwatson	    sizeof(newval)) < 0) {
118172106Srwatson		warn("priv_msgbuf_unprivok_setup: sysctlbyname set");
119172106Srwatson		return (-1);
120172106Srwatson	}
121172106Srwatson	unprivileged_read_msgbuf_initialized = 1;
122172106Srwatson	return (0);
123172106Srwatson}
124172106Srwatson
125172106Srwatsonvoid
126172106Srwatsonpriv_msgbuf_unprivok(int asroot, int injail, struct test *test)
127172106Srwatson{
128172106Srwatson	size_t len;
129172106Srwatson	int error;
130172106Srwatson
131172106Srwatson	error = sysctlbyname(MSGBUF_NAME, NULL, &len, NULL, 0);
132172106Srwatson	if (asroot && injail)
133172106Srwatson		expect("priv_msgbuf_unprivok(asroot, injail)", error, 0, 0);
134172106Srwatson	if (asroot && !injail)
135172106Srwatson		expect("priv_msgbuf_unprivok(asroot, !injail)", error, 0, 0);
136172106Srwatson	if (!asroot && injail)
137172106Srwatson		expect("priv_msgbuf_unprivok(!asroot, injail)", error, 0, 0);
138172106Srwatson	if (!asroot && !injail)
139172106Srwatson		expect("priv_msgbuf_unprivok(!asroot, !injail)", error, 0, 0);
140172106Srwatson}
141172106Srwatson
142172106Srwatsonvoid
143172106Srwatsonpriv_msgbuf_cleanup(int asroot, int injail, struct test *test)
144172106Srwatson{
145172106Srwatson
146172106Srwatson	if (unprivileged_read_msgbuf_initialized) {
147172106Srwatson		(void)sysctlbyname(MSGBUF_NAME, NULL, NULL,
148172106Srwatson		    &unprivileged_read_msgbuf,
149172106Srwatson		    sizeof(unprivileged_read_msgbuf));
150172106Srwatson		unprivileged_read_msgbuf_initialized = 0;
151172106Srwatson	}
152172106Srwatson}
153