[tomoyo-users-en 534] Re: Suggestion for CaitSith about generalizedactions (pivot_root)

Back to archive index
Tetsuo Handa from-****@I-lov*****
Wed Jan 2 13:53:09 JST 2013


do1****@yande***** wrote:
> 31.12.2012, 15:18, "Tetsuo Handa" <from-****@I-lov*****>:
> >
> > What if filesystem namespace is unshared and pivot_root is used for bringing
> > /home/backup to somewhere else?
> 
> What will happen? I verified by experiment that when I have

See http://www.kernel.org/doc/man-pages/online/pages/man2/pivot_root.2.html for
manual. Below is a demo program.

---------- demo.c start ----------
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mount.h>
#include <sched.h>
#include <errno.h>
int pivot_root(const char *new_root, const char *put_old);

int main(int argc, char *argv[])
{
	/* Unshare mount namespace */
	{
		if (unshare(CLONE_NEWNS)) {
			const int err = errno;
			fprintf(stderr, "unshare() failed: %d\n", err);
			return 1;
		}
	}
	/* Mount tmpfs on /tmp */
	{
		if (mount("none", "/tmp", "tmpfs", 0, NULL)) {
			const int err = errno;
			fprintf(stderr, "mount() failed: %d\n", err);
			return 1;
		}
	}
	/* Create /tmp/dir/ */
	{
		if (mkdir("/tmp/dir", 0755)) {
			const int err = errno;
			fprintf(stderr, "mkdir() failed: %d\n", err);
			return 1;
		}
	}
	/* Create /tmp/file */
	{
		const int fd = open("/tmp/file", O_CREAT | O_WRONLY, 0644);
		if (fd == EOF || write(fd, "hello\n", 6) != 6 || close(fd)) {
			const int err = errno;
			fprintf(stderr, "open()/write()/close() failed: %d\n",
				err);
			return 1;
		}
	}
	/* /tmp/file was accessible as /tmp/file */
	{
		char c;
		const int fd = open("/tmp/file", O_RDONLY, 0666);
		if (fd == EOF) {
			const int err = errno;
			fprintf(stderr, "open(\"/tmp/file\") failed: %d\n",
				err);
			return 1;
		}
		fprintf(stderr, "Content of /tmp/file\n");
		while (read(fd, &c, 1) == 1 && write(1, &c, 1));
		close(fd);
	}
	/* Make /tmp/ the new / */
	{
		if (pivot_root("/tmp/", "/tmp/dir/")) {
			const int err = errno;
			fprintf(stderr, "pivot_root() failed: %d\n", err);
			return 1;
		}
	}
	/* /tmp/file is now accessible as /file */
	{
		char c;
		const int fd = open("/file", O_RDONLY);
		if (fd == EOF) {
			const int err = errno;
			fprintf(stderr, "open(\"/file\") failed: %d\n", err);
			return 1;
		}
		fprintf(stderr, "Content of /file\n");
		while (read(fd, &c, 1) == 1 && write(1, &c, 1));
		close(fd);
	}
	return 0;
}
---------- demo.c end ----------

Usage of this demo program is:

(Step 1) Compile this demo program.

  # gcc -Wall -O3 -o a.out demo.c

(Step 2) Add CaitSith's policy that audits reading files on tmpfs.

  # echo 'quota audit[0] allowed=0 denied=1024 unmatched=1024' | caitsith-loadpolicy
  # echo '1 acl read path.fsmagic=0x01021994' | caitsith-loadpolicy

(Step 3) Discard the CaitSith's audit log.

  # cat /proc/caitsith/audit > /dev/null

(Step 4) Run this demo program.

  # ./a.out

(Step 5) Check the CaitSith's audit log.

 # cat /proc/caitsith/audit

An example of audit log looks like

  #2013/01/02 04:41:58# global-pid=1298 result=unmatched priority=1 / read path="/tmp/file" task.pid=1298 task.ppid=1262 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/root/a.out" task.domain="<kernel>" path.uid=0 path.gid=0 path.perm=0644 path.type=file path.ino=9374 path.major=0 path.minor=21 path.fsmagic=0x1021994 path.parent.uid=0 path.parent.gid=0 path.parent.perm=01777 path.parent.ino=9372 path.parent.major=0 path.parent.minor=21 path.parent.fsmagic=0x1021994
  #2013/01/02 04:41:58# global-pid=1298 result=unmatched priority=1 / read path="/file" task.pid=1298 task.ppid=1262 task.uid=0 task.gid=0 task.euid=0 task.egid=0 task.suid=0 task.sgid=0 task.fsuid=0 task.fsgid=0 task.type!=execute_handler task.exe="/root/a.out" task.domain="<kernel>" path.uid=0 path.gid=0 path.perm=0644 path.type=file path.ino=9374 path.major=0 path.minor=21 path.fsmagic=0x1021994 path.parent.uid=0 path.parent.gid=0 path.parent.perm=01777 path.parent.ino=9372 path.parent.major=0 path.parent.minor=21 path.parent.fsmagic=0x1021994

where the difference is only value of "path" variable.

You will find that the location of a file has changed by pivot_root and you
will also find that the inode's attributes (e.g. path.ino ) remain unchanged.

The pathname calculation logic used by TOMOYO, AppArmor, AKARI and CaitSith is
not affected by chroot but is affected by pivot_root .

> 
> 1 acl create path="/home/backup/data1/\(\*\)/\*"
>   1 deny
> 
> And I do `chroot /home/backup /touch /data1/x` I have access properly denied as expected by me. Realpath seems properly accounted for chroot.
> 
> 2013/01/01 11:17:37# global-pid=31896 result=denied priority=1 / create path="/home/backup/data1/x"  ... task.exe="/home/backup/touch" task.domain="/usr/sbin/sshd" ...
> 
> So I don't need to care about pivot_root in my case.

You tested chroot case but didn't test pivot_root case.
You need to care about pivot_root in your case.




More information about the tomoyo-users-en mailing list
Back to archive index