/*
 *   Copyright (c) International Business Machines  Corp., 2001
 *
 *   This program is free software;  you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
 *   the GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program;  if not, write to the Free Software
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/*
 *	Testcase to test whether chroot(2) sets errno correctly.
 *
 *	1.	Test for ENAMETOOLONG:
 *		Create a bad directory name with length more than
 *		VFS_MAXNAMELEN (Linux kernel variable), and pass it as the
 *		path to chroot(2).
 *
 *	2.	Test for ENOENT:
 *		Attempt to chroot(2) on a non-existent directory
 *
 *	3.	Test for ENOTDIR:
 *		Attempt to chdir(2) on a file.
 *
 *	4.	Test for EFAULT:
 *		The pathname parameter to chroot() points to an invalid address,
 *		chroot(2) fails with EPERM.
 *
 *	5.	Test for ELOOP:
 *		Too many symbolic links were encountered When resolving the
 *		pathname parameter.
 *
 *	07/2001 Ported by Wayne Boyer
 */

#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include "test.h"
#include <fcntl.h>
#include "safe_macros.h"

char *TCID = "chroot03";

static int fd;
static char fname[255];
static char good_dir[100] = "/tmp/testdir";
static char bad_dir[] = "abcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyzabcdefghijklmnopqrstmnopqrstuvwxyz";
static char symbolic_dir[] = "sym_dir1";

struct test_case_t {
	char *dir;
	int error;
} TC[] = {
	/*
	 * to test whether chroot() is setting ENAMETOOLONG if the
	 * pathname is more than VFS_MAXNAMELEN
	 */
	{
	bad_dir, ENAMETOOLONG},
	    /*
	     * to test whether chroot() is setting ENOTDIR if the argument
	     * is not a directory.
	     */
	{
	fname, ENOTDIR},
	    /*
	     * to test whether chroot() is setting ENOENT if the directory
	     * does not exist.
	     */
	{
	good_dir, ENOENT},
#if !defined(UCLINUX)
	    /*
	     * attempt to chroot to a path pointing to an invalid address
	     * and expect EFAULT as errno
	     */
	{
	(char *)-1, EFAULT},
#endif
	{symbolic_dir, ELOOP}
};

int TST_TOTAL = ARRAY_SIZE(TC);

static char *bad_addr;

static void setup(void);
static void cleanup(void);

int main(int ac, char **av)
{
	int lc;
	int i;
	const char *msg;

	msg = parse_opts(ac, av, NULL, NULL);
	if (msg != NULL)
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

	setup();

	for (lc = 0; TEST_LOOPING(lc); lc++) {
		tst_count = 0;

		for (i = 0; i < TST_TOTAL; i++) {
			TEST(chroot(TC[i].dir));

			if (TEST_RETURN != -1) {
				tst_resm(TFAIL, "call succeeded unexpectedly");
				continue;
			}

			if (TEST_ERRNO == TC[i].error) {
				tst_resm(TPASS | TTERRNO, "failed as expected");
			} else {
				tst_resm(TFAIL | TTERRNO,
					 "didn't fail as expected (expected errno "
					 "= %d : %s)",
					 TC[i].error, strerror(TC[i].error));
			}
		}
	}

	cleanup();
	tst_exit();
}

static void setup(void)
{
	tst_sig(NOFORK, DEF_HANDLER, cleanup);
	TEST_PAUSE;
	tst_tmpdir();

	/*
	 * create a file and use it to test whether chroot() is setting
	 * ENOTDIR if the argument is not a directory.
	 */
	(void)sprintf(fname, "tfile_%d", getpid());
	fd = creat(fname, 0777);
	if (fd == -1)
		tst_brkm(TBROK, cleanup, "Failed to creat a temp file");

	/*
	 * set up good_dir to test whether chroot() is setting ENOENT if the
	 * directory does not exist.
	 */
	(void)sprintf(good_dir, "%s.%d", good_dir, getpid());

#if !defined(UCLINUX)
	bad_addr = mmap(0, 1, PROT_NONE,
			MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
	if (bad_addr == MAP_FAILED)
		tst_brkm(TBROK, cleanup, "mmap failed");

	TC[3].dir = bad_addr;
#endif
	/*
	 * create two symbolic directory who point to each other to
	 * test ELOOP.
	 */
	SAFE_SYMLINK(cleanup, "sym_dir1/", "sym_dir2");
	SAFE_SYMLINK(cleanup, "sym_dir2/", "sym_dir1");
}

static void cleanup(void)
{
	close(fd);
	tst_rmdir();
}
