1139651Srwatson/*-
2139651Srwatson * Copyright (c) 2005 Robert N. M. Watson
3139651Srwatson * All rights reserved.
4139651Srwatson *
5139651Srwatson * Redistribution and use in source and binary forms, with or without
6139651Srwatson * modification, are permitted provided that the following conditions
7139651Srwatson * are met:
8139651Srwatson * 1. Redistributions of source code must retain the above copyright
9139651Srwatson *    notice, this list of conditions and the following disclaimer.
10139651Srwatson * 2. Redistributions in binary form must reproduce the above copyright
11139651Srwatson *    notice, this list of conditions and the following disclaimer in the
12139651Srwatson *    documentation and/or other materials provided with the distribution.
13139651Srwatson *
14139651Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15139651Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16139651Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17139651Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18139651Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19139651Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20139651Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21139651Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22139651Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23139651Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24139651Srwatson * SUCH DAMAGE.
25139651Srwatson *
26139651Srwatson * $FreeBSD: releng/10.2/tools/regression/mlock/mlock.c 139651 2005-01-03 19:56:20Z rwatson $
27139651Srwatson */
28139651Srwatson
29139651Srwatson#include <sys/types.h>
30139651Srwatson#include <sys/mman.h>
31139651Srwatson
32139651Srwatson#include <err.h>
33139651Srwatson#include <errno.h>
34139651Srwatson#include <pwd.h>
35139651Srwatson#include <stdlib.h>
36139651Srwatson#include <string.h>
37139651Srwatson#include <unistd.h>
38139651Srwatson
39139651Srwatson#define	NOBODY	"nobody"
40139651Srwatson
41139651Srwatson/*
42139651Srwatson * Simple exercise for the mlock() system call -- confirm that mlock() and
43139651Srwatson * munlock() return success on an anonymously mapped memory page when running
44139651Srwatson * with privilege; confirm that they fail with EPERM when running
45139651Srwatson * unprivileged.
46139651Srwatson */
47139651Srwatsonint
48139651Srwatsonmain(int argc, char *argv[])
49139651Srwatson{
50139651Srwatson	struct passwd *pwd;
51139651Srwatson	int pagesize;
52139651Srwatson	char *page;
53139651Srwatson
54139651Srwatson	if (geteuid() != 0)
55139651Srwatson		errx(-1, "mlock must run as root");
56139651Srwatson
57139651Srwatson	errno = 0;
58139651Srwatson	pwd = getpwnam(NOBODY);
59139651Srwatson	if (pwd == NULL && errno == 0)
60139651Srwatson		errx(-1, "getpwnam: user \"%s\" not found", NOBODY);
61139651Srwatson	if (pwd == NULL)
62139651Srwatson		errx(-1, "getpwnam: %s", strerror(errno));
63139651Srwatson	if (pwd->pw_uid == 0)
64139651Srwatson		errx(-1, "getpwnam: user \"%s\" has uid 0", NOBODY);
65139651Srwatson
66139651Srwatson	pagesize = getpagesize();
67139651Srwatson	page = mmap(NULL, pagesize, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0);
68139651Srwatson	if (page == MAP_FAILED)
69139651Srwatson		errx(-1, "mmap: %s", strerror(errno));
70139651Srwatson
71139651Srwatson	if (mlock(page, pagesize) < 0)
72139651Srwatson		errx(-1, "mlock privileged: %s", strerror(errno));
73139651Srwatson
74139651Srwatson	if (munlock(page, pagesize) < 0)
75139651Srwatson		errx(-1, "munlock privileged: %s", strerror(errno));
76139651Srwatson
77139651Srwatson	if (seteuid(pwd->pw_uid) < 0)
78139651Srwatson		errx(-1, "seteuid: %s", strerror(errno));
79139651Srwatson
80139651Srwatson	if (mlock(page, pagesize) == 0)
81139651Srwatson		errx(-1, "mlock unprivileged: succeeded but shouldn't have");
82139651Srwatson	if (errno != EPERM)
83139651Srwatson		errx(-1, "mlock unprivileged: %s", strerror(errno));
84139651Srwatson
85139651Srwatson	if (munlock(page, pagesize) == 0)
86139651Srwatson		errx(-1, "munlock unprivileged: succeeded but shouldn't have");
87139651Srwatson	if (errno != EPERM)
88139651Srwatson		errx(-1, "munlock unprivileged: %s", strerror(errno));
89139651Srwatson
90139651Srwatson	return (0);
91139651Srwatson}
92