summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2001-09-20 20:03:58 +0000
committerrwatson <rwatson@FreeBSD.org>2001-09-20 20:03:58 +0000
commit7e6f69ce22a4606761ef35d9080eaa39a1e62cbd (patch)
tree5200f4fcbfa967ddb2228c3a418b945a813deb1b /tools
parent4f37ea8452ae55b7de96558ef527db798a374560 (diff)
downloadFreeBSD-src-7e6f69ce22a4606761ef35d9080eaa39a1e62cbd.zip
FreeBSD-src-7e6f69ce22a4606761ef35d9080eaa39a1e62cbd.tar.gz
o Regression test to check that appropriate parts of the process
credential are used in the access() and new eaccess() system calls. Obtained from: TrustedBSD Project
Diffstat (limited to 'tools')
-rw-r--r--tools/regression/security/access/Makefile9
-rw-r--r--tools/regression/security/access/testaccess.c360
2 files changed, 369 insertions, 0 deletions
diff --git a/tools/regression/security/access/Makefile b/tools/regression/security/access/Makefile
new file mode 100644
index 0000000..4b8039f
--- /dev/null
+++ b/tools/regression/security/access/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+PROG= testaccess
+NOMAN= yes
+
+SRCS= testaccess.c
+CFLAGS += -Wall
+
+.include <bsd.prog.mk>
diff --git a/tools/regression/security/access/testaccess.c b/tools/regression/security/access/testaccess.c
new file mode 100644
index 0000000..bd6945e
--- /dev/null
+++ b/tools/regression/security/access/testaccess.c
@@ -0,0 +1,360 @@
+/*-
+ * Copyright (c) 2001 Networks Associates Technologies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Written at NAI Labs at Network Associates by Robert Watson for the
+ * TrustedBSD Project.
+ *
+ * Work sponsored by Defense Advanced Research Projects Agency under the
+ * CHATS research program, CBOSS project.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/*
+ * Regression test to check some basic cases and see if access() and
+ * eaccess() are using the correct portions of the process credential.
+ * This test relies on running with privilege, and on UFS file system
+ * semantics. Running the test in other environments may result
+ * in incorrect failure identification.
+ *
+ * Note that this may also break if file system access control is
+ * broken, or if the ability to check and set credentials is broken.
+ *
+ * Note that this test uses two hard-coded non-root UIDs; on multi-user
+ * systems, these UIDs may be in use by an untrusted user, in which
+ * case those users could interfere with the test.
+ */
+
+#define ROOT_UID (uid_t)0
+#define WHEEL_GID (gid_t)0
+#define TEST_UID_ONE (uid_t)500
+#define TEST_GID_ONE (gid_t)500
+#define TEST_UID_TWO (uid_t)501
+#define TEST_GID_TWO (gid_t)501
+
+struct file_description {
+ char *fd_name;
+ uid_t fd_owner;
+ gid_t fd_group;
+ mode_t fd_mode;
+};
+
+static struct file_description fd_list[] = {
+{"test1", ROOT_UID, WHEEL_GID, 0400},
+{"test2", TEST_UID_ONE, WHEEL_GID,0400},
+{"test3", TEST_UID_TWO, WHEEL_GID, 0400},
+{"test4", ROOT_UID, WHEEL_GID, 0040},
+{"test5", ROOT_UID, TEST_GID_ONE, 0040},
+{"test6", ROOT_UID, TEST_GID_TWO, 0040}};
+
+static int fd_list_count = sizeof(fd_list) /
+ sizeof(struct file_description);
+
+int
+setup(void)
+{
+ int i, error;
+
+ for (i = 0; i < fd_list_count; i++) {
+ error = open(fd_list[i].fd_name, O_CREAT | O_EXCL, fd_list[i].fd_mode);
+ if (error == -1) {
+ perror("open");
+ return (error);
+ }
+ close(error);
+ error = chown(fd_list[i].fd_name, fd_list[i].fd_owner,
+ fd_list[i].fd_group);
+ if (error) {
+ perror("chown");
+ return (error);
+ }
+ }
+ return (0);
+}
+
+int
+restoreprivilege(void)
+{
+ int error;
+
+ error = setreuid(ROOT_UID, ROOT_UID);
+ if (error)
+ return (error);
+
+ error = setregid(WHEEL_GID, WHEEL_GID);
+ if (error)
+ return (error);
+
+ return (0);
+}
+
+int
+reportprivilege(char *message)
+{
+ uid_t euid, ruid, suid;
+ gid_t egid, rgid, sgid;
+ int error;
+
+ error = getresuid(&ruid, &euid, &suid);
+ if (error) {
+ perror("getresuid");
+ return (error);
+ }
+
+ error = getresgid(&rgid, &egid, &sgid);
+ if (error) {
+ perror("getresgid");
+ return (error);
+ }
+
+ if (message)
+ printf("%s: ", message);
+ printf("ruid: %d, euid: %d, suid: %d, ", ruid, euid, suid);
+ printf("rgid: %d, egid: %d, sgid: %d\n", rgid, egid, sgid);
+
+ return (0);
+}
+
+int
+cleanup(void)
+{
+ int i, error;
+
+ error = restoreprivilege();
+ if (error) {
+ perror("restoreprivilege");
+ return (error);
+ }
+
+ for (i = 0; i < fd_list_count; i++) {
+ error = unlink(fd_list[i].fd_name);
+ if (error)
+ return (error);
+ }
+
+ return (0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int error, errorseen;
+
+ if (geteuid() != 0) {
+ fprintf(stderr, "testaccess must run as root.\n");
+ exit (EXIT_FAILURE);
+ }
+
+ error = setup();
+ if (error) {
+ cleanup();
+ exit (EXIT_FAILURE);
+ }
+
+ /* Make sure saved uid is set appropriately. */
+ error = setresuid(ROOT_UID, ROOT_UID, ROOT_UID);
+ if (error) {
+ perror("setresuid");
+ cleanup();
+ }
+
+ /* Clear out additional groups. */
+ error = setgroups(0, NULL);
+ if (error) {
+ perror("setgroups");
+ cleanup();
+ }
+
+ /* Make sure saved gid is set appropriately. */
+ error = setresgid(WHEEL_GID, WHEEL_GID, WHEEL_GID);
+ if (error) {
+ perror("setresgid");
+ cleanup();
+ }
+
+ /*
+ * UID-only tests.
+ */
+
+ /* Check that saved uid is not used */
+ error = setresuid(TEST_UID_ONE, TEST_UID_ONE, ROOT_UID);
+ if (error) {
+ perror("setresuid.1");
+ cleanup();
+ exit (EXIT_FAILURE);
+ }
+
+ errorseen = 0;
+
+ error = access("test1", R_OK);
+ if (!error) {
+ fprintf(stderr, "saved uid used instead of real uid\n");
+ errorseen++;
+ }
+
+#ifdef EACCESS_AVAILABLE
+ error = eaccess("test2", R_OK);
+ if (!error) {
+ fprintf(stderr, "saved uid used instead of effective uid\n");
+ errorseen++;
+ }
+#endif
+
+ error = restoreprivilege();
+ if (error) {
+ perror("restoreprivilege");
+ cleanup();
+ exit (EXIT_FAILURE);
+ }
+
+ error = setresuid(TEST_UID_ONE, TEST_UID_TWO, ROOT_UID);
+ if (error) {
+ perror("setresid.2");
+ cleanup();
+ exit (EXIT_FAILURE);
+ }
+
+ /* Check that the real uid is used, not the effective uid */
+ error = access("test2", R_OK);
+ if (error) {
+ fprintf(stderr, "Effective uid was used instead of real uid in access().\n");
+ errorseen++;
+ }
+
+#ifdef EACCESS_AVAILABLE
+ /* Check that the effective uid is used, not the real uid */
+ error = eaccess("test3", R_OK);
+ if (error) {
+ fprintf(stderr, "Real uid was used instead of effective uid in eaccess().\n");
+ errorseen++;
+ }
+#endif
+
+ /* Check that the real uid is used, not the effective uid */
+ error = access("test3", R_OK);
+ if (!error) {
+ fprintf(stderr, "Effective uid was used instead of real uid in access().\n");
+ errorseen++;
+ }
+
+#ifdef EACCESS_AVAILABLE
+ /* Check that the effective uid is used, not the real uid */
+ error = eaccess("test2", R_OK);
+ if (error) {
+ fprintf(stderr, "Real uid was used instead of effective uid in eaccess().\n");
+ errorseen++;
+ }
+#endif
+
+ error = restoreprivilege();
+ if (error) {
+ perror("restoreprivilege");
+ cleanup();
+ exit (EXIT_FAILURE);
+ }
+
+ error = setresgid(TEST_GID_ONE, TEST_GID_TWO, WHEEL_GID);
+ if (error) {
+ perror("setresgid.1");
+ cleanup();
+ exit (EXIT_FAILURE);
+ }
+
+ /* Set non-root effective uid to avoid excess privilege. */
+ error = setresuid(TEST_UID_ONE, TEST_UID_ONE, ROOT_UID);
+ if (error) {
+ perror("setresuid.3");
+ cleanup();
+ exit (EXIT_FAILURE);
+ }
+
+ /* Check that the saved gid is not used */
+ error = access("test4", R_OK);
+ if (!error) {
+ fprintf(stderr, "saved gid used instead of real gid\n");
+ }
+
+#ifdef EACCESS_AVAILABLE
+ error = eaccess("test4", R_OK);
+ if (!error) {
+ fprintf(stderr, "saved gid used instead of effective gid\n");
+ errorseen++;
+ }
+#endif
+
+ /* Check that the real gid is used, not the effective gid */
+ error = access("test5", R_OK);
+ if (error) {
+ fprintf(stderr, "Effective gid was used instead of real gid in access().\n");
+ errorseen++;
+ }
+
+#ifdef EACCESS_AVAILABLE
+ /* Check that the effective gid is used, not the real gid */
+ error = eaccess("test6", R_OK);
+ if (error) {
+ fprintf(stderr, "Real gid was used instead of effective gid in eaccess().\n");
+ errorseen++;
+ }
+#endif
+
+ /* Check that the real gid is used, not the effective gid */
+ error = access("test6", R_OK);
+ if (!error) {
+ fprintf(stderr, "Effective gid was used instead of real gid in access().\n");
+ errorseen++;
+ }
+
+#ifdef EACCESS_AVAILABLE
+ /* Check that the effective gid is used, not the real gid */
+ error = eaccess("test5", R_OK);
+ if (!error) {
+ fprintf(stderr, "Real gid was used instead of effective gid in eaccess().\n");
+ errorseen++;
+ }
+#endif
+
+ fprintf(stderr, "%d errors seen.\n", errorseen);
+
+ /*
+ * All tests done, restore and clean up
+ */
+
+ error = cleanup();
+ if (error) {
+ perror("cleanup");
+ exit (EXIT_FAILURE);
+ }
+
+ exit (EXIT_SUCCESS);
+}
OpenPOWER on IntegriCloud