1 /* Large capacity key type 2 * 3 * Copyright (C) 2013 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/module.h> 13 #include <linux/init.h> 14 #include <linux/seq_file.h> 15 #include <linux/file.h> 16 #include <linux/shmem_fs.h> 17 #include <linux/err.h> 18 #include <keys/user-type.h> 19 #include <keys/big_key-type.h> 20 21 MODULE_LICENSE("GPL"); 22 23 /* 24 * If the data is under this limit, there's no point creating a shm file to 25 * hold it as the permanently resident metadata for the shmem fs will be at 26 * least as large as the data. 27 */ 28 #define BIG_KEY_FILE_THRESHOLD (sizeof(struct inode) + sizeof(struct dentry)) 29 30 /* 31 * big_key defined keys take an arbitrary string as the description and an 32 * arbitrary blob of data as the payload 33 */ 34 struct key_type key_type_big_key = { 35 .name = "big_key", 36 .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, 37 .instantiate = big_key_instantiate, 38 .match = user_match, 39 .revoke = big_key_revoke, 40 .destroy = big_key_destroy, 41 .describe = big_key_describe, 42 .read = big_key_read, 43 }; 44 45 /* 46 * Instantiate a big key 47 */ 48 int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep) 49 { 50 struct path *path = (struct path *)&key->payload.data2; 51 struct file *file; 52 ssize_t written; 53 size_t datalen = prep->datalen; 54 int ret; 55 56 ret = -EINVAL; 57 if (datalen <= 0 || datalen > 1024 * 1024 || !prep->data) 58 goto error; 59 60 /* Set an arbitrary quota */ 61 ret = key_payload_reserve(key, 16); 62 if (ret < 0) 63 goto error; 64 65 key->type_data.x[1] = datalen; 66 67 if (datalen > BIG_KEY_FILE_THRESHOLD) { 68 /* Create a shmem file to store the data in. This will permit the data 69 * to be swapped out if needed. 70 * 71 * TODO: Encrypt the stored data with a temporary key. 72 */ 73 file = shmem_kernel_file_setup("", datalen, 0); 74 if (IS_ERR(file)) { 75 ret = PTR_ERR(file); 76 goto err_quota; 77 } 78 79 written = kernel_write(file, prep->data, prep->datalen, 0); 80 if (written != datalen) { 81 ret = written; 82 if (written >= 0) 83 ret = -ENOMEM; 84 goto err_fput; 85 } 86 87 /* Pin the mount and dentry to the key so that we can open it again 88 * later 89 */ 90 *path = file->f_path; 91 path_get(path); 92 fput(file); 93 } else { 94 /* Just store the data in a buffer */ 95 void *data = kmalloc(datalen, GFP_KERNEL); 96 if (!data) { 97 ret = -ENOMEM; 98 goto err_quota; 99 } 100 101 key->payload.data = memcpy(data, prep->data, prep->datalen); 102 } 103 return 0; 104 105 err_fput: 106 fput(file); 107 err_quota: 108 key_payload_reserve(key, 0); 109 error: 110 return ret; 111 } 112 113 /* 114 * dispose of the links from a revoked keyring 115 * - called with the key sem write-locked 116 */ 117 void big_key_revoke(struct key *key) 118 { 119 struct path *path = (struct path *)&key->payload.data2; 120 121 /* clear the quota */ 122 key_payload_reserve(key, 0); 123 if (key_is_instantiated(key) && key->type_data.x[1] > BIG_KEY_FILE_THRESHOLD) 124 vfs_truncate(path, 0); 125 } 126 127 /* 128 * dispose of the data dangling from the corpse of a big_key key 129 */ 130 void big_key_destroy(struct key *key) 131 { 132 if (key->type_data.x[1] > BIG_KEY_FILE_THRESHOLD) { 133 struct path *path = (struct path *)&key->payload.data2; 134 path_put(path); 135 path->mnt = NULL; 136 path->dentry = NULL; 137 } else { 138 kfree(key->payload.data); 139 key->payload.data = NULL; 140 } 141 } 142 143 /* 144 * describe the big_key key 145 */ 146 void big_key_describe(const struct key *key, struct seq_file *m) 147 { 148 unsigned long datalen = key->type_data.x[1]; 149 150 seq_puts(m, key->description); 151 152 if (key_is_instantiated(key)) 153 seq_printf(m, ": %lu [%s]", 154 datalen, 155 datalen > BIG_KEY_FILE_THRESHOLD ? "file" : "buff"); 156 } 157 158 /* 159 * read the key data 160 * - the key's semaphore is read-locked 161 */ 162 long big_key_read(const struct key *key, char __user *buffer, size_t buflen) 163 { 164 unsigned long datalen = key->type_data.x[1]; 165 long ret; 166 167 if (!buffer || buflen < datalen) 168 return datalen; 169 170 if (datalen > BIG_KEY_FILE_THRESHOLD) { 171 struct path *path = (struct path *)&key->payload.data2; 172 struct file *file; 173 loff_t pos; 174 175 file = dentry_open(path, O_RDONLY, current_cred()); 176 if (IS_ERR(file)) 177 return PTR_ERR(file); 178 179 pos = 0; 180 ret = vfs_read(file, buffer, datalen, &pos); 181 fput(file); 182 if (ret >= 0 && ret != datalen) 183 ret = -EIO; 184 } else { 185 ret = datalen; 186 if (copy_to_user(buffer, key->payload.data, datalen) != 0) 187 ret = -EFAULT; 188 } 189 190 return ret; 191 } 192 193 /* 194 * Module stuff 195 */ 196 static int __init big_key_init(void) 197 { 198 return register_key_type(&key_type_big_key); 199 } 200 201 static void __exit big_key_cleanup(void) 202 { 203 unregister_key_type(&key_type_big_key); 204 } 205 206 module_init(big_key_init); 207 module_exit(big_key_cleanup); 208