0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/fs.h>
0009 #include <linux/cred.h>
0010 #include "internal.h"
0011
0012
0013
0014
0015
0016 int cachefiles_get_security_ID(struct cachefiles_cache *cache)
0017 {
0018 struct cred *new;
0019 int ret;
0020
0021 _enter("{%s}", cache->secctx);
0022
0023 new = prepare_kernel_cred(current);
0024 if (!new) {
0025 ret = -ENOMEM;
0026 goto error;
0027 }
0028
0029 if (cache->secctx) {
0030 ret = set_security_override_from_ctx(new, cache->secctx);
0031 if (ret < 0) {
0032 put_cred(new);
0033 pr_err("Security denies permission to nominate security context: error %d\n",
0034 ret);
0035 goto error;
0036 }
0037 }
0038
0039 cache->cache_cred = new;
0040 ret = 0;
0041 error:
0042 _leave(" = %d", ret);
0043 return ret;
0044 }
0045
0046
0047
0048
0049 static int cachefiles_check_cache_dir(struct cachefiles_cache *cache,
0050 struct dentry *root)
0051 {
0052 int ret;
0053
0054 ret = security_inode_mkdir(d_backing_inode(root), root, 0);
0055 if (ret < 0) {
0056 pr_err("Security denies permission to make dirs: error %d",
0057 ret);
0058 return ret;
0059 }
0060
0061 ret = security_inode_create(d_backing_inode(root), root, 0);
0062 if (ret < 0)
0063 pr_err("Security denies permission to create files: error %d",
0064 ret);
0065
0066 return ret;
0067 }
0068
0069
0070
0071
0072
0073
0074
0075 int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
0076 struct dentry *root,
0077 const struct cred **_saved_cred)
0078 {
0079 struct cred *new;
0080 int ret;
0081
0082 _enter("");
0083
0084
0085
0086 new = prepare_creds();
0087 if (!new)
0088 return -ENOMEM;
0089
0090 cachefiles_end_secure(cache, *_saved_cred);
0091
0092
0093
0094 ret = set_create_files_as(new, d_backing_inode(root));
0095 if (ret < 0) {
0096 abort_creds(new);
0097 cachefiles_begin_secure(cache, _saved_cred);
0098 _leave(" = %d [cfa]", ret);
0099 return ret;
0100 }
0101
0102 put_cred(cache->cache_cred);
0103 cache->cache_cred = new;
0104
0105 cachefiles_begin_secure(cache, _saved_cred);
0106 ret = cachefiles_check_cache_dir(cache, root);
0107
0108 if (ret == -EOPNOTSUPP)
0109 ret = 0;
0110 _leave(" = %d", ret);
0111 return ret;
0112 }