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