• J
    selinux: make security_sb_clone_mnt_opts return an error on context mismatch · 094f7b69
    Jeff Layton 提交于
    I had the following problem reported a while back. If you mount the
    same filesystem twice using NFSv4 with different contexts, then the
    second context= option is ignored. For instance:
    
        # mount server:/export /mnt/test1
        # mount server:/export /mnt/test2 -o context=system_u:object_r:tmp_t:s0
        # ls -dZ /mnt/test1
        drwxrwxrwt. root root system_u:object_r:nfs_t:s0       /mnt/test1
        # ls -dZ /mnt/test2
        drwxrwxrwt. root root system_u:object_r:nfs_t:s0       /mnt/test2
    
    When we call into SELinux to set the context of a "cloned" superblock,
    it will currently just bail out when it notices that we're reusing an
    existing superblock. Since the existing superblock is already set up and
    presumably in use, we can't go overwriting its context with the one from
    the "original" sb. Because of this, the second context= option in this
    case cannot take effect.
    
    This patch fixes this by turning security_sb_clone_mnt_opts into an int
    return operation. When it finds that the "new" superblock that it has
    been handed is already set up, it checks to see whether the contexts on
    the old superblock match it. If it does, then it will just return
    success, otherwise it'll return -EBUSY and emit a printk to tell the
    admin why the second mount failed.
    
    Note that this patch may cause casualties. The NFSv4 code relies on
    being able to walk down to an export from the pseudoroot. If you mount
    filesystems that are nested within one another with different contexts,
    then this patch will make those mounts fail in new and "exciting" ways.
    
    For instance, suppose that /export is a separate filesystem on the
    server:
    
        # mount server:/ /mnt/test1
        # mount salusa:/export /mnt/test2 -o context=system_u:object_r:tmp_t:s0
        mount.nfs: an incorrect mount option was specified
    
    ...with the printk in the ring buffer. Because we *might* eventually
    walk down to /mnt/test1/export, the mount is denied due to this patch.
    The second mount needs the pseudoroot superblock, but that's already
    present with the wrong context.
    
    OTOH, if we mount these in the reverse order, then both mounts work,
    because the pseudoroot superblock created when mounting /export is
    discarded once that mount is done. If we then however try to walk into
    that directory, the automount fails for the similar reasons:
    
        # cd /mnt/test1/scratch/
        -bash: cd: /mnt/test1/scratch: Device or resource busy
    
    The story I've gotten from the SELinux folks that I've talked to is that
    this is desirable behavior. In SELinux-land, mounting the same data
    under different contexts is wrong -- there can be only one.
    
    Cc: Steve Dickson <steved@redhat.com>
    Cc: Stephen Smalley <sds@tycho.nsa.gov>
    Signed-off-by: NJeff Layton <jlayton@redhat.com>
    Acked-by: NEric Paris <eparis@redhat.com>
    Signed-off-by: NJames Morris <james.l.morris@oracle.com>
    094f7b69
security.h 111.6 KB