lkml.org 
[lkml]   [2021]   [Nov]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH 35/64] cachefiles: Add security derivation
    From
    Date

    ---

    fs/cachefiles/Makefile | 3 +
    fs/cachefiles/internal.h | 20 ++++++++
    fs/cachefiles/security.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++
    3 files changed, 134 insertions(+), 1 deletion(-)
    create mode 100644 fs/cachefiles/security.c

    diff --git a/fs/cachefiles/Makefile b/fs/cachefiles/Makefile
    index 183fb5f3b8b1..28bbb0d14868 100644
    --- a/fs/cachefiles/Makefile
    +++ b/fs/cachefiles/Makefile
    @@ -4,7 +4,8 @@
    #

    cachefiles-y := \
    - main.o
    + main.o \
    + security.o

    cachefiles-$(CONFIG_CACHEFILES_ERROR_INJECTION) += error_inject.o

    diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
    index b2adcb59b4ce..e57ce5ef875c 100644
    --- a/fs/cachefiles/internal.h
    +++ b/fs/cachefiles/internal.h
    @@ -104,6 +104,26 @@ static inline int cachefiles_inject_remove_error(void)
    return cachefiles_error_injection_state & 2 ? -EIO : 0;
    }

    +/*
    + * security.c
    + */
    +extern int cachefiles_get_security_ID(struct cachefiles_cache *cache);
    +extern int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
    + struct dentry *root,
    + const struct cred **_saved_cred);
    +
    +static inline void cachefiles_begin_secure(struct cachefiles_cache *cache,
    + const struct cred **_saved_cred)
    +{
    + *_saved_cred = override_creds(cache->cache_cred);
    +}
    +
    +static inline void cachefiles_end_secure(struct cachefiles_cache *cache,
    + const struct cred *saved_cred)
    +{
    + revert_creds(saved_cred);
    +}
    +
    /*
    * Error handling
    */
    diff --git a/fs/cachefiles/security.c b/fs/cachefiles/security.c
    new file mode 100644
    index 000000000000..fe777164f1d8
    --- /dev/null
    +++ b/fs/cachefiles/security.c
    @@ -0,0 +1,112 @@
    +// SPDX-License-Identifier: GPL-2.0-or-later
    +/* CacheFiles security management
    + *
    + * Copyright (C) 2007, 2021 Red Hat, Inc. All Rights Reserved.
    + * Written by David Howells (dhowells@redhat.com)
    + */
    +
    +#include <linux/fs.h>
    +#include <linux/cred.h>
    +#include "internal.h"
    +
    +/*
    + * determine the security context within which we access the cache from within
    + * the kernel
    + */
    +int cachefiles_get_security_ID(struct cachefiles_cache *cache)
    +{
    + struct cred *new;
    + int ret;
    +
    + _enter("{%s}", cache->secctx);
    +
    + new = prepare_kernel_cred(current);
    + if (!new) {
    + ret = -ENOMEM;
    + goto error;
    + }
    +
    + if (cache->secctx) {
    + ret = set_security_override_from_ctx(new, cache->secctx);
    + if (ret < 0) {
    + put_cred(new);
    + pr_err("Security denies permission to nominate security context: error %d\n",
    + ret);
    + goto error;
    + }
    + }
    +
    + cache->cache_cred = new;
    + ret = 0;
    +error:
    + _leave(" = %d", ret);
    + return ret;
    +}
    +
    +/*
    + * see if mkdir and create can be performed in the root directory
    + */
    +static int cachefiles_check_cache_dir(struct cachefiles_cache *cache,
    + struct dentry *root)
    +{
    + int ret;
    +
    + ret = security_inode_mkdir(d_backing_inode(root), root, 0);
    + if (ret < 0) {
    + pr_err("Security denies permission to make dirs: error %d",
    + ret);
    + return ret;
    + }
    +
    + ret = security_inode_create(d_backing_inode(root), root, 0);
    + if (ret < 0)
    + pr_err("Security denies permission to create files: error %d",
    + ret);
    +
    + return ret;
    +}
    +
    +/*
    + * check the security details of the on-disk cache
    + * - must be called with security override in force
    + * - must return with a security override in force - even in the case of an
    + * error
    + */
    +int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
    + struct dentry *root,
    + const struct cred **_saved_cred)
    +{
    + struct cred *new;
    + int ret;
    +
    + _enter("");
    +
    + /* duplicate the cache creds for COW (the override is currently in
    + * force, so we can use prepare_creds() to do this) */
    + new = prepare_creds();
    + if (!new)
    + return -ENOMEM;
    +
    + cachefiles_end_secure(cache, *_saved_cred);
    +
    + /* use the cache root dir's security context as the basis with
    + * which create files */
    + ret = set_create_files_as(new, d_backing_inode(root));
    + if (ret < 0) {
    + abort_creds(new);
    + cachefiles_begin_secure(cache, _saved_cred);
    + _leave(" = %d [cfa]", ret);
    + return ret;
    + }
    +
    + put_cred(cache->cache_cred);
    + cache->cache_cred = new;
    +
    + cachefiles_begin_secure(cache, _saved_cred);
    + ret = cachefiles_check_cache_dir(cache, root);
    +
    + if (ret == -EOPNOTSUPP)
    + ret = 0;
    + _leave(" = %d", ret);
    + return ret;
    +}

    \
     
     \ /
      Last update: 2021-11-29 15:34    [W:4.632 / U:0.052 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site