* New LSM security operation
@ 2007-07-12 3:38 Zeus Gómez Marmolejo
2007-07-12 18:17 ` Serge E. Hallyn
0 siblings, 1 reply; 4+ messages in thread
From: Zeus Gómez Marmolejo @ 2007-07-12 3:38 UTC (permalink / raw)
To: linux-kernel
Hi people,
I've looked around on how to hide inodes in a Linux filesystem but
surprisingly the kernel lacks this functionality. It would be desirable
for me to add an ACL to a file in order not to be seen in the directory
contents but only for some users.
Some Selinux experts point out that the correct way to do this is via
poly-instantiated directories such as /tmp or /var/tmp, so each user
"view" his own version of this directory. But that's not what I want,
for example in /etc, I would want to hide some directories or files for
some users. I don't want a whole /etc instantiation for each user logged in.
Also, there is a patch called LIDS that does the thing, but patching the
whole kernel and adding much extra functionality such as intrussion
detection system as it is. Some rootkits -like adore- also can hide
inodes, but changing the owner to an uid that the kernel module hides
from the system call. I don't thing this is a good approach...
For me, the correct way to achieve this is to add an extra op in the
"security_operations" struct, as an inode operation. With this, a
Mandatory Access Control system that uses LSM such as SELinux can add
some policies on the "list" file access vector.
So, I'd call this hook in the vfs_readdir() syscall just after the "file
<http://lxr.linux.no/ident?i=file>->f_op->readdir()" -the particular
filesystem readdir()- and walk through the list to ask for each inode if
it has permission to be "listed" in that directory. Then, the MAC system
can handle the grant or deny permission per inode, and then return the
"modified" list to userspace.
I'm not sure if this is the correct way, or maybe it adds to much
overhead to the "ls" command, but I'd like to hear some opinions, I can
try to code it and summit a patch...
Thanks for your answer,
Zeus Gómez.
PS. Please, include me in the CC if you reply this message.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: New LSM security operation
[not found] <986851.77016.qm@web36607.mail.mud.yahoo.com>
@ 2007-07-12 5:21 ` Zeus Gómez Marmolejo
0 siblings, 0 replies; 4+ messages in thread
From: Zeus Gómez Marmolejo @ 2007-07-12 5:21 UTC (permalink / raw)
To: casey; +Cc: linux-kernel
> Lets run a thought experiment on this notion...
>
> Let's say that the file you want to hide is "/etc/dangerous".
> One of your fellows decides to create a file for other purposes
> and decides to call it "/etc/dangerous", having looked in /etc
> and seeing no file with that name. What should happen when he
> calls open("/etc/dangerous", O_CREAT) :
>
> 1. a second /etc/dangerous is created
> 2. the open fails, returning EEXISTS
> 3. the open succeeds, silently replacing the old file
>
> Option 1 results in two files with the same name. True,
> AppArmor can handle this, but I think everyone else
> is going to have issues with it. Option 2 defeats the idea
> of the file being hidden. Option 3 is just bad.
>
I don't see much problem on this. For me, the correct response is that
one that just forget the "hidden" attribute, in that case if the user
have the permission of overwritting the file, then the open succeeds,
replacing the old file. In the other case, if the "list permission" and
the "create permission" are denied the open fails. We can discuss in
this case if with an EEXISTS or EACCES... Nevertheless I think it's a
good idea, the same happens when a file is "read protected" and "list
protected", and the user want to open the file for reading it. It could
be: EACCESS or even ENOENT...
Just think about how useful would be in the /proc directory. For now,
applying the selinux policy and doing "ls /proc", it reports errors on
directories not owned by you because it cann't getattr() on them, but
you can even know how many processes are running and even their pids.
You have to apply an extra patch like Grsecurity to don't list the pids
that are not owned by you in /proc. With this hook, this won't be
necessary, just with a correct policy it can be done.
Zeus.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: New LSM security operation
2007-07-12 3:38 Zeus Gómez Marmolejo
@ 2007-07-12 18:17 ` Serge E. Hallyn
0 siblings, 0 replies; 4+ messages in thread
From: Serge E. Hallyn @ 2007-07-12 18:17 UTC (permalink / raw)
To: Zeus Gómez Marmolejo; +Cc: linux-kernel
Quoting Zeus Gómez Marmolejo (zeus@aluzina.org):
> Hi people,
>
> I've looked around on how to hide inodes in a Linux filesystem but
> surprisingly the kernel lacks this functionality. It would be desirable
> for me to add an ACL to a file in order not to be seen in the directory
> contents but only for some users.
>
> Some Selinux experts point out that the correct way to do this is via
> poly-instantiated directories such as /tmp or /var/tmp, so each user
> "view" his own version of this directory. But that's not what I want,
> for example in /etc, I would want to hide some directories or files for
> some users. I don't want a whole /etc instantiation for each user logged in.
>
> Also, there is a patch called LIDS that does the thing, but patching the
> whole kernel and adding much extra functionality such as intrussion
> detection system as it is. Some rootkits -like adore- also can hide
> inodes, but changing the owner to an uid that the kernel module hides
> from the system call. I don't thing this is a good approach...
>
> For me, the correct way to achieve this is to add an extra op in the
> "security_operations" struct, as an inode operation. With this, a
> Mandatory Access Control system that uses LSM such as SELinux can add
> some policies on the "list" file access vector.
That's how it is often done elsewhere, but (at least until now) the
correct way to achieve this in Linux is to make use of either
per-process namespaces or chroots. For example, either create custom fs
trees for each user under /share/ and chroot user hallyn under /share/hallyn
upon login, or, upon login, create a new mounts namespace and massage
the fs tree there.
For persistant filesystems, you can of course keep custom versions of
the filesystems in hidden directories. I.e. under /tmp/ you could
keep /tmp/.priv/hallyn, and, when hallyn logs in, do
mount --bind /tmp/.priv/hallyn /tmp
or if you're going the /share route, just do
mount --bind /share/hallyn/tmp/.priv/hallyn /share/hallyn/tmp
while setting up your trees after boot.
For procfs and sysfs, the containers (specifically process id namespaces
and network namespaces) are starting some of the work to support
showing only authorized data to containers.
-serge
> So, I'd call this hook in the vfs_readdir() syscall just after the "file
> <http://lxr.linux.no/ident?i=file>->f_op->readdir()" -the particular
> filesystem readdir()- and walk through the list to ask for each inode if
> it has permission to be "listed" in that directory. Then, the MAC system
> can handle the grant or deny permission per inode, and then return the
> "modified" list to userspace.
>
> I'm not sure if this is the correct way, or maybe it adds to much
> overhead to the "ls" command, but I'd like to hear some opinions, I can
> try to code it and summit a patch...
>
> Thanks for your answer,
>
> Zeus Gómez.
> PS. Please, include me in the CC if you reply this message.
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: New LSM security operation
[not found] <883505.60477.qm@web36609.mail.mud.yahoo.com>
@ 2007-07-13 2:42 ` Zeus Gómez Marmolejo
0 siblings, 0 replies; 4+ messages in thread
From: Zeus Gómez Marmolejo @ 2007-07-13 2:42 UTC (permalink / raw)
To: casey; +Cc: linux-kernel, linux-security-module
>
> An application that is careful not to destroy existing information
> would not be able to prevent itself from doing so if the file is
> hidden. Its pretty important to avoid defeating programs that are
> trying to behave properly.
>
It's true what you are saying... But I think the best way to know if
there is an existing file with that name is by the stat() syscall, not
reading the contents of the directory, by the way is very inefficient if
there are a lot of files in that directory.
For example, the editor "vi" when editing a file "p1.c" and saving with
":w p2.c" it searches first if this file exists with:
stat64("p2.c", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
(... just verified it with strace). I think doing this is the best way,
and most programs do that in this way.
On the other hand, I'm only talking about modifying the: "sys_readdir",
"sys_getdents" and "sys_getdents64" system calls, all implemented in the
"fs/readdir.c" file.
In fact, I've tried to code it, and I think it's best done in the
"filldir()" callback, called each time that an entry in the directory is
found by the underlying filesystem walk. Just check if this entry is
permitted to list and then return without adding it into the buffer. I
tried this (in fs/readdir.c, filldir64()):
static int filldir64(void * __buf, const char * name, int namlen,
loff_t offset, u64 ino, unsigned int d_type)
{
struct linux_dirent64 __user *dirent;
struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf;
int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 1, sizeof(u64));
+ int res;
+
+ res = security_inode_list( buf->i_dir, iget(buf->sb, ino) );
+ if (res)
+ return 0;
buf->error = -EINVAL; /* only used if we fail.. */
...
}
Adding two members in the callback structure (sb and i_dir) with the
superblock and inode of the parent directory.
This works in all filesystems with a superblock, but for example in
sysfs, the operation iget() segfaults because can't search for an inode
using the superblock operations, because it doesn't have the
read_inode() operation.
Is there any other way to obtain the "struct inode *" from the inode
number, without using the superblock operations!?
>
> In the open-for-read case returning an error other than ENOENT gives
> away the existance of the file. Returning ENOENT is a lie, so is just
> wrong.
>
OK. But maybe is what the administrator wants to return to the user. If
the file is not readable or writable and not listable by some user, then
for him simply doesn't exist... But, I don't care... if we are
consistent with what we are doing, the correct thing is to return an
EACCES because of the forbidding read.
>
> Sounds to me like the problem you're out to solve is specific to
> ls under SELinux. Fixing* ls is straitforward, don't say anything
> about directory entries you don't have access to rather than the
> current annoying error messages. Fixing* SELinux may be an option,
> you may even be able to achieve what you're after using the current
> mechanisms. The SELinux mailing list might be worth cross-posting.
>
I don't think this is a "ls" problem. The fact is if some user wants to
know the pid names or some other directory entries, he just have to
compile his version of "ls" and would get all this names because the
getdents() system call is showing them.
I think they are different policies, one is getting the attributes of a
given file (that is what SELinux can forbid) and then this is why "ls
-l" complains about showing them. But the other policy is just not
showing the file, but you may get the permissions if you really know the
name: "ls -l /etc/abadbad", this is not possible with SELinux nor with
other security module because the Linux SM framework just lack the hook
to avoid doing this listing.
Thank you for your comments!!
Zeus.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2007-07-13 3:10 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <986851.77016.qm@web36607.mail.mud.yahoo.com>
2007-07-12 5:21 ` New LSM security operation Zeus Gómez Marmolejo
[not found] <883505.60477.qm@web36609.mail.mud.yahoo.com>
2007-07-13 2:42 ` Zeus Gómez Marmolejo
2007-07-12 3:38 Zeus Gómez Marmolejo
2007-07-12 18:17 ` Serge E. Hallyn
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox