MAC subsystem and ZFS?
Robert Watson
rwatson at FreeBSD.org
Wed Feb 11 09:52:15 PST 2009
On Mon, 9 Feb 2009, Borja Marcos wrote:
> On Feb 7, 2009, at 11:21 PM, Robert Watson wrote:
>
>>> I'm trying to upgrade the configuration of some web services, already
>>> using the MAC subsystem, to use ZFS instead of UFS, but I see that ZFS
>>> doesn't support MAC labels, even for a whole filesystem, which would be
>>> fine for me, I don't need multilabel support.
>>>
>>> Any ideas? Have I missed anything?
>>
>> Hmmm. Sounds like a bug -- all file systems should be able to operate in
>> single-label mode, even if they don't support EAs and multilabel mode.
>> Could you describe the symptoms you're experiencing in a bit more detail?
>
> Indeed I can :) Sorry for the delay, a human nose-irritating virus, for
> which no known AV software exists, apart from patience, has kept me a bit
> parked this weekend :)
>
> I can read the MAC label from a ZFS dataset, but cannot change it. Example
> follows:
Hi Borja:
This is the expected behavior for a single-label file system -- that is to
say, a file system that doesn't support storing multiple labels. If EA
support in ZFS is mature, it should be fairly straight forward to implement
multi-label support. The following changes were made to UFS/UFS2 to support
per-file label storage:
(1) Implement VOP_SETLABEL for the file system using vop_stdsetlabel_ea in the
any relevant vnode operation vectors:
#ifdef MAC
.vop_setlabel = vop_stdsetlabel_ea,
#endif
(2) Define a file system property, such as a superblock flack in UFS, that
will persisently store whether or not the file system is configured for
multilabel operation (so that singlelabel operation can still be
supported):
#define FS_MULTILABEL 0x20 /* file system is MAC multi-label */
(3) Trigger setting of MNT_MULTILABEL based on that flag being set:
if ((fs->fs_flags & FS_MULTILABEL) != 0) {
#ifdef MAC
MNT_ILOCK(mp);
mp->mnt_flag |= MNT_MULTILABEL;
MNT_IUNLOCK(mp);
#else
printf("WARNING: %s: multilabel flag on fs but no MAC support\n",
mp->mnt_stat.f_mntonname);
#endif
}
(4) When vnodes become associated with particular file system objects, ensure
that the vnode label has been properly set up from the EA data, such as in
this code from ffs_vget:
#ifdef MAC
if ((mp->mnt_flag & MNT_MULTILABEL) && ip->i_mode) {
/*
* If this vnode is already allocated, and we're running
* multi-label, attempt to perform a label association
* from the extended attributes on the inode.
*/
error = mac_associate_vnode_extattr(mp, vp);
if (error) {
/* ufs_inactive will release ip->i_devvp ref. */
vput(vp);
*vpp = NULL;
return (error);
}
}
#endif
The utility routine mac_associate_vnode_extattr() should be called with
the vnode lock held, and before any I/O (etc) can take place on the object
so that appropriate security information is guaranteed to be available.
(5) When a new object is allocated and a vnode is associated with it, ensure
that a new label is created for the object and both set in the EA and
loaded into the vnode label:
#ifdef MAC
if (dvp->v_mount->mnt_flag & MNT_MULTILABEL) {
error = mac_create_vnode_extattr(cnp->cn_cred, dvp->v_mount,
dvp, tvp, cnp);
if (error)
goto bad;
}
#endif
Again, we have a utility routine, mac_create_vnode_extattr(), that does
all the work, and is passed the parent directory object, mountpoint,
creator credential, etc so that the new label can be derived and written
to disk. This needs to happen before any I/O is possible on the vnode so
the security information is available for access control. In UFS, this
happens in two places -- general file create, and separately for directory
create.
(6) Cause VOP_PATHCONF to return an appropriate flag so applications know that
per-file labeling is available:
case _PC_MAC_PRESENT:
#ifdef MAC
if (ap->a_vp->v_mount->mnt_flag & MNT_MULTILABEL)
*ap->a_retval = 1;
else
*ap->a_retval = 0;
#else
*ap->a_retval = 0;
#endif
(7) There may be some places where you need to explicitly disable MAC
checking, such as internal calls to vn_rdwr() on directories, or name
lookup, where there isn't a convenient privileged credential but the work
is arguably on behalf of the file system. IO_NOMACCHECK can be used for
vn_rdwr and NOMACCHECK for namei.
I'm happy to help review patches and discuss this further; the hooks/utility
routines were very much designed with UFS in mind, although intended to be
generic enough to support other file systems, and we may want to revise them
as we gain experience.
Robert N M Watson
Computer Laboratory
University of Cambridge
>
> # zfs create pool/test
>
> (indeed I can read the default label applied when creating it)
> # getfmac pool/test
> pool/test: biba/high,mls/low
>
> (but I cannot change it)
> # setfmac biba/equal,mls/equal /pool/test
> setfmac: labeling not supported in /pool/test
>
> (just in case it's a confusion because of being under "/pool", I try changing
> the mountpoint, still no success)
>
> # mkdir /testing
> # zfs set mountpoint=/testing pool/test
> # setfmac biba/equal,mls/equal /testing
> setfmac: labeling not supported in /testing
>
> This is a 7.1.RELEASE-p2 system.
>
> Thank you very much,
>
>
>
>
>
>
>
> Borja.
>
More information about the freebsd-security
mailing list