Re: [AppArmor 01/41] Pass struct vfsmount to the inode_create LSM hook

Tetsuo Handa
2007-05-26T01:40:49Z

Hello.

Casey Schaufler wrote:
> Sorry, but I don't understand your objection. If AppArmor is configured
> to allow everyone access to /bin/gzip but only some people access to
> /bin/gunzip and (important detail) the single binary uses argv[0]
> as documented and (another important detail) there aren't other links
> named gunzip to the binary (ok, that's lots of if's) you should be fine.

The argv[0] defines the default behavior of hard linked or symbolic linked programs,
but the behavior can be overridden using commandline options.
If you want to allow access to /bin/gzip but deny access to /bin/gunzip ,
you also need to deny access to "/bin/gzip -d" "/bin/gzip --decompress" "/bin/gzip --uncompress".
It is impossible to do so because options to override the default behavior
depends on program's design and you can't know
what programs and what options are there in the system.
Even if you know all programs and all options in the system,
it is a too tough job to find and reject options
that override the default behavior in the kernel space.

> > Well, my point was exactly that App Armor doesn't (as far as I know) do
> > anything to enforce the argv[0] convention,
> Sounds like an opportunity for improvement then.

There are (I think) three types of program invocation.

(1) Invocation of hard linked programs.

/bin/gzip and /bin/gunzip and /bin/zcat are hard links.

There is no problem because you can know which pathname was requested
using d_namespace_path() with "struct linux_binprm"->file .

(2) Invocation of symbolic linked programs.

/sbin/pidof is a symbolic link to /sbin/killall .

There is a problem because you can't know which pathname was requested
using d_namespace_path() with "struct linux_binprm"->file
because the symbolic links were already derefernced inside open_exec().
To know which pathname was requested, you need to lookup
using "struct linux_binprm"->filename without LOOKUP_FOLLOW
and then use d_namespace_path().
Although there is a race condition that the pathname
the symbolic link "struct linux_binprm"->filename points to
may change, but it is inevitable because you can't get
dentry and vfsmount of both "without LOOKUP_FOLLOW flag" and
"with LOOKUP_FOLLOW flag" at the same time.

(3) Invocation of dynamically created programs with random names.

/usr/sbin/logrotate creates files patterned /tmp/logrotate.??????
and executes these dynamically created files.

To keep execution of these dynamically created files under control,
you need to aggregate pathnames of these files.
AppArmor can't define profile if the pathname of programs is random, can it?

Usually the argv[0] and the "struct linux_binprm"->filename are the same,
but if you want to do something with argv[0], you will need to handle the (2) case
to see whether the argv[0] and "struct linux_binprm"->filename are the same.

Thanks.