1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* CacheFiles security management 3 * 4 * Copyright (C) 2007, 2021 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8 #include <linux/fs.h> 9 #include <linux/cred.h> 10 #include "internal.h" 11 12 /* 13 * determine the security context within which we access the cache from within 14 * the kernel 15 */ 16 int cachefiles_get_security_ID(struct cachefiles_cache *cache) 17 { 18 struct cred *new; 19 int ret; 20 21 _enter("{%s}", cache->secctx); 22 23 new = prepare_kernel_cred(current); 24 if (!new) { 25 ret = -ENOMEM; 26 goto error; 27 } 28 29 if (cache->secctx) { 30 ret = set_security_override_from_ctx(new, cache->secctx); 31 if (ret < 0) { 32 put_cred(new); 33 pr_err("Security denies permission to nominate security context: error %d\n", 34 ret); 35 goto error; 36 } 37 } 38 39 cache->cache_cred = new; 40 ret = 0; 41 error: 42 _leave(" = %d", ret); 43 return ret; 44 } 45 46 /* 47 * see if mkdir and create can be performed in the root directory 48 */ 49 static int cachefiles_check_cache_dir(struct cachefiles_cache *cache, 50 struct dentry *root) 51 { 52 int ret; 53 54 ret = security_inode_mkdir(d_backing_inode(root), root, 0); 55 if (ret < 0) { 56 pr_err("Security denies permission to make dirs: error %d", 57 ret); 58 return ret; 59 } 60 61 ret = security_inode_create(d_backing_inode(root), root, 0); 62 if (ret < 0) 63 pr_err("Security denies permission to create files: error %d", 64 ret); 65 66 return ret; 67 } 68 69 /* 70 * check the security details of the on-disk cache 71 * - must be called with security override in force 72 * - must return with a security override in force - even in the case of an 73 * error 74 */ 75 int cachefiles_determine_cache_security(struct cachefiles_cache *cache, 76 struct dentry *root, 77 const struct cred **_saved_cred) 78 { 79 struct cred *new; 80 int ret; 81 82 _enter(""); 83 84 /* duplicate the cache creds for COW (the override is currently in 85 * force, so we can use prepare_creds() to do this) */ 86 new = prepare_creds(); 87 if (!new) 88 return -ENOMEM; 89 90 cachefiles_end_secure(cache, *_saved_cred); 91 92 /* use the cache root dir's security context as the basis with 93 * which create files */ 94 ret = set_create_files_as(new, d_backing_inode(root)); 95 if (ret < 0) { 96 abort_creds(new); 97 cachefiles_begin_secure(cache, _saved_cred); 98 _leave(" = %d [cfa]", ret); 99 return ret; 100 } 101 102 put_cred(cache->cache_cred); 103 cache->cache_cred = new; 104 105 cachefiles_begin_secure(cache, _saved_cred); 106 ret = cachefiles_check_cache_dir(cache, root); 107 108 if (ret == -EOPNOTSUPP) 109 ret = 0; 110 _leave(" = %d", ret); 111 return ret; 112 } 113