lkml.org 
[lkml]   [2020]   [Feb]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    Subject[PATCH 2/3] Teach SELinux about anonymous inodes
    From
    This change uses the anon_inodes and LSM infrastructure introduced in
    the previous patch to give SELinux the ability to control
    anonymous-inode files that are created using the new _secure()
    anon_inodes functions.

    A SELinux policy author detects and controls these anonymous inodes by
    adding a name-based type_transition rule that assigns a new security
    type to anonymous-inode files created in some domain. The name used
    for the name-based transition is the name associated with the
    anonymous inode for file listings --- e.g., "[userfaultfd]" or
    "[perf_event]".

    Example:

    type uffd_t;
    type_transition sysadm_t sysadm_t : file uffd_t "[userfaultfd]";
    allow sysadm_t uffd_t:file { create };

    (The next patch in this series is necessary for making userfaultfd
    support this new interface. The example above is just
    for exposition.)

    Signed-off-by: Daniel Colascione <dancol@google.com>
    ---
    security/selinux/hooks.c | 57 ++++++++++++++++++++++++++++++++++++++++
    1 file changed, 57 insertions(+)

    diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
    index 1659b59fb5d7..6de0892620b3 100644
    --- a/security/selinux/hooks.c
    +++ b/security/selinux/hooks.c
    @@ -2915,6 +2915,62 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
    return 0;
    }

    +static int selinux_inode_init_security_anon(struct inode *inode,
    + const struct qstr *name,
    + const struct file_operations *fops,
    + const struct inode *context_inode)
    +{
    + const struct task_security_struct *tsec = selinux_cred(current_cred());
    + struct common_audit_data ad;
    + struct inode_security_struct *isec;
    + int rc;
    +
    + if (unlikely(IS_PRIVATE(inode)))
    + return 0;
    +
    + if (unlikely(!selinux_state.initialized))
    + return 0;
    +
    + isec = selinux_inode(inode);
    +
    + /*
    + * We only get here once per ephemeral inode. The inode has
    + * been initialized via inode_alloc_security but is otherwise
    + * untouched.
    + */
    +
    + if (context_inode) {
    + struct inode_security_struct *context_isec =
    + selinux_inode(context_inode);
    + if (IS_ERR(context_isec))
    + return PTR_ERR(context_isec);
    + isec->sid = context_isec->sid;
    + } else {
    + rc = security_transition_sid(
    + &selinux_state, tsec->sid, tsec->sid,
    + SECCLASS_FILE, name, &isec->sid);
    + if (rc)
    + return rc;
    + }
    +
    + isec->initialized = LABEL_INITIALIZED;
    +
    + /*
    + * Now that we've initialized security, check whether we're
    + * allowed to actually create this type of anonymous inode.
    + */
    +
    + ad.type = LSM_AUDIT_DATA_INODE;
    + ad.u.inode = inode;
    +
    + return avc_has_perm(&selinux_state,
    + tsec->sid,
    + isec->sid,
    + isec->sclass,
    + FILE__CREATE,
    + &ad);
    +}
    +
    static int selinux_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode)
    {
    return may_create(dir, dentry, SECCLASS_FILE);
    @@ -6923,6 +6979,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {

    LSM_HOOK_INIT(inode_free_security, selinux_inode_free_security),
    LSM_HOOK_INIT(inode_init_security, selinux_inode_init_security),
    + LSM_HOOK_INIT(inode_init_security_anon, selinux_inode_init_security_anon),
    LSM_HOOK_INIT(inode_create, selinux_inode_create),
    LSM_HOOK_INIT(inode_link, selinux_inode_link),
    LSM_HOOK_INIT(inode_unlink, selinux_inode_unlink),
    --
    2.25.0.265.gbab2e86ba0-goog
    \
     
     \ /
      Last update: 2020-02-14 04:27    [W:4.588 / U:0.140 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site