Discussion:
[tomoyo-users-en 681] [caitsith] relative paths in symlink's target and domain transition
Torsten Wörtwein
2017-07-05 18:49:26 UTC
Permalink
Hi,

I encountered an unexpected behavior with symlinks:

1 acl symlink target="/home/user/secret_file"
audit 1
1 deny

$ ln -s /home/user/secret_file test
ln: failed to create symbolic link 'test': Operation not permitted

fails, while

$ cd /home/user
$ ln -s secret_file test test

is successful. Shouldn't both requests be denied as both create a
symlink to the same file?


Independent of that, it is often difficult to debug what the parent
process is if the parent (and child) process are no longer running.
This is mainly interesting when, e.g., /usr/bin/bash wants to perform
some action but you only want to allow /usr/bin/bash's action if it
is called by a trusted process. During rule creation, this trusted
parent process is not known (assume you want to protect a group of
objects). Therefore, I thought the following might be helpful to easily
determine the parent process:

1 acl execute
1 allow transition=task.exe

Unfortunately, this doesn't match anything (adding '2 deny' prevents
any execution).

Lastly, it might be good for visibility to include caitsith in your
comparison on http://tomoyo.osdn.jp/wiki-e/?WhatIs#comparison

Thanks,
Torsten
Tetsuo Handa
2017-07-06 10:14:33 UTC
Permalink
Post by Torsten Wörtwein
Hi,
1 acl symlink target="/home/user/secret_file"
audit 1
1 deny
$ ln -s /home/user/secret_file test
ln: failed to create symbolic link 'test': Operation not permitted
fails, while
$ cd /home/user
$ ln -s secret_file test test
is successful. Shouldn't both requests be denied as both create a
symlink to the same file?
Symlink is just a file containing some string which will be interpreted
as pathname upon pathname resolution.

You might think that CaitSith should be able to understand that
"ln -s secret_file test" will create a symlink to /home/user/secret_file
because the caller's current directory is /home/user . But it is legal to
create a symlink which refers to some pathname which does not exist as of
creating that symlink. For example, how will CaitSith be able to determine
whether "ln -s foo/../bar/../baz/secret_file test" will create a symlink to
/home/user/secret_file when foo and/or bar and/or baz do not exist, even if
the caller's current directory is /home/user ? The kernel should not try to
interpret "foo/../bar/../baz/secret_file" when a symlink is created. Hence,
it is impossible for CaitSith to deny "ln -s secret_file test" without

1 acl symlink target="secret_file"
audit 1
1 deny

entry.
Post by Torsten Wörtwein
Independent of that, it is often difficult to debug what the parent
process is if the parent (and child) process are no longer running.
I could not understand what you are trying to do.

What does parent/child process refer? Guessing from "no longer running"
(i.e. already terminated), is it about PID relation (e.g. task.ppid, task.pid) ?
Post by Torsten Wörtwein
This is mainly interesting when, e.g., /usr/bin/bash wants to perform
some action but you only want to allow /usr/bin/bash's action if it
is called by a trusted process. During rule creation, this trusted
parent process is not known (assume you want to protect a group of
objects). Therefore, I thought the following might be helpful to easily
1 acl execute
1 allow transition=task.exe
If it is about domainname (e.g. /path/to/some/trusted/application /usr/bin/bash
in TOMOYO), why can't task.domain be used for determining whether /usr/bin/bash
is called by a trusted process?
Post by Torsten Wörtwein
Unfortunately, this doesn't match anything (adding '2 deny' prevents
any execution).
Please be sure to check whether some syntax is accepted by CaitSith, for
CaitSith will ignore invalid lines. By comparing on-memory policy (i.e.
output of "/usr/sbin/caitsith-savepolicy -") of before making changes and
after making changes, you can determine whether changes are accepted by
CaitSith.
Post by Torsten Wörtwein
Lastly, it might be good for visibility to include caitsith in your
comparison on http://tomoyo.osdn.jp/wiki-e/?WhatIs#comparison
Maybe, but after CaitSith is accepted to mainline.
Joining reviews at LSM mailing list is welcomed.
Torsten Wörtwein
2017-07-09 08:31:51 UTC
Permalink
thanks for the clarifications on symlinks.

Sorry for describing the second question not good enough. I try to
explain it at an example. Let's assume you want to observe which
programs access files in /sys. The goal would be to prevent programs
to access files which they have not accessed during the learning
phase. If /usr/lib/systemd/systemd accesses a certain file in /sys, you
can then allow this action for /usr/lib/systemd/systemd in the future.
However, if /usr/bin/python (or some other interpreter) requests access
you might not want to allow this action solely based on task.exe because
the behavior of /usr/bin/python depends on how it is called. For
simplicity, let's assume we are fine with allowing /usr/bin/python to
perform the requested action if it is called by /usr/bin/trusted_exe
('trusted_exe' is meant as a placeholder, we don't know the parent
process of /usr/bin/python yet). If the parent process is still running,
you can simply look up what process is behind task.ppid (logged through
caitsith-auditd). Based on this, you can assign a domain
to /usr/bin/python if it is called by this specific process.

If the parent process is not running anymore, you cannot look up
task.ppid anymore. Therefore, I thought it might be helpful to create a
rule to set task.exe as the domain to transition to. Thereby, it is
obvious who called /usr/bin/python when an action of it is logged
through caitsith-auditd. As task.exe represents a string and as
'transition' takes a (constant?) string, I thought the following would
work:

1 acl execute
1 allow transition=task.exe

I guess it is easier to find possible parent processes with
tomoyo and then create domain transitions for the identified parent in
caitsith.

Great, that you are trying to mainline caitsith - good luck! I don't
think I'm qualified to join the review process.

Thanks,
Torsten

On Thu, 6 Jul 2017 19:14:33 +0900 Tetsuo Handa
Post by Tetsuo Handa
Post by Torsten Wörtwein
Hi,
1 acl symlink target="/home/user/secret_file"
audit 1
1 deny
$ ln -s /home/user/secret_file test
ln: failed to create symbolic link 'test': Operation not permitted
fails, while
$ cd /home/user
$ ln -s secret_file test test
is successful. Shouldn't both requests be denied as both create a
symlink to the same file?
Symlink is just a file containing some string which will be
interpreted as pathname upon pathname resolution.
You might think that CaitSith should be able to understand that
"ln -s secret_file test" will create a symlink
to /home/user/secret_file because the caller's current directory
is /home/user . But it is legal to create a symlink which refers to
some pathname which does not exist as of creating that symlink. For
example, how will CaitSith be able to determine whether "ln -s
foo/../bar/../baz/secret_file test" will create a symlink
to /home/user/secret_file when foo and/or bar and/or baz do not
exist, even if the caller's current directory is /home/user ? The
kernel should not try to interpret "foo/../bar/../baz/secret_file"
when a symlink is created. Hence, it is impossible for CaitSith to
deny "ln -s secret_file test" without
1 acl symlink target="secret_file"
audit 1
1 deny
entry.
Post by Torsten Wörtwein
Independent of that, it is often difficult to debug what the parent
process is if the parent (and child) process are no longer
running.
I could not understand what you are trying to do.
What does parent/child process refer? Guessing from "no longer
running" (i.e. already terminated), is it about PID relation (e.g.
task.ppid, task.pid) ?
Post by Torsten Wörtwein
This is mainly interesting when, e.g., /usr/bin/bash wants to
perform some action but you only want to allow /usr/bin/bash's
action if it is called by a trusted process. During rule creation,
this trusted parent process is not known (assume you want to
protect a group of objects). Therefore, I thought the following
1 acl execute
1 allow transition=task.exe
If it is about domainname
(e.g. /path/to/some/trusted/application /usr/bin/bash in TOMOYO), why
can't task.domain be used for determining whether /usr/bin/bash is
called by a trusted process?
Post by Torsten Wörtwein
Unfortunately, this doesn't match anything (adding '2 deny' prevents
any execution).
Please be sure to check whether some syntax is accepted by CaitSith,
for CaitSith will ignore invalid lines. By comparing on-memory policy
(i.e. output of "/usr/sbin/caitsith-savepolicy -") of before making
changes and after making changes, you can determine whether changes
are accepted by CaitSith.
Post by Torsten Wörtwein
Lastly, it might be good for visibility to include caitsith in your
comparison on http://tomoyo.osdn.jp/wiki-e/?WhatIs#comparison
Maybe, but after CaitSith is accepted to mainline.
Joining reviews at LSM mailing list is welcomed.
Tetsuo Handa
2017-07-09 13:09:04 UTC
Permalink
Post by Torsten Wörtwein
I guess it is easier to find possible parent processes with
tomoyo and then create domain transitions for the identified parent in
caitsith.
Yes, recording possible patterns using TOMOYO and then create rules for
CaitSith will be easier. Since you can run TOMOYO and CaitSith in parallel,
you can use TOMOYO (or AKARI) for recording possible patterns.

Also, there was TaskTracker LSM module dedicated for recording parent/child
relations with timestamp at
https://www.redhat.com/archives/linux-audit/2014-June/msg00091.html .
Since security_task_alloc() hook was revived, it might be time to propose
TaskTracker LSM module again.

By the way, there was proposal of shebang LSM module which attempts to restrict
invocation of python interpreter. You might find some hints from the thread at
http://kernsec.org/pipermail/linux-security-module-archive/2017-June/001758.html .
Loading...