2004-06-02 17:48:22

by mitya

[permalink] [raw]
Subject: 2.6.7-rc2: open() hangs on ReiserFS with SELinux enabled

Hello,

I tried enabling SELinux on my Linux-box, using ReiserFS as /, kernel
2.6.7-rc2.

After relabeling and rebooting in non-enforcing mode everything worked
well, exept the fact, that new files on reiserfs filesystems don't get
security attributes.

So I added 'fs_use_xattr reiserfs system_u:object_r:fs_t;' to the policy,
rebooted and found, that mount hangs during opening of /etc/mtab~<pid>
(even in non-enforcing mode).

If I remove that line from SELinux policy, systems boots up OK.

Here are last lines from #strace mount / -o remount :

=== Cut ===
open("/etc/mtab~202", O_WRONLY|O_CREAT|O_LARGEFILE, 0600audit(1085949484.378:0): avc: denied { write } for pid=202 exe=/bin/mount name=etc dev=hda5 ino=91 scontext=system_u:system_r:kernel_t tcontext=system_u:object_r:etc_t tclass=dir
audit(1085949484.378:0): avc: denied { add_name } for pid=202 exe=/bin/mount name=etc dev=hda5 ino=91 scontext=system_u:system_r:kernel_t tcontext=system_u:object_r:etc_t tclass=dir
audit(1085949484.378:0): avc: denied { create } for pid=202 exe=/bin/mount name=mtab~202 dev=hda5 ino=91 scontext=system_u:system_r:kernel_t tcontext=system_u:object_r:etc_t tclass=file
=== Cut ===

Tell me, if I need to provide any additional info.

--
With best wishes
Dmitry Baryshkov


2004-06-02 18:41:36

by Stephen Smalley

[permalink] [raw]
Subject: Re: 2.6.7-rc2: open() hangs on ReiserFS with SELinux enabled

On Wed, 2004-06-02 at 13:48, Dmitry Baryshkov wrote:
> Hello,
>
> I tried enabling SELinux on my Linux-box, using ReiserFS as /, kernel
> 2.6.7-rc2.
>
> After relabeling and rebooting in non-enforcing mode everything worked
> well, exept the fact, that new files on reiserfs filesystems don't get
> security attributes.
>
> So I added 'fs_use_xattr reiserfs system_u:object_r:fs_t;' to the policy,
> rebooted and found, that mount hangs during opening of /etc/mtab~<pid>
> (even in non-enforcing mode).
>
> If I remove that line from SELinux policy, systems boots up OK.
>
> Here are last lines from #strace mount / -o remount :
>
> === Cut ===
> open("/etc/mtab~202", O_WRONLY|O_CREAT|O_LARGEFILE, 0600audit(1085949484.378:0): avc: denied { write } for pid=202 exe=/bin/mount name=etc dev=hda5 ino=91 scontext=system_u:system_r:kernel_t tcontext=system_u:object_r:etc_t tclass=dir
> audit(1085949484.378:0): avc: denied { add_name } for pid=202 exe=/bin/mount name=etc dev=hda5 ino=91 scontext=system_u:system_r:kernel_t tcontext=system_u:object_r:etc_t tclass=dir
> audit(1085949484.378:0): avc: denied { create } for pid=202 exe=/bin/mount name=mtab~202 dev=hda5 ino=91 scontext=system_u:system_r:kernel_t tcontext=system_u:object_r:etc_t tclass=file
> === Cut ===
>
> Tell me, if I need to provide any additional info.

The mount process shouldn't be in kernel_t, although that shouldn't
cause a hang. Is /sbin/init labeled properly? Are you using the
patched /sbin/init that loads policy and then re-execs itself into the
proper security domain?

What output did you get from SELinux during initialization, particularly
for hda5?

When the mount process is hung, what output do you get from pressing
ALT-SysRq-t after enabling sysrq (echo 1 > /proc/sys/kernel/sysrq)?

Most likely location for a hang would be when post_create invokes
inode->i_op->setxattr to set the attribute on the newly created file.
Inode semaphore is taken around the call, as per other invocations of
inode->i_op->setxattr.

--
Stephen Smalley <[email protected]>
National Security Agency

2004-06-02 18:51:40

by Valdis Klētnieks

[permalink] [raw]
Subject: Re: 2.6.7-rc2: open() hangs on ReiserFS with SELinux enabled

On Wed, 02 Jun 2004 21:48:10 +0400, [email protected] (Dmitry Baryshkov) said:
> Hello,
>
> I tried enabling SELinux on my Linux-box, using ReiserFS as /, kernel
> 2.6.7-rc2.
>
> After relabeling and rebooting in non-enforcing mode everything worked
> well, exept the fact, that new files on reiserfs filesystems don't get
> security attributes.
>
> So I added 'fs_use_xattr reiserfs system_u:object_r:fs_t;' to the policy,
> rebooted and found, that mount hangs during opening of /etc/mtab~<pid>
> (even in non-enforcing mode).

Does your .config include CONFIG_REISERFS_FS_XATTR? Very Bad Things
are likely to happen if not.....


Attachments:
(No filename) (226.00 B)

2004-06-03 08:36:30

by mitya

[permalink] [raw]
Subject: Re: 2.6.7-rc2: open() hangs on ReiserFS with SELinux enabled

Hello,
On Wed, Jun 02, 2004 at 02:40:47PM -0400, Stephen Smalley wrote:
> On Wed, 2004-06-02 at 13:48, Dmitry Baryshkov wrote:
> > Hello,
>
> The mount process shouldn't be in kernel_t, although that shouldn't
> cause a hang. Is /sbin/init labeled properly? Are you using the
> patched /sbin/init that loads policy and then re-execs itself into the
> proper security domain?

Yes and no.
strace & cut was produced using manual booting to shell,
mount /proc
mount /selinux
load_policy /etc/security/selinux/policy.17
strace mount / -o remount,rw

>
> When the mount process is hung, what output do you get from pressing
> ALT-SysRq-t after enabling sysrq (echo 1 > /proc/sys/kernel/sysrq)?

Here is a part related to mount (sorry, it's copied by hand from
monitor. can't use serial console here.):

inode2sd+0xcc/0x120
pathrelse+0x20/0x30
reiserfs_update_sd_size+0x13a/0x1d0
rwsem_down_read_failed+0x8d/0x170
.text.lock.xattr+0xb5/0x22f
inode_doinit_with_dentry+0x2ea/0x560
d_instantiate+0x47/0x60
reiserfs_mkdir+0x29b/0x2d0
open_xa_dir+0xbe/0x160
get_xa_file_dentry+0x24/0x100
open_xa_file+0x5/0x40
reiserfs_xattr_set+0x8f/0x360
do_journal_end+0x75e/0xa70
vsprintf+0x12/0x20
sprintf+0x11/0x20
context_struct_to_string+0x108/0x170
reiserfs_setxattr+0xf4/0x190
post_create+0xfb/0x220
vfs_create+0xca/0x130
open_namei+0x3d0/0x420
filp_open+0x2d/0x60
sys_open+0x4d/0xa0
syscall_call+0x7/0xb

--
With best wishes
DMitry Baryshkov.

2004-06-03 14:10:04

by Stephen Smalley

[permalink] [raw]
Subject: Re: 2.6.7-rc2: open() hangs on ReiserFS with SELinux enabled

On Thu, 2004-06-03 at 04:36, Dmitry Baryshkov wrote:
> Here is a part related to mount (sorry, it's copied by hand from
> monitor. can't use serial console here.):
>
> inode2sd+0xcc/0x120
> pathrelse+0x20/0x30
> reiserfs_update_sd_size+0x13a/0x1d0
> rwsem_down_read_failed+0x8d/0x170
> .text.lock.xattr+0xb5/0x22f
> inode_doinit_with_dentry+0x2ea/0x560
> d_instantiate+0x47/0x60
> reiserfs_mkdir+0x29b/0x2d0
> open_xa_dir+0xbe/0x160
> get_xa_file_dentry+0x24/0x100
> open_xa_file+0x5/0x40
> reiserfs_xattr_set+0x8f/0x360
> do_journal_end+0x75e/0xa70
> vsprintf+0x12/0x20
> sprintf+0x11/0x20
> context_struct_to_string+0x108/0x170
> reiserfs_setxattr+0xf4/0x190
> post_create+0xfb/0x220
> vfs_create+0xca/0x130
> open_namei+0x3d0/0x420
> filp_open+0x2d/0x60
> sys_open+0x4d/0xa0
> syscall_call+0x7/0xb

Ok, so vfs_create calls security_inode_post_create hook, and SELinux
attempts to set the xattr on the newly created inode. But reiserfs
xattr implementation attempts to create a directory to store the xattr,
and the attempt to instantiate the dentry for the directory inode causes
the security_d_instantiate hook to be called, so that SELinux then
attempts to get the xattr value for that directory inode to initialize
the directory inode's security field before it becomes accessible via
the dcache. More generally, reiserfs_mkdir code is calling
d_instantiate while holding reiserfs_write_lock, but d_instantiate can
_block_ under SELinux due to need to fetch xattr for inode. See
http://marc.theaimsgroup.com/?l=linux-kernel&m=106712276514199&w=2 for
related discussion.

--
Stephen Smalley <[email protected]>
National Security Agency

2004-06-03 19:47:49

by Stephen Smalley

[permalink] [raw]
Subject: Re: 2.6.7-rc2: open() hangs on ReiserFS with SELinux enabled

On Thu, 2004-06-03 at 10:09, Stephen Smalley wrote:
> Ok, so vfs_create calls security_inode_post_create hook, and SELinux
> attempts to set the xattr on the newly created inode. But reiserfs
> xattr implementation attempts to create a directory to store the xattr,
> and the attempt to instantiate the dentry for the directory inode causes
> the security_d_instantiate hook to be called, so that SELinux then
> attempts to get the xattr value for that directory inode to initialize
> the directory inode's security field before it becomes accessible via
> the dcache. More generally, reiserfs_mkdir code is calling
> d_instantiate while holding reiserfs_write_lock, but d_instantiate can
> _block_ under SELinux due to need to fetch xattr for inode. See
> http://marc.theaimsgroup.com/?l=linux-kernel&m=106712276514199&w=2 for
> related discussion.

Actually, that last part may be a red herring, since reiserfs_write_lock
is simply a macro for lock_kernel. The more immediate concern is
avoiding the inode->i_op->getxattr call from SELinux on the xattr
directory inode. reiserfs xattr code would need to call a new security
hook to mark the xattr root directory inode in some manner, so that
subsequent security_d_instantiate calls on the per-object subdirectories
could be identified by SELinux, and it could then just set the SID on
the incore inode to a well-defined value and not call
inode->i_op->getxattr for those inodes.

--
Stephen Smalley <[email protected]>
National Security Agency

2004-06-04 12:00:17

by mitya

[permalink] [raw]
Subject: Re: 2.6.7-rc2: open() hangs on ReiserFS with SELinux enabled

Hello,
On Thu, Jun 03, 2004 at 03:46:31PM -0400, Stephen Smalley wrote:
> On Thu, 2004-06-03 at 10:09, Stephen Smalley wrote:
>
> Actually, that last part may be a red herring, since reiserfs_write_lock
> is simply a macro for lock_kernel. The more immediate concern is
> avoiding the inode->i_op->getxattr call from SELinux on the xattr
> directory inode. reiserfs xattr code would need to call a new security
> hook to mark the xattr root directory inode in some manner, so that
> subsequent security_d_instantiate calls on the per-object subdirectories
> could be identified by SELinux, and it could then just set the SID on
> the incore inode to a well-defined value and not call
> inode->i_op->getxattr for those inodes.

Here is a patch, based on discussion with Stephen Smalley, that fixes
the problem for me. As private files don't have xattrs,
reiserfs_getxattr should return early for them, thus not trying to lock anything.
--
With best wishes
Dmitry Baryshkov

diff -pur linux-2.6.7-rc2-orig/fs/reiserfs/xattr.c linux-2.6.7-rc2/fs/reiserfs/xattr.c
--- linux-2.6.7-rc2-orig/fs/reiserfs/xattr.c 2004-06-04 00:22:25.000000000 +0400
+++ linux-2.6.7-rc2/fs/reiserfs/xattr.c 2004-06-04 10:13:00.000000000 +0400
@@ -944,6 +944,16 @@ reiserfs_getxattr (struct dentry *dentry
{
struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
int err;
+ struct dentry *dpar;
+
+ dpar = dget_parent(dentry);
+ if (is_reiserfs_priv_object (dentry->d_inode) ||
+ (dpar && is_reiserfs_priv_object (dpar->d_inode)))
+ {
+ dput(dpar);
+ return -ENODATA;
+ }
+ dput(dpar);

if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)