diff options
| -rw-r--r-- | Documentation/ecryptfs.txt | 77 | ||||
| -rw-r--r-- | MAINTAINERS | 7 | ||||
| -rw-r--r-- | fs/Kconfig | 12 | ||||
| -rw-r--r-- | fs/Makefile | 1 | ||||
| -rw-r--r-- | fs/ecryptfs/Makefile | 7 | ||||
| -rw-r--r-- | fs/ecryptfs/crypto.c | 1659 | ||||
| -rw-r--r-- | fs/ecryptfs/debug.c | 123 | ||||
| -rw-r--r-- | fs/ecryptfs/dentry.c | 87 | ||||
| -rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 482 | ||||
| -rw-r--r-- | fs/ecryptfs/file.c | 440 | ||||
| -rw-r--r-- | fs/ecryptfs/inode.c | 1079 | ||||
| -rw-r--r-- | fs/ecryptfs/keystore.c | 1061 | ||||
| -rw-r--r-- | fs/ecryptfs/main.c | 831 | ||||
| -rw-r--r-- | fs/ecryptfs/mmap.c | 788 | ||||
| -rw-r--r-- | fs/ecryptfs/super.c | 198 |
15 files changed, 6852 insertions, 0 deletions
diff --git a/Documentation/ecryptfs.txt b/Documentation/ecryptfs.txt new file mode 100644 index 000000000000..01d8a08351ac --- /dev/null +++ b/Documentation/ecryptfs.txt | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | eCryptfs: A stacked cryptographic filesystem for Linux | ||
| 2 | |||
| 3 | eCryptfs is free software. Please see the file COPYING for details. | ||
| 4 | For documentation, please see the files in the doc/ subdirectory. For | ||
| 5 | building and installation instructions please see the INSTALL file. | ||
| 6 | |||
| 7 | Maintainer: Phillip Hellewell | ||
| 8 | Lead developer: Michael A. Halcrow <mhalcrow@us.ibm.com> | ||
| 9 | Developers: Michael C. Thompson | ||
| 10 | Kent Yoder | ||
| 11 | Web Site: http://ecryptfs.sf.net | ||
| 12 | |||
| 13 | This software is currently undergoing development. Make sure to | ||
| 14 | maintain a backup copy of any data you write into eCryptfs. | ||
| 15 | |||
| 16 | eCryptfs requires the userspace tools downloadable from the | ||
| 17 | SourceForge site: | ||
| 18 | |||
| 19 | http://sourceforge.net/projects/ecryptfs/ | ||
| 20 | |||
| 21 | Userspace requirements include: | ||
| 22 | - David Howells' userspace keyring headers and libraries (version | ||
| 23 | 1.0 or higher), obtainable from | ||
| 24 | http://people.redhat.com/~dhowells/keyutils/ | ||
| 25 | - Libgcrypt | ||
| 26 | |||
| 27 | |||
| 28 | NOTES | ||
| 29 | |||
| 30 | In the beta/experimental releases of eCryptfs, when you upgrade | ||
| 31 | eCryptfs, you should copy the files to an unencrypted location and | ||
| 32 | then copy the files back into the new eCryptfs mount to migrate the | ||
| 33 | files. | ||
| 34 | |||
| 35 | |||
| 36 | MOUNT-WIDE PASSPHRASE | ||
| 37 | |||
| 38 | Create a new directory into which eCryptfs will write its encrypted | ||
| 39 | files (i.e., /root/crypt). Then, create the mount point directory | ||
| 40 | (i.e., /mnt/crypt). Now it's time to mount eCryptfs: | ||
| 41 | |||
| 42 | mount -t ecryptfs /root/crypt /mnt/crypt | ||
| 43 | |||
| 44 | You should be prompted for a passphrase and a salt (the salt may be | ||
| 45 | blank). | ||
| 46 | |||
| 47 | Try writing a new file: | ||
| 48 | |||
| 49 | echo "Hello, World" > /mnt/crypt/hello.txt | ||
| 50 | |||
| 51 | The operation will complete. Notice that there is a new file in | ||
| 52 | /root/crypt that is at least 12288 bytes in size (depending on your | ||
| 53 | host page size). This is the encrypted underlying file for what you | ||
| 54 | just wrote. To test reading, from start to finish, you need to clear | ||
| 55 | the user session keyring: | ||
| 56 | |||
| 57 | keyctl clear @u | ||
| 58 | |||
| 59 | Then umount /mnt/crypt and mount again per the instructions given | ||
| 60 | above. | ||
| 61 | |||
| 62 | cat /mnt/crypt/hello.txt | ||
| 63 | |||
| 64 | |||
| 65 | NOTES | ||
| 66 | |||
| 67 | eCryptfs version 0.1 should only be mounted on (1) empty directories | ||
| 68 | or (2) directories containing files only created by eCryptfs. If you | ||
| 69 | mount a directory that has pre-existing files not created by eCryptfs, | ||
| 70 | then behavior is undefined. Do not run eCryptfs in higher verbosity | ||
| 71 | levels unless you are doing so for the sole purpose of debugging or | ||
| 72 | development, since secret values will be written out to the system log | ||
| 73 | in that case. | ||
| 74 | |||
| 75 | |||
| 76 | Mike Halcrow | ||
| 77 | mhalcrow@us.ibm.com | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 77e58585ce55..129511c0c27e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -977,6 +977,13 @@ L: ebtables-devel@lists.sourceforge.net | |||
| 977 | W: http://ebtables.sourceforge.net/ | 977 | W: http://ebtables.sourceforge.net/ |
| 978 | S: Maintained | 978 | S: Maintained |
| 979 | 979 | ||
| 980 | ECRYPT FILE SYSTEM | ||
| 981 | P: Mike Halcrow, Phillip Hellewell | ||
| 982 | M: mhalcrow@us.ibm.com, phillip@hellewell.homeip.net | ||
| 983 | L: ecryptfs-devel@lists.sourceforge.net | ||
| 984 | W: http://ecryptfs.sourceforge.net/ | ||
| 985 | S: Supported | ||
| 986 | |||
| 980 | EDAC-CORE | 987 | EDAC-CORE |
| 981 | P: Doug Thompson | 988 | P: Doug Thompson |
| 982 | M: norsk5@xmission.com | 989 | M: norsk5@xmission.com |
diff --git a/fs/Kconfig b/fs/Kconfig index 68f4561423ff..674cfbb83a95 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
| @@ -995,6 +995,18 @@ config AFFS_FS | |||
| 995 | To compile this file system support as a module, choose M here: the | 995 | To compile this file system support as a module, choose M here: the |
| 996 | module will be called affs. If unsure, say N. | 996 | module will be called affs. If unsure, say N. |
| 997 | 997 | ||
| 998 | config ECRYPT_FS | ||
| 999 | tristate "eCrypt filesystem layer support (EXPERIMENTAL)" | ||
| 1000 | depends on EXPERIMENTAL && KEYS && CRYPTO | ||
| 1001 | help | ||
| 1002 | Encrypted filesystem that operates on the VFS layer. See | ||
| 1003 | <file:Documentation/ecryptfs.txt> to learn more about | ||
| 1004 | eCryptfs. Userspace components are required and can be | ||
| 1005 | obtained from <http://ecryptfs.sf.net>. | ||
| 1006 | |||
| 1007 | To compile this file system support as a module, choose M here: the | ||
| 1008 | module will be called ecryptfs. | ||
| 1009 | |||
| 998 | config HFS_FS | 1010 | config HFS_FS |
| 999 | tristate "Apple Macintosh file system support (EXPERIMENTAL)" | 1011 | tristate "Apple Macintosh file system support (EXPERIMENTAL)" |
| 1000 | depends on BLOCK && EXPERIMENTAL | 1012 | depends on BLOCK && EXPERIMENTAL |
diff --git a/fs/Makefile b/fs/Makefile index 819b2a93bebe..fd24d67a7cdb 100644 --- a/fs/Makefile +++ b/fs/Makefile | |||
| @@ -75,6 +75,7 @@ obj-$(CONFIG_BFS_FS) += bfs/ | |||
| 75 | obj-$(CONFIG_ISO9660_FS) += isofs/ | 75 | obj-$(CONFIG_ISO9660_FS) += isofs/ |
| 76 | obj-$(CONFIG_HFSPLUS_FS) += hfsplus/ # Before hfs to find wrapped HFS+ | 76 | obj-$(CONFIG_HFSPLUS_FS) += hfsplus/ # Before hfs to find wrapped HFS+ |
| 77 | obj-$(CONFIG_HFS_FS) += hfs/ | 77 | obj-$(CONFIG_HFS_FS) += hfs/ |
| 78 | obj-$(CONFIG_ECRYPT_FS) += ecryptfs/ | ||
| 78 | obj-$(CONFIG_VXFS_FS) += freevxfs/ | 79 | obj-$(CONFIG_VXFS_FS) += freevxfs/ |
| 79 | obj-$(CONFIG_NFS_FS) += nfs/ | 80 | obj-$(CONFIG_NFS_FS) += nfs/ |
| 80 | obj-$(CONFIG_EXPORTFS) += exportfs/ | 81 | obj-$(CONFIG_EXPORTFS) += exportfs/ |
diff --git a/fs/ecryptfs/Makefile b/fs/ecryptfs/Makefile new file mode 100644 index 000000000000..ca6562451eeb --- /dev/null +++ b/fs/ecryptfs/Makefile | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | # | ||
| 2 | # Makefile for the Linux 2.6 eCryptfs | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-$(CONFIG_ECRYPT_FS) += ecryptfs.o | ||
| 6 | |||
| 7 | ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o crypto.o keystore.o debug.o | ||
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c new file mode 100644 index 000000000000..ed35a9712fa1 --- /dev/null +++ b/fs/ecryptfs/crypto.c | |||
| @@ -0,0 +1,1659 @@ | |||
| 1 | /** | ||
| 2 | * eCryptfs: Linux filesystem encryption layer | ||
| 3 | * | ||
| 4 | * Copyright (C) 1997-2004 Erez Zadok | ||
| 5 | * Copyright (C) 2001-2004 Stony Brook University | ||
| 6 | * Copyright (C) 2004-2006 International Business Machines Corp. | ||
| 7 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> | ||
| 8 | * Michael C. Thompson <mcthomps@us.ibm.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or | ||
| 11 | * modify it under the terms of the GNU General Public License as | ||
| 12 | * published by the Free Software Foundation; either version 2 of the | ||
| 13 | * License, or (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, but | ||
| 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 18 | * General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
| 23 | * 02111-1307, USA. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <linux/fs.h> | ||
| 27 | #include <linux/mount.h> | ||
| 28 | #include <linux/pagemap.h> | ||
| 29 | #include <linux/random.h> | ||
| 30 | #include <linux/compiler.h> | ||
| 31 | #include <linux/key.h> | ||
| 32 | #include <linux/namei.h> | ||
| 33 | #include <linux/crypto.h> | ||
| 34 | #include <linux/file.h> | ||
| 35 | #include <linux/scatterlist.h> | ||
| 36 | #include "ecryptfs_kernel.h" | ||
| 37 | |||
| 38 | static int | ||
| 39 | ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat, | ||
| 40 | struct page *dst_page, int dst_offset, | ||
| 41 | struct page *src_page, int src_offset, int size, | ||
| 42 | unsigned char *iv); | ||
| 43 | static int | ||
| 44 | ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat, | ||
| 45 | struct page *dst_page, int dst_offset, | ||
| 46 | struct page *src_page, int src_offset, int size, | ||
| 47 | unsigned char *iv); | ||
| 48 | |||
| 49 | /** | ||
| 50 | * ecryptfs_to_hex | ||
| 51 | * @dst: Buffer to take hex character representation of contents of | ||
| 52 | * src; must be at least of size (src_size * 2) | ||
| 53 | * @src: Buffer to be converted to a hex string respresentation | ||
| 54 | * @src_size: number of bytes to convert | ||
| 55 | */ | ||
| 56 | void ecryptfs_to_hex(char *dst, char *src, size_t src_size) | ||
| 57 | { | ||
| 58 | int x; | ||
| 59 | |||
| 60 | for (x = 0; x < src_size; x++) | ||
| 61 | sprintf(&dst[x * 2], "%.2x", (unsigned char)src[x]); | ||
| 62 | } | ||
| 63 | |||
| 64 | /** | ||
| 65 | * ecryptfs_from_hex | ||
| 66 | * @dst: Buffer to take the bytes from src hex; must be at least of | ||
| 67 | * size (src_size / 2) | ||
| 68 | * @src: Buffer to be converted from a hex string respresentation to raw value | ||
| 69 | * @dst_size: size of dst buffer, or number of hex characters pairs to convert | ||
| 70 | */ | ||
| 71 | void ecryptfs_from_hex(char *dst, char *src, int dst_size) | ||
| 72 | { | ||
| 73 | int x; | ||
| 74 | char tmp[3] = { 0, }; | ||
| 75 | |||
| 76 | for (x = 0; x < dst_size; x++) { | ||
| 77 | tmp[0] = src[x * 2]; | ||
| 78 | tmp[1] = src[x * 2 + 1]; | ||
| 79 | dst[x] = (unsigned char)simple_strtol(tmp, NULL, 16); | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | /** | ||
| 84 | * ecryptfs_calculate_md5 - calculates the md5 of @src | ||
| 85 | * @dst: Pointer to 16 bytes of allocated memory | ||
| 86 | * @crypt_stat: Pointer to crypt_stat struct for the current inode | ||
| 87 | * @src: Data to be md5'd | ||
| 88 | * @len: Length of @src | ||
| 89 | * | ||
| 90 | * Uses the allocated crypto context that crypt_stat references to | ||
| 91 | * generate the MD5 sum of the contents of src. | ||
| 92 | */ | ||
| 93 | static int ecryptfs_calculate_md5(char *dst, | ||
| 94 | struct ecryptfs_crypt_stat *crypt_stat, | ||
| 95 | char *src, int len) | ||
| 96 | { | ||
| 97 | int rc = 0; | ||
| 98 | struct scatterlist sg; | ||
| 99 | |||
| 100 | mutex_lock(&crypt_stat->cs_md5_tfm_mutex); | ||
| 101 | sg_init_one(&sg, (u8 *)src, len); | ||
| 102 | if (!crypt_stat->md5_tfm) { | ||
| 103 | crypt_stat->md5_tfm = | ||
| 104 | crypto_alloc_tfm("md5", CRYPTO_TFM_REQ_MAY_SLEEP); | ||
| 105 | if (!crypt_stat->md5_tfm) { | ||
| 106 | rc = -ENOMEM; | ||
| 107 | ecryptfs_printk(KERN_ERR, "Error attempting to " | ||
| 108 | "allocate crypto context\n"); | ||
| 109 | goto out; | ||
| 110 | } | ||
| 111 | } | ||
| 112 | crypto_digest_init(crypt_stat->md5_tfm); | ||
| 113 | crypto_digest_update(crypt_stat->md5_tfm, &sg, 1); | ||
| 114 | crypto_digest_final(crypt_stat->md5_tfm, dst); | ||
| 115 | mutex_unlock(&crypt_stat->cs_md5_tfm_mutex); | ||
| 116 | out: | ||
| 117 | return rc; | ||
| 118 | } | ||
| 119 | |||
| 120 | /** | ||
| 121 | * ecryptfs_derive_iv | ||
| 122 | * @iv: destination for the derived iv vale | ||
| 123 | * @crypt_stat: Pointer to crypt_stat struct for the current inode | ||
| 124 | * @offset: Offset of the page whose's iv we are to derive | ||
| 125 | * | ||
| 126 | * Generate the initialization vector from the given root IV and page | ||
| 127 | * offset. | ||
| 128 | * | ||
| 129 | * Returns zero on success; non-zero on error. | ||
| 130 | */ | ||
| 131 | static int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat, | ||
| 132 | pgoff_t offset) | ||
| 133 | { | ||
| 134 | int rc = 0; | ||
| 135 | char dst[MD5_DIGEST_SIZE]; | ||
| 136 | char src[ECRYPTFS_MAX_IV_BYTES + 16]; | ||
| 137 | |||
| 138 | if (unlikely(ecryptfs_verbosity > 0)) { | ||
| 139 | ecryptfs_printk(KERN_DEBUG, "root iv:\n"); | ||
| 140 | ecryptfs_dump_hex(crypt_stat->root_iv, crypt_stat->iv_bytes); | ||
| 141 | } | ||
| 142 | /* TODO: It is probably secure to just cast the least | ||
| 143 | * significant bits of the root IV into an unsigned long and | ||
| 144 | * add the offset to that rather than go through all this | ||
| 145 | * hashing business. -Halcrow */ | ||
| 146 | memcpy(src, crypt_stat->root_iv, crypt_stat->iv_bytes); | ||
| 147 | memset((src + crypt_stat->iv_bytes), 0, 16); | ||
| 148 | snprintf((src + crypt_stat->iv_bytes), 16, "%ld", offset); | ||
| 149 | if (unlikely(ecryptfs_verbosity > 0)) { | ||
| 150 | ecryptfs_printk(KERN_DEBUG, "source:\n"); | ||
| 151 | ecryptfs_dump_hex(src, (crypt_stat->iv_bytes + 16)); | ||
| 152 | } | ||
| 153 | rc = ecryptfs_calculate_md5(dst, crypt_stat, src, | ||
| 154 | (crypt_stat->iv_bytes + 16)); | ||
| 155 | if (rc) { | ||
| 156 | ecryptfs_printk(KERN_WARNING, "Error attempting to compute " | ||
| 157 | "MD5 while generating IV for a page\n"); | ||
| 158 | goto out; | ||
| 159 | } | ||
| 160 | memcpy(iv, dst, crypt_stat->iv_bytes); | ||
| 161 | if (unlikely(ecryptfs_verbosity > 0)) { | ||
| 162 | ecryptfs_printk(KERN_DEBUG, "derived iv:\n"); | ||
| 163 | ecryptfs_dump_hex(iv, crypt_stat->iv_bytes); | ||
| 164 | } | ||
| 165 | out: | ||
| 166 | return rc; | ||
| 167 | } | ||
| 168 | |||
| 169 | /** | ||
| 170 | * ecryptfs_init_crypt_stat | ||
| 171 | * @crypt_stat: Pointer to the crypt_stat struct to initialize. | ||
| 172 | * | ||
| 173 | * Initialize the crypt_stat structure. | ||
| 174 | */ | ||
| 175 | void | ||
| 176 | ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) | ||
| 177 | { | ||
| 178 | memset((void *)crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat)); | ||
| 179 | mutex_init(&crypt_stat->cs_mutex); | ||
| 180 | mutex_init(&crypt_stat->cs_tfm_mutex); | ||
| 181 | mutex_init(&crypt_stat->cs_md5_tfm_mutex); | ||
| 182 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_STRUCT_INITIALIZED); | ||
| 183 | } | ||
| 184 | |||
| 185 | /** | ||
| 186 | * ecryptfs_destruct_crypt_stat | ||
| 187 | * @crypt_stat: Pointer to the crypt_stat struct to initialize. | ||
| 188 | * | ||
| 189 | * Releases all memory associated with a crypt_stat struct. | ||
| 190 | */ | ||
| 191 | void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) | ||
| 192 | { | ||
| 193 | if (crypt_stat->tfm) | ||
| 194 | crypto_free_tfm(crypt_stat->tfm); | ||
| 195 | if (crypt_stat->md5_tfm) | ||
| 196 | crypto_free_tfm(crypt_stat->md5_tfm); | ||
| 197 | memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat)); | ||
| 198 | } | ||
| 199 | |||
| 200 | void ecryptfs_destruct_mount_crypt_stat( | ||
| 201 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) | ||
| 202 | { | ||
| 203 | if (mount_crypt_stat->global_auth_tok_key) | ||
| 204 | key_put(mount_crypt_stat->global_auth_tok_key); | ||
| 205 | if (mount_crypt_stat->global_key_tfm) | ||
| 206 | crypto_free_tfm(mount_crypt_stat->global_key_tfm); | ||
| 207 | memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat)); | ||
| 208 | } | ||
| 209 | |||
| 210 | /** | ||
| 211 | * virt_to_scatterlist | ||
| 212 | * @addr: Virtual address | ||
| 213 | * @size: Size of data; should be an even multiple of the block size | ||
| 214 | * @sg: Pointer to scatterlist array; set to NULL to obtain only | ||
| 215 | * the number of scatterlist structs required in array | ||
| 216 | * @sg_size: Max array size | ||
| 217 | * | ||
| 218 | * Fills in a scatterlist array with page references for a passed | ||
| 219 | * virtual address. | ||
| 220 | * | ||
| 221 | * Returns the number of scatterlist structs in array used | ||
| 222 | */ | ||
| 223 | int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg, | ||
| 224 | int sg_size) | ||
| 225 | { | ||
| 226 | int i = 0; | ||
| 227 | struct page *pg; | ||
| 228 | int offset; | ||
| 229 | int remainder_of_page; | ||
| 230 | |||
| 231 | while (size > 0 && i < sg_size) { | ||
| 232 | pg = virt_to_page(addr); | ||
| 233 | offset = offset_in_page(addr); | ||
| 234 | if (sg) { | ||
| 235 | sg[i].page = pg; | ||
| 236 | sg[i].offset = offset; | ||
| 237 | } | ||
| 238 | remainder_of_page = PAGE_CACHE_SIZE - offset; | ||
| 239 | if (size >= remainder_of_page) { | ||
| 240 | if (sg) | ||
| 241 | sg[i].length = remainder_of_page; | ||
| 242 | addr += remainder_of_page; | ||
| 243 | size -= remainder_of_page; | ||
| 244 | } else { | ||
| 245 | if (sg) | ||
| 246 | sg[i].length = size; | ||
| 247 | addr += size; | ||
| 248 | size = 0; | ||
| 249 | } | ||
| 250 | i++; | ||
| 251 | } | ||
| 252 | if (size > 0) | ||
| 253 | return -ENOMEM; | ||
| 254 | return i; | ||
| 255 | } | ||
| 256 | |||
| 257 | /** | ||
| 258 | * encrypt_scatterlist | ||
| 259 | * @crypt_stat: Pointer to the crypt_stat struct to initialize. | ||
| 260 | * @dest_sg: Destination of encrypted data | ||
| 261 | * @src_sg: Data to be encrypted | ||
| 262 | * @size: Length of data to be encrypted | ||
| 263 | * @iv: iv to use during encryption | ||
| 264 | * | ||
| 265 | * Returns the number of bytes encrypted; negative value on error | ||
| 266 | */ | ||
| 267 | static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, | ||
| 268 | struct scatterlist *dest_sg, | ||
| 269 | struct scatterlist *src_sg, int size, | ||
| 270 | unsigned char *iv) | ||
| 271 | { | ||
| 272 | int rc = 0; | ||
| 273 | |||
| 274 | BUG_ON(!crypt_stat || !crypt_stat->tfm | ||
| 275 | || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags, | ||
| 276 | ECRYPTFS_STRUCT_INITIALIZED)); | ||
| 277 | if (unlikely(ecryptfs_verbosity > 0)) { | ||
| 278 | ecryptfs_printk(KERN_DEBUG, "Key size [%d]; key:\n", | ||
| 279 | crypt_stat->key_size); | ||
| 280 | ecryptfs_dump_hex(crypt_stat->key, | ||
| 281 | crypt_stat->key_size); | ||
| 282 | } | ||
| 283 | /* Consider doing this once, when the file is opened */ | ||
| 284 | mutex_lock(&crypt_stat->cs_tfm_mutex); | ||
| 285 | rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key, | ||
| 286 | crypt_stat->key_size); | ||
| 287 | if (rc) { | ||
| 288 | ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n", | ||
| 289 | rc); | ||
| 290 | mutex_unlock(&crypt_stat->cs_tfm_mutex); | ||
| 291 | rc = -EINVAL; | ||
| 292 | goto out; | ||
| 293 | } | ||
| 294 | ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes.\n", size); | ||
| 295 | crypto_cipher_encrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size, iv); | ||
| 296 | mutex_unlock(&crypt_stat->cs_tfm_mutex); | ||
| 297 | out: | ||
| 298 | return rc; | ||
| 299 | } | ||
| 300 | |||
| 301 | static void | ||
| 302 | ecryptfs_extent_to_lwr_pg_idx_and_offset(unsigned long *lower_page_idx, | ||
| 303 | int *byte_offset, | ||
| 304 | struct ecryptfs_crypt_stat *crypt_stat, | ||
| 305 | unsigned long extent_num) | ||
| 306 | { | ||
| 307 | unsigned long lower_extent_num; | ||
| 308 | int extents_occupied_by_headers_at_front; | ||
| 309 | int bytes_occupied_by_headers_at_front; | ||
| 310 | int extent_offset; | ||
| 311 | int extents_per_page; | ||
| 312 | |||
| 313 | bytes_occupied_by_headers_at_front = | ||
| 314 | ( crypt_stat->header_extent_size | ||
| 315 | * crypt_stat->num_header_extents_at_front ); | ||
| 316 | extents_occupied_by_headers_at_front = | ||
| 317 | ( bytes_occupied_by_headers_at_front | ||
| 318 | / crypt_stat->extent_size ); | ||
| 319 | lower_extent_num = extents_occupied_by_headers_at_front + extent_num; | ||
| 320 | extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size; | ||
| 321 | (*lower_page_idx) = lower_extent_num / extents_per_page; | ||
| 322 | extent_offset = lower_extent_num % extents_per_page; | ||
| 323 | (*byte_offset) = extent_offset * crypt_stat->extent_size; | ||
| 324 | ecryptfs_printk(KERN_DEBUG, " * crypt_stat->header_extent_size = " | ||
| 325 | "[%d]\n", crypt_stat->header_extent_size); | ||
| 326 | ecryptfs_printk(KERN_DEBUG, " * crypt_stat->" | ||
| 327 | "num_header_extents_at_front = [%d]\n", | ||
| 328 | crypt_stat->num_header_extents_at_front); | ||
| 329 | ecryptfs_printk(KERN_DEBUG, " * extents_occupied_by_headers_at_" | ||
| 330 | "front = [%d]\n", extents_occupied_by_headers_at_front); | ||
| 331 | ecryptfs_printk(KERN_DEBUG, " * lower_extent_num = [0x%.16x]\n", | ||
| 332 | lower_extent_num); | ||
| 333 | ecryptfs_printk(KERN_DEBUG, " * extents_per_page = [%d]\n", | ||
| 334 | extents_per_page); | ||
| 335 | ecryptfs_printk(KERN_DEBUG, " * (*lower_page_idx) = [0x%.16x]\n", | ||
| 336 | (*lower_page_idx)); | ||
| 337 | ecryptfs_printk(KERN_DEBUG, " * extent_offset = [%d]\n", | ||
| 338 | extent_offset); | ||
| 339 | ecryptfs_printk(KERN_DEBUG, " * (*byte_offset) = [%d]\n", | ||
| 340 | (*byte_offset)); | ||
| 341 | } | ||
| 342 | |||
| 343 | static int ecryptfs_write_out_page(struct ecryptfs_page_crypt_context *ctx, | ||
| 344 | struct page *lower_page, | ||
| 345 | struct inode *lower_inode, | ||
| 346 | int byte_offset_in_page, int bytes_to_write) | ||
| 347 | { | ||
| 348 | int rc = 0; | ||
| 349 | |||
| 350 | if (ctx->mode == ECRYPTFS_PREPARE_COMMIT_MODE) { | ||
| 351 | rc = ecryptfs_commit_lower_page(lower_page, lower_inode, | ||
| 352 | ctx->param.lower_file, | ||
| 353 | byte_offset_in_page, | ||
| 354 | bytes_to_write); | ||
| 355 | if (rc) { | ||
| 356 | ecryptfs_printk(KERN_ERR, "Error calling lower " | ||
| 357 | "commit; rc = [%d]\n", rc); | ||
| 358 | goto out; | ||
| 359 | } | ||
| 360 | } else { | ||
| 361 | rc = ecryptfs_writepage_and_release_lower_page(lower_page, | ||
| 362 | lower_inode, | ||
| 363 | ctx->param.wbc); | ||
| 364 | if (rc) { | ||
| 365 | ecryptfs_printk(KERN_ERR, "Error calling lower " | ||
| 366 | "writepage(); rc = [%d]\n", rc); | ||
| 367 | goto out; | ||
| 368 | } | ||
| 369 | } | ||
| 370 | out: | ||
| 371 | return rc; | ||
| 372 | } | ||
| 373 | |||
| 374 | static int ecryptfs_read_in_page(struct ecryptfs_page_crypt_context *ctx, | ||
| 375 | struct page **lower_page, | ||
| 376 | struct inode *lower_inode, | ||
| 377 | unsigned long lower_page_idx, | ||
| 378 | int byte_offset_in_page) | ||
| 379 | { | ||
| 380 | int rc = 0; | ||
| 381 | |||
| 382 | if (ctx->mode == ECRYPTFS_PREPARE_COMMIT_MODE) { | ||
| 383 | /* TODO: Limit this to only the data extents that are | ||
| 384 | * needed */ | ||
| 385 | rc = ecryptfs_get_lower_page(lower_page, lower_inode, | ||
| 386 | ctx->param.lower_file, | ||
| 387 | lower_page_idx, | ||
| 388 | byte_offset_in_page, | ||
| 389 | (PAGE_CACHE_SIZE | ||
| 390 | - byte_offset_in_page)); | ||
| 391 | if (rc) { | ||
| 392 | ecryptfs_printk( | ||
| 393 | KERN_ERR, "Error attempting to grab, map, " | ||
| 394 | "and prepare_write lower page with index " | ||
| 395 | "[0x%.16x]; rc = [%d]\n", lower_page_idx, rc); | ||
| 396 | goto out; | ||
| 397 | } | ||
| 398 | } else { | ||
| 399 | rc = ecryptfs_grab_and_map_lower_page(lower_page, NULL, | ||
| 400 | lower_inode, | ||
| 401 | lower_page_idx); | ||
| 402 | if (rc) { | ||
| 403 | ecryptfs_printk( | ||
| 404 | KERN_ERR, "Error attempting to grab and map " | ||
| 405 | "lower page with index [0x%.16x]; rc = [%d]\n", | ||
| 406 | lower_page_idx, rc); | ||
| 407 | goto out; | ||
| 408 | } | ||
| 409 | } | ||
| 410 | out: | ||
| 411 | return rc; | ||
| 412 | } | ||
| 413 | |||
| 414 | /** | ||
| 415 | * ecryptfs_encrypt_page | ||
| 416 | * @ctx: The context of the page | ||
| 417 | * | ||
| 418 | * Encrypt an eCryptfs page. This is done on a per-extent basis. Note | ||
| 419 | * that eCryptfs pages may straddle the lower pages -- for instance, | ||
| 420 | * if the file was created on a machine with an 8K page size | ||
| 421 | * (resulting in an 8K header), and then the file is copied onto a | ||
| 422 | * host with a 32K page size, then when reading page 0 of the eCryptfs | ||
| 423 | * file, 24K of page 0 of the lower file will be read and decrypted, | ||
| 424 | * and then 8K of page 1 of the lower file will be read and decrypted. | ||
| 425 | * | ||
| 426 | * The actual operations performed on each page depends on the | ||
| 427 | * contents of the ecryptfs_page_crypt_context struct. | ||
| 428 | * | ||
| 429 | * Returns zero on success; negative on error | ||
| 430 | */ | ||
| 431 | int ecryptfs_encrypt_page(struct ecryptfs_page_crypt_context *ctx) | ||
| 432 | { | ||
| 433 | char extent_iv[ECRYPTFS_MAX_IV_BYTES]; | ||
| 434 | unsigned long base_extent; | ||
| 435 | unsigned long extent_offset = 0; | ||
| 436 | unsigned long lower_page_idx = 0; | ||
| 437 | unsigned long prior_lower_page_idx = 0; | ||
| 438 | struct page *lower_page; | ||
| 439 | struct inode *lower_inode; | ||
| 440 | struct ecryptfs_inode_info *inode_info; | ||
| 441 | struct ecryptfs_crypt_stat *crypt_stat; | ||
| 442 | int rc = 0; | ||
| 443 | int lower_byte_offset = 0; | ||
| 444 | int orig_byte_offset = 0; | ||
| 445 | int num_extents_per_page; | ||
| 446 | #define ECRYPTFS_PAGE_STATE_UNREAD 0 | ||
| 447 | #define ECRYPTFS_PAGE_STATE_READ 1 | ||
| 448 | #define ECRYPTFS_PAGE_STATE_MODIFIED 2 | ||
| 449 | #define ECRYPTFS_PAGE_STATE_WRITTEN 3 | ||
| 450 | int page_state; | ||
| 451 | |||
| 452 | lower_inode = ecryptfs_inode_to_lower(ctx->page->mapping->host); | ||
| 453 | inode_info = ecryptfs_inode_to_private(ctx->page->mapping->host); | ||
| 454 | crypt_stat = &inode_info->crypt_stat; | ||
| 455 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED)) { | ||
| 456 | rc = ecryptfs_copy_page_to_lower(ctx->page, lower_inode, | ||
| 457 | ctx->param.lower_file); | ||
| 458 | if (rc) | ||
| 459 | ecryptfs_printk(KERN_ERR, "Error attempting to copy " | ||
| 460 | "page at index [0x%.16x]\n", | ||
| 461 | ctx->page->index); | ||
| 462 | goto out; | ||
| 463 | } | ||
| 464 | num_extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size; | ||
| 465 | base_extent = (ctx->page->index * num_extents_per_page); | ||
| 466 | page_state = ECRYPTFS_PAGE_STATE_UNREAD; | ||
| 467 | while (extent_offset < num_extents_per_page) { | ||
| 468 | ecryptfs_extent_to_lwr_pg_idx_and_offset( | ||
| 469 | &lower_page_idx, &lower_byte_offset, crypt_stat, | ||
| 470 | (base_extent + extent_offset)); | ||
| 471 | if (prior_lower_page_idx != lower_page_idx | ||
| 472 | && page_state == ECRYPTFS_PAGE_STATE_MODIFIED) { | ||
| 473 | rc = ecryptfs_write_out_page(ctx, lower_page, | ||
| 474 | lower_inode, | ||
| 475 | orig_byte_offset, | ||
| 476 | (PAGE_CACHE_SIZE | ||
| 477 | - orig_byte_offset)); | ||
| 478 | if (rc) { | ||
| 479 | ecryptfs_printk(KERN_ERR, "Error attempting " | ||
| 480 | "to write out page; rc = [%d]" | ||
| 481 | "\n", rc); | ||
| 482 | goto out; | ||
| 483 | } | ||
| 484 | page_state = ECRYPTFS_PAGE_STATE_WRITTEN; | ||
| 485 | } | ||
| 486 | if (page_state == ECRYPTFS_PAGE_STATE_UNREAD | ||
| 487 | || page_state == ECRYPTFS_PAGE_STATE_WRITTEN) { | ||
| 488 | rc = ecryptfs_read_in_page(ctx, &lower_page, | ||
| 489 | lower_inode, lower_page_idx, | ||
| 490 | lower_byte_offset); | ||
| 491 | if (rc) { | ||
| 492 | ecryptfs_printk(KERN_ERR, "Error attempting " | ||
| 493 | "to read in lower page with " | ||
| 494 | "index [0x%.16x]; rc = [%d]\n", | ||
| 495 | lower_page_idx, rc); | ||
| 496 | goto out; | ||
| 497 | } | ||
| 498 | orig_byte_offset = lower_byte_offset; | ||
| 499 | prior_lower_page_idx = lower_page_idx; | ||
| 500 | page_state = ECRYPTFS_PAGE_STATE_READ; | ||
| 501 | } | ||
| 502 | BUG_ON(!(page_state == ECRYPTFS_PAGE_STATE_MODIFIED | ||
| 503 | || page_state == ECRYPTFS_PAGE_STATE_READ)); | ||
| 504 | rc = ecryptfs_derive_iv(extent_iv, crypt_stat, | ||
| 505 | (base_extent + extent_offset)); | ||
| 506 | if (rc) { | ||
| 507 | ecryptfs_printk(KERN_ERR, "Error attempting to " | ||
| 508 | "derive IV for extent [0x%.16x]; " | ||
| 509 | "rc = [%d]\n", | ||
| 510 | (base_extent + extent_offset), rc); | ||
| 511 | goto out; | ||
| 512 | } | ||
| 513 | if (unlikely(ecryptfs_verbosity > 0)) { | ||
| 514 | ecryptfs_printk(KERN_DEBUG, "Encrypting extent " | ||
| 515 | "with iv:\n"); | ||
| 516 | ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes); | ||
| 517 | ecryptfs_printk(KERN_DEBUG, "First 8 bytes before " | ||
| 518 | "encryption:\n"); | ||
| 519 | ecryptfs_dump_hex((char *) | ||
| 520 | (page_address(ctx->page) | ||
| 521 | + (extent_offset | ||
| 522 | * crypt_stat->extent_size)), 8); | ||
| 523 | } | ||
| 524 | rc = ecryptfs_encrypt_page_offset( | ||
| 525 | crypt_stat, lower_page, lower_byte_offset, ctx->page, | ||
| 526 | (extent_offset * crypt_stat->extent_size), | ||
| 527 | crypt_stat->extent_size, extent_iv); | ||
| 528 | ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16x]; " | ||
| 529 | "rc = [%d]\n", | ||
| 530 | (base_extent + extent_offset), rc); | ||
| 531 | if (unlikely(ecryptfs_verbosity > 0)) { | ||
| 532 | ecryptfs_printk(KERN_DEBUG, "First 8 bytes after " | ||
| 533 | "encryption:\n"); | ||
| 534 | ecryptfs_dump_hex((char *)(page_address(lower_page) | ||
| 535 | + lower_byte_offset), 8); | ||
| 536 | } | ||
| 537 | page_state = ECRYPTFS_PAGE_STATE_MODIFIED; | ||
| 538 | extent_offset++; | ||
| 539 | } | ||
| 540 | BUG_ON(orig_byte_offset != 0); | ||
| 541 | rc = ecryptfs_write_out_page(ctx, lower_page, lower_inode, 0, | ||
| 542 | (lower_byte_offset | ||
| 543 | + crypt_stat->extent_size)); | ||
| 544 | if (rc) { | ||
| 545 | ecryptfs_printk(KERN_ERR, "Error attempting to write out " | ||
| 546 | "page; rc = [%d]\n", rc); | ||
| 547 | goto out; | ||
| 548 | } | ||
| 549 | out: | ||
| 550 | return rc; | ||
| 551 | } | ||
| 552 | |||
| 553 | /** | ||
| 554 | * ecryptfs_decrypt_page | ||
| 555 | * @file: The ecryptfs file | ||
| 556 | * @page: The page in ecryptfs to decrypt | ||
| 557 | * | ||
| 558 | * Decrypt an eCryptfs page. This is done on a per-extent basis. Note | ||
| 559 | * that eCryptfs pages may straddle the lower pages -- for instance, | ||
| 560 | * if the file was created on a machine with an 8K page size | ||
| 561 | * (resulting in an 8K header), and then the file is copied onto a | ||
| 562 | * host with a 32K page size, then when reading page 0 of the eCryptfs | ||
| 563 | * file, 24K of page 0 of the lower file will be read and decrypted, | ||
| 564 | * and then 8K of page 1 of the lower file will be read and decrypted. | ||
| 565 | * | ||
| 566 | * Returns zero on success; negative on error | ||
| 567 | */ | ||
| 568 | int ecryptfs_decrypt_page(struct file *file, struct page *page) | ||
| 569 | { | ||
| 570 | char extent_iv[ECRYPTFS_MAX_IV_BYTES]; | ||
| 571 | unsigned long base_extent; | ||
| 572 | unsigned long extent_offset = 0; | ||
| 573 | unsigned long lower_page_idx = 0; | ||
| 574 | unsigned long prior_lower_page_idx = 0; | ||
| 575 | struct page *lower_page; | ||
| 576 | char *lower_page_virt = NULL; | ||
| 577 | struct inode *lower_inode; | ||
| 578 | struct ecryptfs_crypt_stat *crypt_stat; | ||
| 579 | int rc = 0; | ||
| 580 | int byte_offset; | ||
| 581 | int num_extents_per_page; | ||
| 582 | int page_state; | ||
| 583 | |||
| 584 | crypt_stat = &(ecryptfs_inode_to_private( | ||
| 585 | page->mapping->host)->crypt_stat); | ||
| 586 | lower_inode = ecryptfs_inode_to_lower(page->mapping->host); | ||
| 587 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED)) { | ||
| 588 | rc = ecryptfs_do_readpage(file, page, page->index); | ||
| 589 | if (rc) | ||
| 590 | ecryptfs_printk(KERN_ERR, "Error attempting to copy " | ||
| 591 | "page at index [0x%.16x]\n", | ||
| 592 | page->index); | ||
| 593 | goto out; | ||
| 594 | } | ||
| 595 | num_extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size; | ||
| 596 | base_extent = (page->index * num_extents_per_page); | ||
| 597 | lower_page_virt = kmem_cache_alloc(ecryptfs_lower_page_cache, | ||
| 598 | SLAB_KERNEL); | ||
| 599 | if (!lower_page_virt) { | ||
| 600 | rc = -ENOMEM; | ||
| 601 | ecryptfs_printk(KERN_ERR, "Error getting page for encrypted " | ||
| 602 | "lower page(s)\n"); | ||
| 603 | goto out; | ||
| 604 | } | ||
| 605 | lower_page = virt_to_page(lower_page_virt); | ||
| 606 | page_state = ECRYPTFS_PAGE_STATE_UNREAD; | ||
| 607 | while (extent_offset < num_extents_per_page) { | ||
| 608 | ecryptfs_extent_to_lwr_pg_idx_and_offset( | ||
| 609 | &lower_page_idx, &byte_offset, crypt_stat, | ||
| 610 | (base_extent + extent_offset)); | ||
| 611 | if (prior_lower_page_idx != lower_page_idx | ||
| 612 | || page_state == ECRYPTFS_PAGE_STATE_UNREAD) { | ||
| 613 | rc = ecryptfs_do_readpage(file, lower_page, | ||
| 614 | lower_page_idx); | ||
| 615 | if (rc) { | ||
| 616 | ecryptfs_printk(KERN_ERR, "Error reading " | ||
| 617 | "lower encrypted page; rc = " | ||
| 618 | "[%d]\n", rc); | ||
| 619 | goto out; | ||
| 620 | } | ||
| 621 | prior_lower_page_idx = lower_page_idx; | ||
| 622 | page_state = ECRYPTFS_PAGE_STATE_READ; | ||
| 623 | } | ||
| 624 | rc = ecryptfs_derive_iv(extent_iv, crypt_stat, | ||
| 625 | (base_extent + extent_offset)); | ||
| 626 | if (rc) { | ||
| 627 | ecryptfs_printk(KERN_ERR, "Error attempting to " | ||
| 628 | "derive IV for extent [0x%.16x]; rc = " | ||
| 629 | "[%d]\n", | ||
| 630 | (base_extent + extent_offset), rc); | ||
| 631 | goto out; | ||
| 632 | } | ||
| 633 | if (unlikely(ecryptfs_verbosity > 0)) { | ||
| 634 | ecryptfs_printk(KERN_DEBUG, "Decrypting extent " | ||
| 635 | "with iv:\n"); | ||
| 636 | ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes); | ||
| 637 | ecryptfs_printk(KERN_DEBUG, "First 8 bytes before " | ||
| 638 | "decryption:\n"); | ||
| 639 | ecryptfs_dump_hex((lower_page_virt + byte_offset), 8); | ||
| 640 | } | ||
| 641 | rc = ecryptfs_decrypt_page_offset(crypt_stat, page, | ||
| 642 | (extent_offset | ||
| 643 | * crypt_stat->extent_size), | ||
| 644 | lower_page, byte_offset, | ||
| 645 | crypt_stat->extent_size, | ||
| 646 | extent_iv); | ||
| 647 | if (rc != crypt_stat->extent_size) { | ||
| 648 | ecryptfs_printk(KERN_ERR, "Error attempting to " | ||
| 649 | "decrypt extent [0x%.16x]\n", | ||
| 650 | (base_extent + extent_offset)); | ||
| 651 | goto out; | ||
| 652 | } | ||
| 653 | rc = 0; | ||
| 654 | if (unlikely(ecryptfs_verbosity > 0)) { | ||
| 655 | ecryptfs_printk(KERN_DEBUG, "First 8 bytes after " | ||
| 656 | "decryption:\n"); | ||
| 657 | ecryptfs_dump_hex((char *)(page_address(page) | ||
| 658 | + byte_offset), 8); | ||
| 659 | } | ||
| 660 | extent_offset++; | ||
| 661 | } | ||
| 662 | out: | ||
| 663 | if (lower_page_virt) | ||
| 664 | kmem_cache_free(ecryptfs_lower_page_cache, lower_page_virt); | ||
| 665 | return rc; | ||
| 666 | } | ||
| 667 | |||
| 668 | /** | ||
| 669 | * decrypt_scatterlist | ||
| 670 | * | ||
| 671 | * Returns the number of bytes decrypted; negative value on error | ||
| 672 | */ | ||
| 673 | static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, | ||
| 674 | struct scatterlist *dest_sg, | ||
| 675 | struct scatterlist *src_sg, int size, | ||
| 676 | unsigned char *iv) | ||
| 677 | { | ||
| 678 | int rc = 0; | ||
| 679 | |||
| 680 | /* Consider doing this once, when the file is opened */ | ||
| 681 | mutex_lock(&crypt_stat->cs_tfm_mutex); | ||
| 682 | rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key, | ||
| 683 | crypt_stat->key_size); | ||
| 684 | if (rc) { | ||
| 685 | ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n", | ||
| 686 | rc); | ||
| 687 | mutex_unlock(&crypt_stat->cs_tfm_mutex); | ||
| 688 | rc = -EINVAL; | ||
| 689 | goto out; | ||
| 690 | } | ||
| 691 | ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size); | ||
| 692 | rc = crypto_cipher_decrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size, | ||
| 693 | iv); | ||
| 694 | mutex_unlock(&crypt_stat->cs_tfm_mutex); | ||
| 695 | if (rc) { | ||
| 696 | ecryptfs_printk(KERN_ERR, "Error decrypting; rc = [%d]\n", | ||
| 697 | rc); | ||
| 698 | goto out; | ||
| 699 | } | ||
| 700 | rc = size; | ||
| 701 | out: | ||
| 702 | return rc; | ||
| 703 | } | ||
| 704 | |||
| 705 | /** | ||
| 706 | * ecryptfs_encrypt_page_offset | ||
| 707 | * | ||
| 708 | * Returns the number of bytes encrypted | ||
| 709 | */ | ||
| 710 | static int | ||
| 711 | ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat, | ||
| 712 | struct page *dst_page, int dst_offset, | ||
| 713 | struct page *src_page, int src_offset, int size, | ||
| 714 | unsigned char *iv) | ||
| 715 | { | ||
| 716 | struct scatterlist src_sg, dst_sg; | ||
| 717 | |||
| 718 | src_sg.page = src_page; | ||
| 719 | src_sg.offset = src_offset; | ||
| 720 | src_sg.length = size; | ||
| 721 | dst_sg.page = dst_page; | ||
| 722 | dst_sg.offset = dst_offset; | ||
| 723 | dst_sg.length = size; | ||
| 724 | return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv); | ||
| 725 | } | ||
| 726 | |||
| 727 | /** | ||
| 728 | * ecryptfs_decrypt_page_offset | ||
| 729 | * | ||
| 730 | * Returns the number of bytes decrypted | ||
| 731 | */ | ||
| 732 | static int | ||
| 733 | ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat, | ||
| 734 | struct page *dst_page, int dst_offset, | ||
| 735 | struct page *src_page, int src_offset, int size, | ||
| 736 | unsigned char *iv) | ||
| 737 | { | ||
| 738 | struct scatterlist src_sg, dst_sg; | ||
| 739 | |||
| 740 | src_sg.page = src_page; | ||
| 741 | src_sg.offset = src_offset; | ||
| 742 | src_sg.length = size; | ||
| 743 | dst_sg.page = dst_page; | ||
| 744 | dst_sg.offset = dst_offset; | ||
| 745 | dst_sg.length = size; | ||
| 746 | return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv); | ||
| 747 | } | ||
| 748 | |||
| 749 | #define ECRYPTFS_MAX_SCATTERLIST_LEN 4 | ||
| 750 | |||
| 751 | /** | ||
| 752 | * ecryptfs_init_crypt_ctx | ||
| 753 | * @crypt_stat: Uninitilized crypt stats structure | ||
| 754 | * | ||
| 755 | * Initialize the crypto context. | ||
| 756 | * | ||
| 757 | * TODO: Performance: Keep a cache of initialized cipher contexts; | ||
| 758 | * only init if needed | ||
| 759 | */ | ||
| 760 | int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat) | ||
| 761 | { | ||
| 762 | int rc = -EINVAL; | ||
| 763 | |||
| 764 | if (!crypt_stat->cipher) { | ||
| 765 | ecryptfs_printk(KERN_ERR, "No cipher specified\n"); | ||
| 766 | goto out; | ||
| 767 | } | ||
| 768 | ecryptfs_printk(KERN_DEBUG, | ||
| 769 | "Initializing cipher [%s]; strlen = [%d]; " | ||
| 770 | "key_size_bits = [%d]\n", | ||
| 771 | crypt_stat->cipher, (int)strlen(crypt_stat->cipher), | ||
| 772 | crypt_stat->key_size << 3); | ||
| 773 | if (crypt_stat->tfm) { | ||
| 774 | rc = 0; | ||
| 775 | goto out; | ||
| 776 | } | ||
| 777 | mutex_lock(&crypt_stat->cs_tfm_mutex); | ||
| 778 | crypt_stat->tfm = crypto_alloc_tfm(crypt_stat->cipher, | ||
| 779 | ECRYPTFS_DEFAULT_CHAINING_MODE | ||
| 780 | | CRYPTO_TFM_REQ_WEAK_KEY); | ||
| 781 | mutex_unlock(&crypt_stat->cs_tfm_mutex); | ||
| 782 | if (!crypt_stat->tfm) { | ||
| 783 | ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): " | ||
| 784 | "Error initializing cipher [%s]\n", | ||
| 785 | crypt_stat->cipher); | ||
| 786 | goto out; | ||
| 787 | } | ||
| 788 | rc = 0; | ||
| 789 | out: | ||
| 790 | return rc; | ||
| 791 | } | ||
| 792 | |||
| 793 | static void set_extent_mask_and_shift(struct ecryptfs_crypt_stat *crypt_stat) | ||
| 794 | { | ||
| 795 | int extent_size_tmp; | ||
| 796 | |||
| 797 | crypt_stat->extent_mask = 0xFFFFFFFF; | ||
| 798 | crypt_stat->extent_shift = 0; | ||
| 799 | if (crypt_stat->extent_size == 0) | ||
| 800 | return; | ||
| 801 | extent_size_tmp = crypt_stat->extent_size; | ||
| 802 | while ((extent_size_tmp & 0x01) == 0) { | ||
| 803 | extent_size_tmp >>= 1; | ||
| 804 | crypt_stat->extent_mask <<= 1; | ||
| 805 | crypt_stat->extent_shift++; | ||
| 806 | } | ||
| 807 | } | ||
| 808 | |||
| 809 | void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat) | ||
| 810 | { | ||
| 811 | /* Default values; may be overwritten as we are parsing the | ||
| 812 | * packets. */ | ||
| 813 | crypt_stat->extent_size = ECRYPTFS_DEFAULT_EXTENT_SIZE; | ||
| 814 | set_extent_mask_and_shift(crypt_stat); | ||
| 815 | crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES; | ||
| 816 | if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) { | ||
| 817 | crypt_stat->header_extent_size = | ||
| 818 | ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; | ||
| 819 | } else | ||
| 820 | crypt_stat->header_extent_size = PAGE_CACHE_SIZE; | ||
| 821 | crypt_stat->num_header_extents_at_front = 1; | ||
| 822 | } | ||
| 823 | |||
| 824 | /** | ||
| 825 | * ecryptfs_compute_root_iv | ||
| 826 | * @crypt_stats | ||
| 827 | * | ||
| 828 | * On error, sets the root IV to all 0's. | ||
| 829 | */ | ||
| 830 | int ecryptfs_compute_root_iv(struct ecryptfs_crypt_stat *crypt_stat) | ||
| 831 | { | ||
| 832 | int rc = 0; | ||
| 833 | char dst[MD5_DIGEST_SIZE]; | ||
| 834 | |||
| 835 | BUG_ON(crypt_stat->iv_bytes > MD5_DIGEST_SIZE); | ||
| 836 | BUG_ON(crypt_stat->iv_bytes <= 0); | ||
| 837 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID)) { | ||
| 838 | rc = -EINVAL; | ||
| 839 | ecryptfs_printk(KERN_WARNING, "Session key not valid; " | ||
| 840 | "cannot generate root IV\n"); | ||
| 841 | goto out; | ||
| 842 | } | ||
| 843 | rc = ecryptfs_calculate_md5(dst, crypt_stat, crypt_stat->key, | ||
| 844 | crypt_stat->key_size); | ||
| 845 | if (rc) { | ||
| 846 | ecryptfs_printk(KERN_WARNING, "Error attempting to compute " | ||
| 847 | "MD5 while generating root IV\n"); | ||
| 848 | goto out; | ||
| 849 | } | ||
| 850 | memcpy(crypt_stat->root_iv, dst, crypt_stat->iv_bytes); | ||
| 851 | out: | ||
| 852 | if (rc) { | ||
| 853 | memset(crypt_stat->root_iv, 0, crypt_stat->iv_bytes); | ||
| 854 | ECRYPTFS_SET_FLAG(crypt_stat->flags, | ||
| 855 | ECRYPTFS_SECURITY_WARNING); | ||
| 856 | } | ||
| 857 | return rc; | ||
| 858 | } | ||
| 859 | |||
| 860 | static void ecryptfs_generate_new_key(struct ecryptfs_crypt_stat *crypt_stat) | ||
| 861 | { | ||
| 862 | get_random_bytes(crypt_stat->key, crypt_stat->key_size); | ||
| 863 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID); | ||
| 864 | ecryptfs_compute_root_iv(crypt_stat); | ||
| 865 | if (unlikely(ecryptfs_verbosity > 0)) { | ||
| 866 | ecryptfs_printk(KERN_DEBUG, "Generated new session key:\n"); | ||
| 867 | ecryptfs_dump_hex(crypt_stat->key, | ||
| 868 | crypt_stat->key_size); | ||
| 869 | } | ||
| 870 | } | ||
| 871 | |||
| 872 | /** | ||
| 873 | * ecryptfs_set_default_crypt_stat_vals | ||
| 874 | * @crypt_stat | ||
| 875 | * | ||
| 876 | * Default values in the event that policy does not override them. | ||
| 877 | */ | ||
| 878 | static void ecryptfs_set_default_crypt_stat_vals( | ||
| 879 | struct ecryptfs_crypt_stat *crypt_stat, | ||
| 880 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) | ||
| 881 | { | ||
| 882 | ecryptfs_set_default_sizes(crypt_stat); | ||
| 883 | strcpy(crypt_stat->cipher, ECRYPTFS_DEFAULT_CIPHER); | ||
| 884 | crypt_stat->key_size = ECRYPTFS_DEFAULT_KEY_BYTES; | ||
| 885 | ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID); | ||
| 886 | crypt_stat->file_version = ECRYPTFS_FILE_VERSION; | ||
| 887 | crypt_stat->mount_crypt_stat = mount_crypt_stat; | ||
| 888 | } | ||
| 889 | |||
| 890 | /** | ||
| 891 | * ecryptfs_new_file_context | ||
| 892 | * @ecryptfs_dentry | ||
| 893 | * | ||
| 894 | * If the crypto context for the file has not yet been established, | ||
| 895 | * this is where we do that. Establishing a new crypto context | ||
| 896 | * involves the following decisions: | ||
| 897 | * - What cipher to use? | ||
| 898 | * - What set of authentication tokens to use? | ||
| 899 | * Here we just worry about getting enough information into the | ||
| 900 | * authentication tokens so that we know that they are available. | ||
| 901 | * We associate the available authentication tokens with the new file | ||
| 902 | * via the set of signatures in the crypt_stat struct. Later, when | ||
| 903 | * the headers are actually written out, we may again defer to | ||
| 904 | * userspace to perform the encryption of the session key; for the | ||
| 905 | * foreseeable future, this will be the case with public key packets. | ||
| 906 | * | ||
| 907 | * Returns zero on success; non-zero otherwise | ||
| 908 | */ | ||
| 909 | /* Associate an authentication token(s) with the file */ | ||
| 910 | int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry) | ||
| 911 | { | ||
| 912 | int rc = 0; | ||
| 913 | struct ecryptfs_crypt_stat *crypt_stat = | ||
| 914 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; | ||
| 915 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | ||
| 916 | &ecryptfs_superblock_to_private( | ||
| 917 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | ||
| 918 | int cipher_name_len; | ||
| 919 | |||
| 920 | ecryptfs_set_default_crypt_stat_vals(crypt_stat, mount_crypt_stat); | ||
| 921 | /* See if there are mount crypt options */ | ||
| 922 | if (mount_crypt_stat->global_auth_tok) { | ||
| 923 | ecryptfs_printk(KERN_DEBUG, "Initializing context for new " | ||
| 924 | "file using mount_crypt_stat\n"); | ||
| 925 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); | ||
| 926 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID); | ||
| 927 | memcpy(crypt_stat->keysigs[crypt_stat->num_keysigs++], | ||
| 928 | mount_crypt_stat->global_auth_tok_sig, | ||
| 929 | ECRYPTFS_SIG_SIZE_HEX); | ||
| 930 | cipher_name_len = | ||
| 931 | strlen(mount_crypt_stat->global_default_cipher_name); | ||
| 932 | memcpy(crypt_stat->cipher, | ||
| 933 | mount_crypt_stat->global_default_cipher_name, | ||
| 934 | cipher_name_len); | ||
| 935 | crypt_stat->cipher[cipher_name_len] = '\0'; | ||
| 936 | crypt_stat->key_size = | ||
| 937 | mount_crypt_stat->global_default_cipher_key_size; | ||
| 938 | ecryptfs_generate_new_key(crypt_stat); | ||
| 939 | } else | ||
| 940 | /* We should not encounter this scenario since we | ||
| 941 | * should detect lack of global_auth_tok at mount time | ||
| 942 | * TODO: Applies to 0.1 release only; remove in future | ||
| 943 | * release */ | ||
| 944 | BUG(); | ||
| 945 | rc = ecryptfs_init_crypt_ctx(crypt_stat); | ||
| 946 | if (rc) | ||
| 947 | ecryptfs_printk(KERN_ERR, "Error initializing cryptographic " | ||
| 948 | "context for cipher [%s]: rc = [%d]\n", | ||
| 949 | crypt_stat->cipher, rc); | ||
| 950 | return rc; | ||
| 951 | } | ||
| 952 | |||
| 953 | /** | ||
| 954 | * contains_ecryptfs_marker - check for the ecryptfs marker | ||
| 955 | * @data: The data block in which to check | ||
| 956 | * | ||
| 957 | * Returns one if marker found; zero if not found | ||
| 958 | */ | ||
| 959 | int contains_ecryptfs_marker(char *data) | ||
| 960 | { | ||
| 961 | u32 m_1, m_2; | ||
| 962 | |||
| 963 | memcpy(&m_1, data, 4); | ||
| 964 | m_1 = be32_to_cpu(m_1); | ||
| 965 | memcpy(&m_2, (data + 4), 4); | ||
| 966 | m_2 = be32_to_cpu(m_2); | ||
| 967 | if ((m_1 ^ MAGIC_ECRYPTFS_MARKER) == m_2) | ||
| 968 | return 1; | ||
| 969 | ecryptfs_printk(KERN_DEBUG, "m_1 = [0x%.8x]; m_2 = [0x%.8x]; " | ||
| 970 | "MAGIC_ECRYPTFS_MARKER = [0x%.8x]\n", m_1, m_2, | ||
| 971 | MAGIC_ECRYPTFS_MARKER); | ||
| 972 | ecryptfs_printk(KERN_DEBUG, "(m_1 ^ MAGIC_ECRYPTFS_MARKER) = " | ||
| 973 | "[0x%.8x]\n", (m_1 ^ MAGIC_ECRYPTFS_MARKER)); | ||
| 974 | return 0; | ||
| 975 | } | ||
| 976 | |||
| 977 | struct ecryptfs_flag_map_elem { | ||
| 978 | u32 file_flag; | ||
| 979 | u32 local_flag; | ||
| 980 | }; | ||
| 981 | |||
| 982 | /* Add support for additional flags by adding elements here. */ | ||
| 983 | static struct ecryptfs_flag_map_elem ecryptfs_flag_map[] = { | ||
| 984 | {0x00000001, ECRYPTFS_ENABLE_HMAC}, | ||
| 985 | {0x00000002, ECRYPTFS_ENCRYPTED} | ||
| 986 | }; | ||
| 987 | |||
| 988 | /** | ||
| 989 | * ecryptfs_process_flags | ||
| 990 | * @crypt_stat | ||
| 991 | * @page_virt: Source data to be parsed | ||
| 992 | * @bytes_read: Updated with the number of bytes read | ||
| 993 | * | ||
| 994 | * Returns zero on success; non-zero if the flag set is invalid | ||
| 995 | */ | ||
| 996 | static int ecryptfs_process_flags(struct ecryptfs_crypt_stat *crypt_stat, | ||
| 997 | char *page_virt, int *bytes_read) | ||
| 998 | { | ||
| 999 | int rc = 0; | ||
| 1000 | int i; | ||
| 1001 | u32 flags; | ||
| 1002 | |||
| 1003 | memcpy(&flags, page_virt, 4); | ||
| 1004 | flags = be32_to_cpu(flags); | ||
| 1005 | for (i = 0; i < ((sizeof(ecryptfs_flag_map) | ||
| 1006 | / sizeof(struct ecryptfs_flag_map_elem))); i++) | ||
| 1007 | if (flags & ecryptfs_flag_map[i].file_flag) { | ||
| 1008 | ECRYPTFS_SET_FLAG(crypt_stat->flags, | ||
| 1009 | ecryptfs_flag_map[i].local_flag); | ||
| 1010 | } else | ||
| 1011 | ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, | ||
| 1012 | ecryptfs_flag_map[i].local_flag); | ||
| 1013 | /* Version is in top 8 bits of the 32-bit flag vector */ | ||
| 1014 | crypt_stat->file_version = ((flags >> 24) & 0xFF); | ||
| 1015 | (*bytes_read) = 4; | ||
| 1016 | return rc; | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | /** | ||
| 1020 | * write_ecryptfs_marker | ||
| 1021 | * @page_virt: The pointer to in a page to begin writing the marker | ||
| 1022 | * @written: Number of bytes written | ||
| 1023 | * | ||
| 1024 | * Marker = 0x3c81b7f5 | ||
| 1025 | */ | ||
| 1026 | static void write_ecryptfs_marker(char *page_virt, size_t *written) | ||
| 1027 | { | ||
| 1028 | u32 m_1, m_2; | ||
| 1029 | |||
| 1030 | get_random_bytes(&m_1, (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2)); | ||
| 1031 | m_2 = (m_1 ^ MAGIC_ECRYPTFS_MARKER); | ||
| 1032 | m_1 = cpu_to_be32(m_1); | ||
| 1033 | memcpy(page_virt, &m_1, (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2)); | ||
| 1034 | m_2 = cpu_to_be32(m_2); | ||
| 1035 | memcpy(page_virt + (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2), &m_2, | ||
| 1036 | (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2)); | ||
| 1037 | (*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; | ||
| 1038 | } | ||
| 1039 | |||
| 1040 | static void | ||
| 1041 | write_ecryptfs_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat, | ||
| 1042 | size_t *written) | ||
| 1043 | { | ||
| 1044 | u32 flags = 0; | ||
| 1045 | int i; | ||
| 1046 | |||
| 1047 | for (i = 0; i < ((sizeof(ecryptfs_flag_map) | ||
| 1048 | / sizeof(struct ecryptfs_flag_map_elem))); i++) | ||
| 1049 | if (ECRYPTFS_CHECK_FLAG(crypt_stat->flags, | ||
| 1050 | ecryptfs_flag_map[i].local_flag)) | ||
| 1051 | flags |= ecryptfs_flag_map[i].file_flag; | ||
| 1052 | /* Version is in top 8 bits of the 32-bit flag vector */ | ||
| 1053 | flags |= ((((u8)crypt_stat->file_version) << 24) & 0xFF000000); | ||
| 1054 | flags = cpu_to_be32(flags); | ||
| 1055 | memcpy(page_virt, &flags, 4); | ||
| 1056 | (*written) = 4; | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | struct ecryptfs_cipher_code_str_map_elem { | ||
| 1060 | char cipher_str[16]; | ||
| 1061 | u16 cipher_code; | ||
| 1062 | }; | ||
| 1063 | |||
| 1064 | /* Add support for additional ciphers by adding elements here. The | ||
| 1065 | * cipher_code is whatever OpenPGP applicatoins use to identify the | ||
| 1066 | * ciphers. List in order of probability. */ | ||
| 1067 | static struct ecryptfs_cipher_code_str_map_elem | ||
| 1068 | ecryptfs_cipher_code_str_map[] = { | ||
| 1069 | {"aes",RFC2440_CIPHER_AES_128 }, | ||
| 1070 | {"blowfish", RFC2440_CIPHER_BLOWFISH}, | ||
| 1071 | {"des3_ede", RFC2440_CIPHER_DES3_EDE}, | ||
| 1072 | {"cast5", RFC2440_CIPHER_CAST_5}, | ||
| 1073 | {"twofish", RFC2440_CIPHER_TWOFISH}, | ||
| 1074 | {"cast6", RFC2440_CIPHER_CAST_6}, | ||
| 1075 | {"aes", RFC2440_CIPHER_AES_192}, | ||
| 1076 | {"aes", RFC2440_CIPHER_AES_256} | ||
| 1077 | }; | ||
| 1078 | |||
| 1079 | /** | ||
| 1080 | * ecryptfs_code_for_cipher_string | ||
| 1081 | * @str: The string representing the cipher name | ||
| 1082 | * | ||
| 1083 | * Returns zero on no match, or the cipher code on match | ||
| 1084 | */ | ||
| 1085 | u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat) | ||
| 1086 | { | ||
| 1087 | int i; | ||
| 1088 | u16 code = 0; | ||
| 1089 | struct ecryptfs_cipher_code_str_map_elem *map = | ||
| 1090 | ecryptfs_cipher_code_str_map; | ||
| 1091 | |||
| 1092 | if (strcmp(crypt_stat->cipher, "aes") == 0) { | ||
| 1093 | switch (crypt_stat->key_size) { | ||
| 1094 | case 16: | ||
| 1095 | code = RFC2440_CIPHER_AES_128; | ||
| 1096 | break; | ||
| 1097 | case 24: | ||
| 1098 | code = RFC2440_CIPHER_AES_192; | ||
| 1099 | break; | ||
| 1100 | case 32: | ||
| 1101 | code = RFC2440_CIPHER_AES_256; | ||
| 1102 | } | ||
| 1103 | } else { | ||
| 1104 | for (i = 0; i < ARRAY_SIZE(ecryptfs_cipher_code_str_map); i++) | ||
| 1105 | if (strcmp(crypt_stat->cipher, map[i].cipher_str) == 0){ | ||
| 1106 | code = map[i].cipher_code; | ||
| 1107 | break; | ||
| 1108 | } | ||
| 1109 | } | ||
| 1110 | return code; | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | /** | ||
| 1114 | * ecryptfs_cipher_code_to_string | ||
| 1115 | * @str: Destination to write out the cipher name | ||
| 1116 | * @cipher_code: The code to convert to cipher name string | ||
| 1117 | * | ||
| 1118 | * Returns zero on success | ||
| 1119 | */ | ||
| 1120 | int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code) | ||
| 1121 | { | ||
| 1122 | int rc = 0; | ||
| 1123 | int i; | ||
| 1124 | |||
| 1125 | str[0] = '\0'; | ||
| 1126 | for (i = 0; i < ARRAY_SIZE(ecryptfs_cipher_code_str_map); i++) | ||
| 1127 | if (cipher_code == ecryptfs_cipher_code_str_map[i].cipher_code) | ||
| 1128 | strcpy(str, ecryptfs_cipher_code_str_map[i].cipher_str); | ||
| 1129 | if (str[0] == '\0') { | ||
| 1130 | ecryptfs_printk(KERN_WARNING, "Cipher code not recognized: " | ||
| 1131 | "[%d]\n", cipher_code); | ||
| 1132 | rc = -EINVAL; | ||
| 1133 | } | ||
| 1134 | return rc; | ||
| 1135 | } | ||
| 1136 | |||
| 1137 | /** | ||
| 1138 | * ecryptfs_read_header_region | ||
| 1139 | * @data | ||
| 1140 | * @dentry | ||
| 1141 | * @nd | ||
| 1142 | * | ||
| 1143 | * Returns zero on success; non-zero otherwise | ||
| 1144 | */ | ||
| 1145 | int ecryptfs_read_header_region(char *data, struct dentry *dentry, | ||
| 1146 | struct vfsmount *mnt) | ||
| 1147 | { | ||
| 1148 | struct file *file; | ||
| 1149 | mm_segment_t oldfs; | ||
| 1150 | int rc; | ||
| 1151 | |||
| 1152 | mnt = mntget(mnt); | ||
| 1153 | file = dentry_open(dentry, mnt, O_RDONLY); | ||
| 1154 | if (IS_ERR(file)) { | ||
| 1155 | ecryptfs_printk(KERN_DEBUG, "Error opening file to " | ||
| 1156 | "read header region\n"); | ||
| 1157 | mntput(mnt); | ||
| 1158 | rc = PTR_ERR(file); | ||
| 1159 | goto out; | ||
| 1160 | } | ||
| 1161 | file->f_pos = 0; | ||
| 1162 | oldfs = get_fs(); | ||
| 1163 | set_fs(get_ds()); | ||
| 1164 | /* For releases 0.1 and 0.2, all of the header information | ||
| 1165 | * fits in the first data extent-sized region. */ | ||
| 1166 | rc = file->f_op->read(file, (char __user *)data, | ||
| 1167 | ECRYPTFS_DEFAULT_EXTENT_SIZE, &file->f_pos); | ||
| 1168 | set_fs(oldfs); | ||
| 1169 | fput(file); | ||
| 1170 | rc = 0; | ||
| 1171 | out: | ||
| 1172 | return rc; | ||
| 1173 | } | ||
| 1174 | |||
| 1175 | static void | ||
| 1176 | write_header_metadata(char *virt, struct ecryptfs_crypt_stat *crypt_stat, | ||
| 1177 | size_t *written) | ||
| 1178 | { | ||
| 1179 | u32 header_extent_size; | ||
| 1180 | u16 num_header_extents_at_front; | ||
| 1181 | |||
| 1182 | header_extent_size = (u32)crypt_stat->header_extent_size; | ||
| 1183 | num_header_extents_at_front = | ||
| 1184 | (u16)crypt_stat->num_header_extents_at_front; | ||
| 1185 | header_extent_size = cpu_to_be32(header_extent_size); | ||
| 1186 | memcpy(virt, &header_extent_size, 4); | ||
| 1187 | virt += 4; | ||
| 1188 | num_header_extents_at_front = cpu_to_be16(num_header_extents_at_front); | ||
| 1189 | memcpy(virt, &num_header_extents_at_front, 2); | ||
| 1190 | (*written) = 6; | ||
| 1191 | } | ||
| 1192 | |||
| 1193 | struct kmem_cache *ecryptfs_header_cache_0; | ||
| 1194 | struct kmem_cache *ecryptfs_header_cache_1; | ||
| 1195 | struct kmem_cache *ecryptfs_header_cache_2; | ||
| 1196 | |||
| 1197 | /** | ||
| 1198 | * ecryptfs_write_headers_virt | ||
| 1199 | * @page_virt | ||
| 1200 | * @crypt_stat | ||
| 1201 | * @ecryptfs_dentry | ||
| 1202 | * | ||
| 1203 | * Format version: 1 | ||
| 1204 | * | ||
| 1205 | * Header Extent: | ||
| 1206 | * Octets 0-7: Unencrypted file size (big-endian) | ||
| 1207 | * Octets 8-15: eCryptfs special marker | ||
| 1208 | * Octets 16-19: Flags | ||
| 1209 | * Octet 16: File format version number (between 0 and 255) | ||
| 1210 | * Octets 17-18: Reserved | ||
| 1211 | * Octet 19: Bit 1 (lsb): Reserved | ||
| 1212 | * Bit 2: Encrypted? | ||
| 1213 | * Bits 3-8: Reserved | ||
| 1214 | * Octets 20-23: Header extent size (big-endian) | ||
| 1215 | * Octets 24-25: Number of header extents at front of file | ||
| 1216 | * (big-endian) | ||
| 1217 | * Octet 26: Begin RFC 2440 authentication token packet set | ||
| 1218 | * Data Extent 0: | ||
| 1219 | * Lower data (CBC encrypted) | ||
| 1220 | * Data Extent 1: | ||
| 1221 | * Lower data (CBC encrypted) | ||
| 1222 | * ... | ||
| 1223 | * | ||
| 1224 | * Returns zero on success | ||
| 1225 | */ | ||
| 1226 | int ecryptfs_write_headers_virt(char *page_virt, | ||
| 1227 | struct ecryptfs_crypt_stat *crypt_stat, | ||
| 1228 | struct dentry *ecryptfs_dentry) | ||
| 1229 | { | ||
| 1230 | int rc; | ||
| 1231 | size_t written; | ||
| 1232 | size_t offset; | ||
| 1233 | |||
| 1234 | offset = ECRYPTFS_FILE_SIZE_BYTES; | ||
| 1235 | write_ecryptfs_marker((page_virt + offset), &written); | ||
| 1236 | offset += written; | ||
| 1237 | write_ecryptfs_flags((page_virt + offset), crypt_stat, &written); | ||
| 1238 | offset += written; | ||
| 1239 | write_header_metadata((page_virt + offset), crypt_stat, &written); | ||
| 1240 | offset += written; | ||
| 1241 | rc = ecryptfs_generate_key_packet_set((page_virt + offset), crypt_stat, | ||
| 1242 | ecryptfs_dentry, &written, | ||
| 1243 | PAGE_CACHE_SIZE - offset); | ||
| 1244 | if (rc) | ||
| 1245 | ecryptfs_printk(KERN_WARNING, "Error generating key packet " | ||
| 1246 | "set; rc = [%d]\n", rc); | ||
| 1247 | return rc; | ||
| 1248 | } | ||
| 1249 | |||
| 1250 | /** | ||
| 1251 | * ecryptfs_write_headers | ||
| 1252 | * @lower_file: The lower file struct, which was returned from dentry_open | ||
| 1253 | * | ||
| 1254 | * Write the file headers out. This will likely involve a userspace | ||
| 1255 | * callout, in which the session key is encrypted with one or more | ||
| 1256 | * public keys and/or the passphrase necessary to do the encryption is | ||
| 1257 | * retrieved via a prompt. Exactly what happens at this point should | ||
| 1258 | * be policy-dependent. | ||
| 1259 | * | ||
| 1260 | * Returns zero on success; non-zero on error | ||
| 1261 | */ | ||
| 1262 | int ecryptfs_write_headers(struct dentry *ecryptfs_dentry, | ||
| 1263 | struct file *lower_file) | ||
| 1264 | { | ||
| 1265 | mm_segment_t oldfs; | ||
| 1266 | struct ecryptfs_crypt_stat *crypt_stat; | ||
| 1267 | char *page_virt; | ||
| 1268 | int current_header_page; | ||
| 1269 | int header_pages; | ||
| 1270 | int rc = 0; | ||
| 1271 | |||
| 1272 | crypt_stat = &ecryptfs_inode_to_private( | ||
| 1273 | ecryptfs_dentry->d_inode)->crypt_stat; | ||
| 1274 | if (likely(ECRYPTFS_CHECK_FLAG(crypt_stat->flags, | ||
| 1275 | ECRYPTFS_ENCRYPTED))) { | ||
| 1276 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, | ||
| 1277 | ECRYPTFS_KEY_VALID)) { | ||
| 1278 | ecryptfs_printk(KERN_DEBUG, "Key is " | ||
| 1279 | "invalid; bailing out\n"); | ||
| 1280 | rc = -EINVAL; | ||
| 1281 | goto out; | ||
| 1282 | } | ||
| 1283 | } else { | ||
| 1284 | rc = -EINVAL; | ||
| 1285 | ecryptfs_printk(KERN_WARNING, | ||
| 1286 | "Called with crypt_stat->encrypted == 0\n"); | ||
| 1287 | goto out; | ||
| 1288 | } | ||
| 1289 | /* Released in this function */ | ||
| 1290 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_0, SLAB_USER); | ||
| 1291 | if (!page_virt) { | ||
| 1292 | ecryptfs_printk(KERN_ERR, "Out of memory\n"); | ||
| 1293 | rc = -ENOMEM; | ||
| 1294 | goto out; | ||
| 1295 | } | ||
| 1296 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
| 1297 | rc = ecryptfs_write_headers_virt(page_virt, crypt_stat, | ||
| 1298 | ecryptfs_dentry); | ||
| 1299 | if (unlikely(rc)) { | ||
| 1300 | ecryptfs_printk(KERN_ERR, "Error whilst writing headers\n"); | ||
| 1301 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
| 1302 | goto out_free; | ||
| 1303 | } | ||
| 1304 | ecryptfs_printk(KERN_DEBUG, | ||
| 1305 | "Writing key packet set to underlying file\n"); | ||
| 1306 | lower_file->f_pos = 0; | ||
| 1307 | oldfs = get_fs(); | ||
| 1308 | set_fs(get_ds()); | ||
| 1309 | ecryptfs_printk(KERN_DEBUG, "Calling lower_file->f_op->" | ||
| 1310 | "write() w/ header page; lower_file->f_pos = " | ||
| 1311 | "[0x%.16x]\n", lower_file->f_pos); | ||
| 1312 | lower_file->f_op->write(lower_file, (char __user *)page_virt, | ||
| 1313 | PAGE_CACHE_SIZE, &lower_file->f_pos); | ||
| 1314 | header_pages = ((crypt_stat->header_extent_size | ||
| 1315 | * crypt_stat->num_header_extents_at_front) | ||
| 1316 | / PAGE_CACHE_SIZE); | ||
| 1317 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
| 1318 | current_header_page = 1; | ||
| 1319 | while (current_header_page < header_pages) { | ||
| 1320 | ecryptfs_printk(KERN_DEBUG, "Calling lower_file->f_op->" | ||
| 1321 | "write() w/ zero'd page; lower_file->f_pos = " | ||
| 1322 | "[0x%.16x]\n", lower_file->f_pos); | ||
| 1323 | lower_file->f_op->write(lower_file, (char __user *)page_virt, | ||
| 1324 | PAGE_CACHE_SIZE, &lower_file->f_pos); | ||
| 1325 | current_header_page++; | ||
| 1326 | } | ||
| 1327 | set_fs(oldfs); | ||
| 1328 | ecryptfs_printk(KERN_DEBUG, | ||
| 1329 | "Done writing key packet set to underlying file.\n"); | ||
| 1330 | out_free: | ||
| 1331 | kmem_cache_free(ecryptfs_header_cache_0, page_virt); | ||
| 1332 | out: | ||
| 1333 | return rc; | ||
| 1334 | } | ||
| 1335 | |||
| 1336 | static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat, | ||
| 1337 | char *virt, int *bytes_read) | ||
| 1338 | { | ||
| 1339 | int rc = 0; | ||
| 1340 | u32 header_extent_size; | ||
| 1341 | u16 num_header_extents_at_front; | ||
| 1342 | |||
| 1343 | memcpy(&header_extent_size, virt, 4); | ||
| 1344 | header_extent_size = be32_to_cpu(header_extent_size); | ||
| 1345 | virt += 4; | ||
| 1346 | memcpy(&num_header_extents_at_front, virt, 2); | ||
| 1347 | num_header_extents_at_front = be16_to_cpu(num_header_extents_at_front); | ||
| 1348 | crypt_stat->header_extent_size = (int)header_extent_size; | ||
| 1349 | crypt_stat->num_header_extents_at_front = | ||
| 1350 | (int)num_header_extents_at_front; | ||
| 1351 | (*bytes_read) = 6; | ||
| 1352 | if ((crypt_stat->header_extent_size | ||
| 1353 | * crypt_stat->num_header_extents_at_front) | ||
| 1354 | < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) { | ||
| 1355 | rc = -EINVAL; | ||
| 1356 | ecryptfs_printk(KERN_WARNING, "Invalid header extent size: " | ||
| 1357 | "[%d]\n", crypt_stat->header_extent_size); | ||
| 1358 | } | ||
| 1359 | return rc; | ||
| 1360 | } | ||
| 1361 | |||
| 1362 | /** | ||
| 1363 | * set_default_header_data | ||
| 1364 | * | ||
| 1365 | * For version 0 file format; this function is only for backwards | ||
| 1366 | * compatibility for files created with the prior versions of | ||
| 1367 | * eCryptfs. | ||
| 1368 | */ | ||
| 1369 | static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat) | ||
| 1370 | { | ||
| 1371 | crypt_stat->header_extent_size = 4096; | ||
| 1372 | crypt_stat->num_header_extents_at_front = 1; | ||
| 1373 | } | ||
| 1374 | |||
| 1375 | /** | ||
| 1376 | * ecryptfs_read_headers_virt | ||
| 1377 | * | ||
| 1378 | * Read/parse the header data. The header format is detailed in the | ||
| 1379 | * comment block for the ecryptfs_write_headers_virt() function. | ||
| 1380 | * | ||
| 1381 | * Returns zero on success | ||
| 1382 | */ | ||
| 1383 | static int ecryptfs_read_headers_virt(char *page_virt, | ||
| 1384 | struct ecryptfs_crypt_stat *crypt_stat, | ||
| 1385 | struct dentry *ecryptfs_dentry) | ||
| 1386 | { | ||
| 1387 | int rc = 0; | ||
| 1388 | int offset; | ||
| 1389 | int bytes_read; | ||
| 1390 | |||
| 1391 | ecryptfs_set_default_sizes(crypt_stat); | ||
| 1392 | crypt_stat->mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
| 1393 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | ||
| 1394 | offset = ECRYPTFS_FILE_SIZE_BYTES; | ||
| 1395 | rc = contains_ecryptfs_marker(page_virt + offset); | ||
| 1396 | if (rc == 0) { | ||
| 1397 | rc = -EINVAL; | ||
| 1398 | goto out; | ||
| 1399 | } | ||
| 1400 | offset += MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; | ||
| 1401 | rc = ecryptfs_process_flags(crypt_stat, (page_virt + offset), | ||
| 1402 | &bytes_read); | ||
| 1403 | if (rc) { | ||
| 1404 | ecryptfs_printk(KERN_WARNING, "Error processing flags\n"); | ||
| 1405 | goto out; | ||
| 1406 | } | ||
| 1407 | if (crypt_stat->file_version > ECRYPTFS_SUPPORTED_FILE_VERSION) { | ||
| 1408 | ecryptfs_printk(KERN_WARNING, "File version is [%d]; only " | ||
| 1409 | "file version [%d] is supported by this " | ||
| 1410 | "version of eCryptfs\n", | ||
| 1411 | crypt_stat->file_version, | ||
| 1412 | ECRYPTFS_SUPPORTED_FILE_VERSION); | ||
| 1413 | rc = -EINVAL; | ||
| 1414 | goto out; | ||
| 1415 | } | ||
| 1416 | offset += bytes_read; | ||
| 1417 | if (crypt_stat->file_version >= 1) { | ||
| 1418 | rc = parse_header_metadata(crypt_stat, (page_virt + offset), | ||
| 1419 | &bytes_read); | ||
| 1420 | if (rc) { | ||
| 1421 | ecryptfs_printk(KERN_WARNING, "Error reading header " | ||
| 1422 | "metadata; rc = [%d]\n", rc); | ||
| 1423 | } | ||
| 1424 | offset += bytes_read; | ||
| 1425 | } else | ||
| 1426 | set_default_header_data(crypt_stat); | ||
| 1427 | rc = ecryptfs_parse_packet_set(crypt_stat, (page_virt + offset), | ||
| 1428 | ecryptfs_dentry); | ||
| 1429 | out: | ||
| 1430 | return rc; | ||
| 1431 | } | ||
| 1432 | |||
| 1433 | /** | ||
| 1434 | * ecryptfs_read_headers | ||
| 1435 | * | ||
| 1436 | * Returns zero if valid headers found and parsed; non-zero otherwise | ||
| 1437 | */ | ||
| 1438 | int ecryptfs_read_headers(struct dentry *ecryptfs_dentry, | ||
| 1439 | struct file *lower_file) | ||
| 1440 | { | ||
| 1441 | int rc = 0; | ||
| 1442 | char *page_virt = NULL; | ||
| 1443 | mm_segment_t oldfs; | ||
| 1444 | ssize_t bytes_read; | ||
| 1445 | struct ecryptfs_crypt_stat *crypt_stat = | ||
| 1446 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; | ||
| 1447 | |||
| 1448 | /* Read the first page from the underlying file */ | ||
| 1449 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, SLAB_USER); | ||
| 1450 | if (!page_virt) { | ||
| 1451 | rc = -ENOMEM; | ||
| 1452 | ecryptfs_printk(KERN_ERR, "Unable to allocate page_virt\n"); | ||
| 1453 | goto out; | ||
| 1454 | } | ||
| 1455 | lower_file->f_pos = 0; | ||
| 1456 | oldfs = get_fs(); | ||
| 1457 | set_fs(get_ds()); | ||
| 1458 | bytes_read = lower_file->f_op->read(lower_file, | ||
| 1459 | (char __user *)page_virt, | ||
| 1460 | ECRYPTFS_DEFAULT_EXTENT_SIZE, | ||
| 1461 | &lower_file->f_pos); | ||
| 1462 | set_fs(oldfs); | ||
| 1463 | if (bytes_read != ECRYPTFS_DEFAULT_EXTENT_SIZE) { | ||
| 1464 | rc = -EINVAL; | ||
| 1465 | goto out; | ||
| 1466 | } | ||
| 1467 | rc = ecryptfs_read_headers_virt(page_virt, crypt_stat, | ||
| 1468 | ecryptfs_dentry); | ||
| 1469 | if (rc) { | ||
| 1470 | ecryptfs_printk(KERN_DEBUG, "Valid eCryptfs headers not " | ||
| 1471 | "found\n"); | ||
| 1472 | rc = -EINVAL; | ||
| 1473 | } | ||
| 1474 | out: | ||
| 1475 | if (page_virt) { | ||
| 1476 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
| 1477 | kmem_cache_free(ecryptfs_header_cache_1, page_virt); | ||
| 1478 | } | ||
| 1479 | return rc; | ||
| 1480 | } | ||
| 1481 | |||
| 1482 | /** | ||
| 1483 | * ecryptfs_encode_filename - converts a plaintext file name to cipher text | ||
| 1484 | * @crypt_stat: The crypt_stat struct associated with the file anem to encode | ||
| 1485 | * @name: The plaintext name | ||
| 1486 | * @length: The length of the plaintext | ||
| 1487 | * @encoded_name: The encypted name | ||
| 1488 | * | ||
| 1489 | * Encrypts and encodes a filename into something that constitutes a | ||
| 1490 | * valid filename for a filesystem, with printable characters. | ||
| 1491 | * | ||
| 1492 | * We assume that we have a properly initialized crypto context, | ||
| 1493 | * pointed to by crypt_stat->tfm. | ||
| 1494 | * | ||
| 1495 | * TODO: Implement filename decoding and decryption here, in place of | ||
| 1496 | * memcpy. We are keeping the framework around for now to (1) | ||
| 1497 | * facilitate testing of the components needed to implement filename | ||
| 1498 | * encryption and (2) to provide a code base from which other | ||
| 1499 | * developers in the community can easily implement this feature. | ||
| 1500 | * | ||
| 1501 | * Returns the length of encoded filename; negative if error | ||
| 1502 | */ | ||
| 1503 | int | ||
| 1504 | ecryptfs_encode_filename(struct ecryptfs_crypt_stat *crypt_stat, | ||
| 1505 | const char *name, int length, char **encoded_name) | ||
| 1506 | { | ||
| 1507 | int error = 0; | ||
| 1508 | |||
| 1509 | (*encoded_name) = kmalloc(length + 2, GFP_KERNEL); | ||
| 1510 | if (!(*encoded_name)) { | ||
| 1511 | error = -ENOMEM; | ||
| 1512 | goto out; | ||
| 1513 | } | ||
| 1514 | /* TODO: Filename encryption is a scheduled feature for a | ||
| 1515 | * future version of eCryptfs. This function is here only for | ||
| 1516 | * the purpose of providing a framework for other developers | ||
| 1517 | * to easily implement filename encryption. Hint: Replace this | ||
| 1518 | * memcpy() with a call to encrypt and encode the | ||
| 1519 | * filename, the set the length accordingly. */ | ||
| 1520 | memcpy((void *)(*encoded_name), (void *)name, length); | ||
| 1521 | (*encoded_name)[length] = '\0'; | ||
| 1522 | error = length + 1; | ||
| 1523 | out: | ||
| 1524 | return error; | ||
| 1525 | } | ||
| 1526 | |||
| 1527 | /** | ||
| 1528 | * ecryptfs_decode_filename - converts the cipher text name to plaintext | ||
| 1529 | * @crypt_stat: The crypt_stat struct associated with the file | ||
| 1530 | * @name: The filename in cipher text | ||
| 1531 | * @length: The length of the cipher text name | ||
| 1532 | * @decrypted_name: The plaintext name | ||
| 1533 | * | ||
| 1534 | * Decodes and decrypts the filename. | ||
| 1535 | * | ||
| 1536 | * We assume that we have a properly initialized crypto context, | ||
| 1537 | * pointed to by crypt_stat->tfm. | ||
| 1538 | * | ||
| 1539 | * TODO: Implement filename decoding and decryption here, in place of | ||
| 1540 | * memcpy. We are keeping the framework around for now to (1) | ||
| 1541 | * facilitate testing of the components needed to implement filename | ||
| 1542 | * encryption and (2) to provide a code base from which other | ||
| 1543 | * developers in the community can easily implement this feature. | ||
| 1544 | * | ||
| 1545 | * Returns the length of decoded filename; negative if error | ||
| 1546 | */ | ||
| 1547 | int | ||
| 1548 | ecryptfs_decode_filename(struct ecryptfs_crypt_stat *crypt_stat, | ||
| 1549 | const char *name, int length, char **decrypted_name) | ||
| 1550 | { | ||
| 1551 | int error = 0; | ||
| 1552 | |||
| 1553 | (*decrypted_name) = kmalloc(length + 2, GFP_KERNEL); | ||
| 1554 | if (!(*decrypted_name)) { | ||
| 1555 | error = -ENOMEM; | ||
| 1556 | goto out; | ||
| 1557 | } | ||
| 1558 | /* TODO: Filename encryption is a scheduled feature for a | ||
| 1559 | * future version of eCryptfs. This function is here only for | ||
| 1560 | * the purpose of providing a framework for other developers | ||
| 1561 | * to easily implement filename encryption. Hint: Replace this | ||
| 1562 | * memcpy() with a call to decode and decrypt the | ||
| 1563 | * filename, the set the length accordingly. */ | ||
| 1564 | memcpy((void *)(*decrypted_name), (void *)name, length); | ||
| 1565 | (*decrypted_name)[length + 1] = '\0'; /* Only for convenience | ||
| 1566 | * in printing out the | ||
| 1567 | * string in debug | ||
| 1568 | * messages */ | ||
| 1569 | error = length; | ||
| 1570 | out: | ||
| 1571 | return error; | ||
| 1572 | } | ||
| 1573 | |||
| 1574 | /** | ||
| 1575 | * ecryptfs_process_cipher - Perform cipher initialization. | ||
| 1576 | * @tfm: Crypto context set by this function | ||
| 1577 | * @key_tfm: Crypto context for key material, set by this function | ||
| 1578 | * @cipher_name: Name of the cipher. | ||
| 1579 | * @key_size: Size of the key in bytes. | ||
| 1580 | * | ||
| 1581 | * Returns zero on success. Any crypto_tfm structs allocated here | ||
| 1582 | * should be released by other functions, such as on a superblock put | ||
| 1583 | * event, regardless of whether this function succeeds for fails. | ||
| 1584 | */ | ||
| 1585 | int | ||
| 1586 | ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm, | ||
| 1587 | char *cipher_name, size_t key_size) | ||
| 1588 | { | ||
| 1589 | char dummy_key[ECRYPTFS_MAX_KEY_BYTES]; | ||
| 1590 | int rc; | ||
| 1591 | |||
| 1592 | *tfm = *key_tfm = NULL; | ||
| 1593 | if (key_size > ECRYPTFS_MAX_KEY_BYTES) { | ||
| 1594 | rc = -EINVAL; | ||
| 1595 | printk(KERN_ERR "Requested key size is [%Zd] bytes; maximum " | ||
| 1596 | "allowable is [%d]\n", key_size, ECRYPTFS_MAX_KEY_BYTES); | ||
| 1597 | goto out; | ||
| 1598 | } | ||
| 1599 | *tfm = crypto_alloc_tfm(cipher_name, (ECRYPTFS_DEFAULT_CHAINING_MODE | ||
| 1600 | | CRYPTO_TFM_REQ_WEAK_KEY)); | ||
| 1601 | if (!(*tfm)) { | ||
| 1602 | rc = -EINVAL; | ||
| 1603 | printk(KERN_ERR "Unable to allocate crypto cipher with name " | ||
| 1604 | "[%s]\n", cipher_name); | ||
| 1605 | goto out; | ||
| 1606 | } | ||
| 1607 | *key_tfm = crypto_alloc_tfm(cipher_name, CRYPTO_TFM_REQ_WEAK_KEY); | ||
| 1608 | if (!(*key_tfm)) { | ||
| 1609 | rc = -EINVAL; | ||
| 1610 | printk(KERN_ERR "Unable to allocate crypto cipher with name " | ||
| 1611 | "[%s]\n", cipher_name); | ||
| 1612 | goto out; | ||
| 1613 | } | ||
| 1614 | if (key_size < crypto_tfm_alg_min_keysize(*tfm)) { | ||
| 1615 | rc = -EINVAL; | ||
| 1616 | printk(KERN_ERR "Request key size is [%Zd]; minimum key size " | ||
| 1617 | "supported by cipher [%s] is [%d]\n", key_size, | ||
| 1618 | cipher_name, crypto_tfm_alg_min_keysize(*tfm)); | ||
| 1619 | goto out; | ||
| 1620 | } | ||
| 1621 | if (key_size < crypto_tfm_alg_min_keysize(*key_tfm)) { | ||
| 1622 | rc = -EINVAL; | ||
| 1623 | printk(KERN_ERR "Request key size is [%Zd]; minimum key size " | ||
| 1624 | "supported by cipher [%s] is [%d]\n", key_size, | ||
| 1625 | cipher_name, crypto_tfm_alg_min_keysize(*key_tfm)); | ||
| 1626 | goto out; | ||
| 1627 | } | ||
| 1628 | if (key_size > crypto_tfm_alg_max_keysize(*tfm)) { | ||
| 1629 | rc = -EINVAL; | ||
| 1630 | printk(KERN_ERR "Request key size is [%Zd]; maximum key size " | ||
| 1631 | "supported by cipher [%s] is [%d]\n", key_size, | ||
| 1632 | cipher_name, crypto_tfm_alg_min_keysize(*tfm)); | ||
| 1633 | goto out; | ||
| 1634 | } | ||
| 1635 | if (key_size > crypto_tfm_alg_max_keysize(*key_tfm)) { | ||
| 1636 | rc = -EINVAL; | ||
| 1637 | printk(KERN_ERR "Request key size is [%Zd]; maximum key size " | ||
| 1638 | "supported by cipher [%s] is [%d]\n", key_size, | ||
| 1639 | cipher_name, crypto_tfm_alg_min_keysize(*key_tfm)); | ||
| 1640 | goto out; | ||
| 1641 | } | ||
| 1642 | get_random_bytes(dummy_key, key_size); | ||
| 1643 | rc = crypto_cipher_setkey(*tfm, dummy_key, key_size); | ||
| 1644 | if (rc) { | ||
| 1645 | printk(KERN_ERR "Error attempting to set key of size [%Zd] for " | ||
| 1646 | "cipher [%s]; rc = [%d]\n", key_size, cipher_name, rc); | ||
| 1647 | rc = -EINVAL; | ||
| 1648 | goto out; | ||
| 1649 | } | ||
| 1650 | rc = crypto_cipher_setkey(*key_tfm, dummy_key, key_size); | ||
| 1651 | if (rc) { | ||
| 1652 | printk(KERN_ERR "Error attempting to set key of size [%Zd] for " | ||
| 1653 | "cipher [%s]; rc = [%d]\n", key_size, cipher_name, rc); | ||
| 1654 | rc = -EINVAL; | ||
| 1655 | goto out; | ||
| 1656 | } | ||
| 1657 | out: | ||
| 1658 | return rc; | ||
| 1659 | } | ||
diff --git a/fs/ecryptfs/debug.c b/fs/ecryptfs/debug.c new file mode 100644 index 000000000000..61f8e894284f --- /dev/null +++ b/fs/ecryptfs/debug.c | |||
| @@ -0,0 +1,123 @@ | |||
| 1 | /** | ||
| 2 | * eCryptfs: Linux filesystem encryption layer | ||
| 3 | * Functions only useful for debugging. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2006 International Business Machines Corp. | ||
| 6 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or | ||
| 9 | * modify it under the terms of the GNU General Public License as | ||
| 10 | * published by the Free Software Foundation; either version 2 of the | ||
| 11 | * License, or (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, but | ||
| 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | * General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
| 21 | * 02111-1307, USA. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #include "ecryptfs_kernel.h" | ||
| 25 | |||
| 26 | /** | ||
| 27 | * ecryptfs_dump_auth_tok - debug function to print auth toks | ||
| 28 | * | ||
| 29 | * This function will print the contents of an ecryptfs authentication | ||
| 30 | * token. | ||
| 31 | */ | ||
| 32 | void ecryptfs_dump_auth_tok(struct ecryptfs_auth_tok *auth_tok) | ||
| 33 | { | ||
| 34 | char salt[ECRYPTFS_SALT_SIZE * 2 + 1]; | ||
| 35 | char sig[ECRYPTFS_SIG_SIZE_HEX + 1]; | ||
| 36 | |||
| 37 | ecryptfs_printk(KERN_DEBUG, "Auth tok at mem loc [%p]:\n", | ||
| 38 | auth_tok); | ||
| 39 | if (ECRYPTFS_CHECK_FLAG(auth_tok->flags, ECRYPTFS_PRIVATE_KEY)) { | ||
| 40 | ecryptfs_printk(KERN_DEBUG, " * private key type\n"); | ||
| 41 | ecryptfs_printk(KERN_DEBUG, " * (NO PRIVATE KEY SUPPORT " | ||
| 42 | "IN ECRYPTFS VERSION 0.1)\n"); | ||
| 43 | } else { | ||
| 44 | ecryptfs_printk(KERN_DEBUG, " * passphrase type\n"); | ||
| 45 | ecryptfs_to_hex(salt, auth_tok->token.password.salt, | ||
| 46 | ECRYPTFS_SALT_SIZE); | ||
| 47 | salt[ECRYPTFS_SALT_SIZE * 2] = '\0'; | ||
| 48 | ecryptfs_printk(KERN_DEBUG, " * salt = [%s]\n", salt); | ||
| 49 | if (ECRYPTFS_CHECK_FLAG(auth_tok->token.password.flags, | ||
| 50 | ECRYPTFS_PERSISTENT_PASSWORD)) { | ||
| 51 | ecryptfs_printk(KERN_DEBUG, " * persistent\n"); | ||
| 52 | } | ||
| 53 | memcpy(sig, auth_tok->token.password.signature, | ||
| 54 | ECRYPTFS_SIG_SIZE_HEX); | ||
| 55 | sig[ECRYPTFS_SIG_SIZE_HEX] = '\0'; | ||
| 56 | ecryptfs_printk(KERN_DEBUG, " * signature = [%s]\n", sig); | ||
| 57 | } | ||
| 58 | ecryptfs_printk(KERN_DEBUG, " * session_key.flags = [0x%x]\n", | ||
| 59 | auth_tok->session_key.flags); | ||
| 60 | if (auth_tok->session_key.flags | ||
| 61 | & ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT) | ||
| 62 | ecryptfs_printk(KERN_DEBUG, | ||
| 63 | " * Userspace decrypt request set\n"); | ||
| 64 | if (auth_tok->session_key.flags | ||
| 65 | & ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT) | ||
| 66 | ecryptfs_printk(KERN_DEBUG, | ||
| 67 | " * Userspace encrypt request set\n"); | ||
| 68 | if (auth_tok->session_key.flags & ECRYPTFS_CONTAINS_DECRYPTED_KEY) { | ||
| 69 | ecryptfs_printk(KERN_DEBUG, " * Contains decrypted key\n"); | ||
| 70 | ecryptfs_printk(KERN_DEBUG, | ||
| 71 | " * session_key.decrypted_key_size = [0x%x]\n", | ||
| 72 | auth_tok->session_key.decrypted_key_size); | ||
| 73 | ecryptfs_printk(KERN_DEBUG, " * Decrypted session key " | ||
| 74 | "dump:\n"); | ||
| 75 | if (ecryptfs_verbosity > 0) | ||
| 76 | ecryptfs_dump_hex(auth_tok->session_key.decrypted_key, | ||
| 77 | ECRYPTFS_DEFAULT_KEY_BYTES); | ||
| 78 | } | ||
| 79 | if (auth_tok->session_key.flags & ECRYPTFS_CONTAINS_ENCRYPTED_KEY) { | ||
| 80 | ecryptfs_printk(KERN_DEBUG, " * Contains encrypted key\n"); | ||
| 81 | ecryptfs_printk(KERN_DEBUG, | ||
| 82 | " * session_key.encrypted_key_size = [0x%x]\n", | ||
| 83 | auth_tok->session_key.encrypted_key_size); | ||
| 84 | ecryptfs_printk(KERN_DEBUG, " * Encrypted session key " | ||
| 85 | "dump:\n"); | ||
| 86 | if (ecryptfs_verbosity > 0) | ||
| 87 | ecryptfs_dump_hex(auth_tok->session_key.encrypted_key, | ||
| 88 | auth_tok->session_key. | ||
| 89 | encrypted_key_size); | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 93 | /** | ||
| 94 | * ecryptfs_dump_hex - debug hex printer | ||
| 95 | * @data: string of bytes to be printed | ||
| 96 | * @bytes: number of bytes to print | ||
| 97 | * | ||
| 98 | * Dump hexadecimal representation of char array | ||
| 99 | */ | ||
| 100 | void ecryptfs_dump_hex(char *data, int bytes) | ||
| 101 | { | ||
| 102 | int i = 0; | ||
| 103 | int add_newline = 1; | ||
| 104 | |||
| 105 | if (ecryptfs_verbosity < 1) | ||
| 106 | return; | ||
| 107 | if (bytes != 0) { | ||
| 108 | printk(KERN_DEBUG "0x%.2x.", (unsigned char)data[i]); | ||
| 109 | i++; | ||
| 110 | } | ||
| 111 | while (i < bytes) { | ||
| 112 | printk("0x%.2x.", (unsigned char)data[i]); | ||
| 113 | i++; | ||
| 114 | if (i % 16 == 0) { | ||
| 115 | printk("\n"); | ||
| 116 | add_newline = 0; | ||
| 117 | } else | ||
| 118 | add_newline = 1; | ||
| 119 | } | ||
| 120 | if (add_newline) | ||
| 121 | printk("\n"); | ||
| 122 | } | ||
| 123 | |||
diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c new file mode 100644 index 000000000000..f0d2a433242b --- /dev/null +++ b/fs/ecryptfs/dentry.c | |||
| @@ -0,0 +1,87 @@ | |||
| 1 | /** | ||
| 2 | * eCryptfs: Linux filesystem encryption layer | ||
| 3 | * | ||
| 4 | * Copyright (C) 1997-2003 Erez Zadok | ||
| 5 | * Copyright (C) 2001-2003 Stony Brook University | ||
| 6 | * Copyright (C) 2004-2006 International Business Machines Corp. | ||
| 7 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or | ||
| 10 | * modify it under the terms of the GNU General Public License as | ||
| 11 | * published by the Free Software Foundation; either version 2 of the | ||
| 12 | * License, or (at your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, but | ||
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 17 | * General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
| 22 | * 02111-1307, USA. | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/dcache.h> | ||
| 26 | #include <linux/namei.h> | ||
| 27 | #include "ecryptfs_kernel.h" | ||
| 28 | |||
| 29 | /** | ||
| 30 | * ecryptfs_d_revalidate - revalidate an ecryptfs dentry | ||
| 31 | * @dentry: The ecryptfs dentry | ||
| 32 | * @nd: The associated nameidata | ||
| 33 | * | ||
| 34 | * Called when the VFS needs to revalidate a dentry. This | ||
| 35 | * is called whenever a name lookup finds a dentry in the | ||
| 36 | * dcache. Most filesystems leave this as NULL, because all their | ||
| 37 | * dentries in the dcache are valid. | ||
| 38 | * | ||
| 39 | * Returns 1 if valid, 0 otherwise. | ||
| 40 | * | ||
| 41 | */ | ||
| 42 | static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) | ||
| 43 | { | ||
| 44 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 45 | struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); | ||
| 46 | struct dentry *dentry_save; | ||
| 47 | struct vfsmount *vfsmount_save; | ||
| 48 | int rc = 1; | ||
| 49 | |||
| 50 | if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate) | ||
| 51 | goto out; | ||
| 52 | dentry_save = nd->dentry; | ||
| 53 | vfsmount_save = nd->mnt; | ||
| 54 | nd->dentry = lower_dentry; | ||
| 55 | nd->mnt = lower_mnt; | ||
| 56 | rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd); | ||
| 57 | nd->dentry = dentry_save; | ||
| 58 | nd->mnt = vfsmount_save; | ||
| 59 | out: | ||
| 60 | return rc; | ||
| 61 | } | ||
| 62 | |||
| 63 | struct kmem_cache *ecryptfs_dentry_info_cache; | ||
| 64 | |||
| 65 | /** | ||
| 66 | * ecryptfs_d_release | ||
| 67 | * @dentry: The ecryptfs dentry | ||
| 68 | * | ||
| 69 | * Called when a dentry is really deallocated. | ||
| 70 | */ | ||
| 71 | static void ecryptfs_d_release(struct dentry *dentry) | ||
| 72 | { | ||
| 73 | struct dentry *lower_dentry; | ||
| 74 | |||
| 75 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 76 | if (ecryptfs_dentry_to_private(dentry)) | ||
| 77 | kmem_cache_free(ecryptfs_dentry_info_cache, | ||
| 78 | ecryptfs_dentry_to_private(dentry)); | ||
| 79 | if (lower_dentry) | ||
| 80 | dput(lower_dentry); | ||
| 81 | return; | ||
| 82 | } | ||
| 83 | |||
| 84 | struct dentry_operations ecryptfs_dops = { | ||
| 85 | .d_revalidate = ecryptfs_d_revalidate, | ||
| 86 | .d_release = ecryptfs_d_release, | ||
| 87 | }; | ||
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h new file mode 100644 index 000000000000..872c9958531a --- /dev/null +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
| @@ -0,0 +1,482 @@ | |||
| 1 | /** | ||
| 2 | * eCryptfs: Linux filesystem encryption layer | ||
| 3 | * Kernel declarations. | ||
| 4 | * | ||
| 5 | * Copyright (C) 1997-2003 Erez Zadok | ||
| 6 | * Copyright (C) 2001-2003 Stony Brook University | ||
| 7 | * Copyright (C) 2004-2006 International Business Machines Corp. | ||
| 8 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or | ||
| 11 | * modify it under the terms of the GNU General Public License as | ||
| 12 | * published by the Free Software Foundation; either version 2 of the | ||
| 13 | * License, or (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, but | ||
| 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 18 | * General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
| 23 | * 02111-1307, USA. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #ifndef ECRYPTFS_KERNEL_H | ||
| 27 | #define ECRYPTFS_KERNEL_H | ||
| 28 | |||
| 29 | #include <keys/user-type.h> | ||
| 30 | #include <linux/fs.h> | ||
| 31 | #include <linux/scatterlist.h> | ||
| 32 | |||
| 33 | /* Version verification for shared data structures w/ userspace */ | ||
| 34 | #define ECRYPTFS_VERSION_MAJOR 0x00 | ||
| 35 | #define ECRYPTFS_VERSION_MINOR 0x04 | ||
| 36 | #define ECRYPTFS_SUPPORTED_FILE_VERSION 0x01 | ||
| 37 | /* These flags indicate which features are supported by the kernel | ||
| 38 | * module; userspace tools such as the mount helper read | ||
| 39 | * ECRYPTFS_VERSIONING_MASK from a sysfs handle in order to determine | ||
| 40 | * how to behave. */ | ||
| 41 | #define ECRYPTFS_VERSIONING_PASSPHRASE 0x00000001 | ||
| 42 | #define ECRYPTFS_VERSIONING_PUBKEY 0x00000002 | ||
| 43 | #define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004 | ||
| 44 | #define ECRYPTFS_VERSIONING_POLICY 0x00000008 | ||
| 45 | #define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \ | ||
| 46 | | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH) | ||
| 47 | |||
| 48 | #define ECRYPTFS_MAX_PASSWORD_LENGTH 64 | ||
| 49 | #define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH | ||
| 50 | #define ECRYPTFS_SALT_SIZE 8 | ||
| 51 | #define ECRYPTFS_SALT_SIZE_HEX (ECRYPTFS_SALT_SIZE*2) | ||
| 52 | /* The original signature size is only for what is stored on disk; all | ||
| 53 | * in-memory representations are expanded hex, so it better adapted to | ||
| 54 | * be passed around or referenced on the command line */ | ||
| 55 | #define ECRYPTFS_SIG_SIZE 8 | ||
| 56 | #define ECRYPTFS_SIG_SIZE_HEX (ECRYPTFS_SIG_SIZE*2) | ||
| 57 | #define ECRYPTFS_PASSWORD_SIG_SIZE ECRYPTFS_SIG_SIZE_HEX | ||
| 58 | #define ECRYPTFS_MAX_KEY_BYTES 64 | ||
| 59 | #define ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES 512 | ||
| 60 | #define ECRYPTFS_DEFAULT_IV_BYTES 16 | ||
| 61 | #define ECRYPTFS_FILE_VERSION 0x01 | ||
| 62 | #define ECRYPTFS_DEFAULT_HEADER_EXTENT_SIZE 8192 | ||
| 63 | #define ECRYPTFS_DEFAULT_EXTENT_SIZE 4096 | ||
| 64 | #define ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE 8192 | ||
| 65 | |||
| 66 | #define RFC2440_CIPHER_DES3_EDE 0x02 | ||
| 67 | #define RFC2440_CIPHER_CAST_5 0x03 | ||
| 68 | #define RFC2440_CIPHER_BLOWFISH 0x04 | ||
| 69 | #define RFC2440_CIPHER_AES_128 0x07 | ||
| 70 | #define RFC2440_CIPHER_AES_192 0x08 | ||
| 71 | #define RFC2440_CIPHER_AES_256 0x09 | ||
| 72 | #define RFC2440_CIPHER_TWOFISH 0x0a | ||
| 73 | #define RFC2440_CIPHER_CAST_6 0x0b | ||
| 74 | |||
| 75 | #define ECRYPTFS_SET_FLAG(flag_bit_vector, flag) (flag_bit_vector |= (flag)) | ||
| 76 | #define ECRYPTFS_CLEAR_FLAG(flag_bit_vector, flag) (flag_bit_vector &= ~(flag)) | ||
| 77 | #define ECRYPTFS_CHECK_FLAG(flag_bit_vector, flag) (flag_bit_vector & (flag)) | ||
| 78 | |||
| 79 | /** | ||
| 80 | * For convenience, we may need to pass around the encrypted session | ||
| 81 | * key between kernel and userspace because the authentication token | ||
| 82 | * may not be extractable. For example, the TPM may not release the | ||
| 83 | * private key, instead requiring the encrypted data and returning the | ||
| 84 | * decrypted data. | ||
| 85 | */ | ||
| 86 | struct ecryptfs_session_key { | ||
| 87 | #define ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT 0x00000001 | ||
| 88 | #define ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT 0x00000002 | ||
| 89 | #define ECRYPTFS_CONTAINS_DECRYPTED_KEY 0x00000004 | ||
| 90 | #define ECRYPTFS_CONTAINS_ENCRYPTED_KEY 0x00000008 | ||
| 91 | u32 flags; | ||
| 92 | u32 encrypted_key_size; | ||
| 93 | u32 decrypted_key_size; | ||
| 94 | u8 encrypted_key[ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES]; | ||
| 95 | u8 decrypted_key[ECRYPTFS_MAX_KEY_BYTES]; | ||
| 96 | }; | ||
| 97 | |||
| 98 | struct ecryptfs_password { | ||
| 99 | u32 password_bytes; | ||
| 100 | s32 hash_algo; | ||
| 101 | u32 hash_iterations; | ||
| 102 | u32 session_key_encryption_key_bytes; | ||
| 103 | #define ECRYPTFS_PERSISTENT_PASSWORD 0x01 | ||
| 104 | #define ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET 0x02 | ||
| 105 | u32 flags; | ||
| 106 | /* Iterated-hash concatenation of salt and passphrase */ | ||
| 107 | u8 session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; | ||
| 108 | u8 signature[ECRYPTFS_PASSWORD_SIG_SIZE + 1]; | ||
| 109 | /* Always in expanded hex */ | ||
| 110 | u8 salt[ECRYPTFS_SALT_SIZE]; | ||
| 111 | }; | ||
| 112 | |||
| 113 | enum ecryptfs_token_types {ECRYPTFS_PASSWORD, ECRYPTFS_PRIVATE_KEY}; | ||
| 114 | |||
| 115 | /* May be a password or a private key */ | ||
| 116 | struct ecryptfs_auth_tok { | ||
| 117 | u16 version; /* 8-bit major and 8-bit minor */ | ||
| 118 | u16 token_type; | ||
| 119 | u32 flags; | ||
| 120 | struct ecryptfs_session_key session_key; | ||
| 121 | u8 reserved[32]; | ||
| 122 | union { | ||
| 123 | struct ecryptfs_password password; | ||
| 124 | /* Private key is in future eCryptfs releases */ | ||
| 125 | } token; | ||
| 126 | } __attribute__ ((packed)); | ||
| 127 | |||
| 128 | void ecryptfs_dump_auth_tok(struct ecryptfs_auth_tok *auth_tok); | ||
| 129 | extern void ecryptfs_to_hex(char *dst, char *src, size_t src_size); | ||
| 130 | extern void ecryptfs_from_hex(char *dst, char *src, int dst_size); | ||
| 131 | |||
| 132 | struct ecryptfs_key_record { | ||
| 133 | unsigned char type; | ||
| 134 | size_t enc_key_size; | ||
| 135 | unsigned char sig[ECRYPTFS_SIG_SIZE]; | ||
| 136 | unsigned char enc_key[ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES]; | ||
| 137 | }; | ||
| 138 | |||
| 139 | struct ecryptfs_auth_tok_list { | ||
| 140 | struct ecryptfs_auth_tok *auth_tok; | ||
| 141 | struct list_head list; | ||
| 142 | }; | ||
| 143 | |||
| 144 | struct ecryptfs_crypt_stat; | ||
| 145 | struct ecryptfs_mount_crypt_stat; | ||
| 146 | |||
| 147 | struct ecryptfs_page_crypt_context { | ||
| 148 | struct page *page; | ||
| 149 | #define ECRYPTFS_PREPARE_COMMIT_MODE 0 | ||
| 150 | #define ECRYPTFS_WRITEPAGE_MODE 1 | ||
| 151 | unsigned int mode; | ||
| 152 | union { | ||
| 153 | struct file *lower_file; | ||
| 154 | struct writeback_control *wbc; | ||
| 155 | } param; | ||
| 156 | }; | ||
| 157 | |||
| 158 | static inline struct ecryptfs_auth_tok * | ||
| 159 | ecryptfs_get_key_payload_data(struct key *key) | ||
| 160 | { | ||
| 161 | return (struct ecryptfs_auth_tok *) | ||
| 162 | (((struct user_key_payload*)key->payload.data)->data); | ||
| 163 | } | ||
| 164 | |||
| 165 | #define ECRYPTFS_SUPER_MAGIC 0xf15f | ||
| 166 | #define ECRYPTFS_MAX_KEYSET_SIZE 1024 | ||
| 167 | #define ECRYPTFS_MAX_CIPHER_NAME_SIZE 32 | ||
| 168 | #define ECRYPTFS_MAX_NUM_ENC_KEYS 64 | ||
| 169 | #define ECRYPTFS_MAX_NUM_KEYSIGS 2 /* TODO: Make this a linked list */ | ||
| 170 | #define ECRYPTFS_MAX_IV_BYTES 16 /* 128 bits */ | ||
| 171 | #define ECRYPTFS_SALT_BYTES 2 | ||
| 172 | #define MAGIC_ECRYPTFS_MARKER 0x3c81b7f5 | ||
| 173 | #define MAGIC_ECRYPTFS_MARKER_SIZE_BYTES 8 /* 4*2 */ | ||
| 174 | #define ECRYPTFS_FILE_SIZE_BYTES 8 | ||
| 175 | #define ECRYPTFS_DEFAULT_CIPHER "aes" | ||
| 176 | #define ECRYPTFS_DEFAULT_KEY_BYTES 16 | ||
| 177 | #define ECRYPTFS_DEFAULT_CHAINING_MODE CRYPTO_TFM_MODE_CBC | ||
| 178 | #define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C | ||
| 179 | #define ECRYPTFS_TAG_11_PACKET_TYPE 0xED | ||
| 180 | #define MD5_DIGEST_SIZE 16 | ||
| 181 | |||
| 182 | /** | ||
| 183 | * This is the primary struct associated with each encrypted file. | ||
| 184 | * | ||
| 185 | * TODO: cache align/pack? | ||
| 186 | */ | ||
| 187 | struct ecryptfs_crypt_stat { | ||
| 188 | #define ECRYPTFS_STRUCT_INITIALIZED 0x00000001 | ||
| 189 | #define ECRYPTFS_POLICY_APPLIED 0x00000002 | ||
| 190 | #define ECRYPTFS_NEW_FILE 0x00000004 | ||
| 191 | #define ECRYPTFS_ENCRYPTED 0x00000008 | ||
| 192 | #define ECRYPTFS_SECURITY_WARNING 0x00000010 | ||
| 193 | #define ECRYPTFS_ENABLE_HMAC 0x00000020 | ||
| 194 | #define ECRYPTFS_ENCRYPT_IV_PAGES 0x00000040 | ||
| 195 | #define ECRYPTFS_KEY_VALID 0x00000080 | ||
| 196 | u32 flags; | ||
| 197 | unsigned int file_version; | ||
| 198 | size_t iv_bytes; | ||
| 199 | size_t num_keysigs; | ||
| 200 | size_t header_extent_size; | ||
| 201 | size_t num_header_extents_at_front; | ||
| 202 | size_t extent_size; /* Data extent size; default is 4096 */ | ||
| 203 | size_t key_size; | ||
| 204 | size_t extent_shift; | ||
| 205 | unsigned int extent_mask; | ||
| 206 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | ||
| 207 | struct crypto_tfm *tfm; | ||
| 208 | struct crypto_tfm *md5_tfm; /* Crypto context for generating | ||
| 209 | * the initialization vectors */ | ||
| 210 | unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE]; | ||
| 211 | unsigned char key[ECRYPTFS_MAX_KEY_BYTES]; | ||
| 212 | unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES]; | ||
| 213 | unsigned char keysigs[ECRYPTFS_MAX_NUM_KEYSIGS][ECRYPTFS_SIG_SIZE_HEX]; | ||
| 214 | struct mutex cs_tfm_mutex; | ||
| 215 | struct mutex cs_md5_tfm_mutex; | ||
| 216 | struct mutex cs_mutex; | ||
| 217 | }; | ||
| 218 | |||
| 219 | /* inode private data. */ | ||
| 220 | struct ecryptfs_inode_info { | ||
| 221 | struct inode vfs_inode; | ||
| 222 | struct inode *wii_inode; | ||
| 223 | struct ecryptfs_crypt_stat crypt_stat; | ||
| 224 | }; | ||
| 225 | |||
| 226 | /* dentry private data. Each dentry must keep track of a lower | ||
| 227 | * vfsmount too. */ | ||
| 228 | struct ecryptfs_dentry_info { | ||
| 229 | struct dentry *wdi_dentry; | ||
| 230 | struct vfsmount *lower_mnt; | ||
| 231 | struct ecryptfs_crypt_stat *crypt_stat; | ||
| 232 | }; | ||
| 233 | |||
| 234 | /** | ||
| 235 | * This struct is to enable a mount-wide passphrase/salt combo. This | ||
| 236 | * is more or less a stopgap to provide similar functionality to other | ||
| 237 | * crypto filesystems like EncFS or CFS until full policy support is | ||
| 238 | * implemented in eCryptfs. | ||
| 239 | */ | ||
| 240 | struct ecryptfs_mount_crypt_stat { | ||
| 241 | /* Pointers to memory we do not own, do not free these */ | ||
| 242 | #define ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED 0x00000001 | ||
| 243 | u32 flags; | ||
| 244 | struct ecryptfs_auth_tok *global_auth_tok; | ||
| 245 | struct key *global_auth_tok_key; | ||
| 246 | size_t global_default_cipher_key_size; | ||
| 247 | struct crypto_tfm *global_key_tfm; | ||
| 248 | struct mutex global_key_tfm_mutex; | ||
| 249 | unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE | ||
| 250 | + 1]; | ||
| 251 | unsigned char global_auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX + 1]; | ||
| 252 | }; | ||
| 253 | |||
| 254 | /* superblock private data. */ | ||
| 255 | struct ecryptfs_sb_info { | ||
| 256 | struct super_block *wsi_sb; | ||
| 257 | struct ecryptfs_mount_crypt_stat mount_crypt_stat; | ||
| 258 | }; | ||
| 259 | |||
| 260 | /* file private data. */ | ||
| 261 | struct ecryptfs_file_info { | ||
| 262 | struct file *wfi_file; | ||
| 263 | struct ecryptfs_crypt_stat *crypt_stat; | ||
| 264 | }; | ||
| 265 | |||
| 266 | /* auth_tok <=> encrypted_session_key mappings */ | ||
| 267 | struct ecryptfs_auth_tok_list_item { | ||
| 268 | unsigned char encrypted_session_key[ECRYPTFS_MAX_KEY_BYTES]; | ||
| 269 | struct list_head list; | ||
| 270 | struct ecryptfs_auth_tok auth_tok; | ||
| 271 | }; | ||
| 272 | |||
| 273 | static inline struct ecryptfs_file_info * | ||
| 274 | ecryptfs_file_to_private(struct file *file) | ||
| 275 | { | ||
| 276 | return (struct ecryptfs_file_info *)file->private_data; | ||
| 277 | } | ||
| 278 | |||
| 279 | static inline void | ||
| 280 | ecryptfs_set_file_private(struct file *file, | ||
| 281 | struct ecryptfs_file_info *file_info) | ||
| 282 | { | ||
| 283 | file->private_data = file_info; | ||
| 284 | } | ||
| 285 | |||
| 286 | static inline struct file *ecryptfs_file_to_lower(struct file *file) | ||
| 287 | { | ||
| 288 | return ((struct ecryptfs_file_info *)file->private_data)->wfi_file; | ||
| 289 | } | ||
| 290 | |||
| 291 | static inline void | ||
| 292 | ecryptfs_set_file_lower(struct file *file, struct file *lower_file) | ||
| 293 | { | ||
| 294 | ((struct ecryptfs_file_info *)file->private_data)->wfi_file = | ||
| 295 | lower_file; | ||
| 296 | } | ||
| 297 | |||
| 298 | static inline struct ecryptfs_inode_info * | ||
| 299 | ecryptfs_inode_to_private(struct inode *inode) | ||
| 300 | { | ||
| 301 | return container_of(inode, struct ecryptfs_inode_info, vfs_inode); | ||
| 302 | } | ||
| 303 | |||
| 304 | static inline struct inode *ecryptfs_inode_to_lower(struct inode *inode) | ||
| 305 | { | ||
| 306 | return ecryptfs_inode_to_private(inode)->wii_inode; | ||
| 307 | } | ||
| 308 | |||
| 309 | static inline void | ||
| 310 | ecryptfs_set_inode_lower(struct inode *inode, struct inode *lower_inode) | ||
| 311 | { | ||
| 312 | ecryptfs_inode_to_private(inode)->wii_inode = lower_inode; | ||
| 313 | } | ||
| 314 | |||
| 315 | static inline struct ecryptfs_sb_info * | ||
| 316 | ecryptfs_superblock_to_private(struct super_block *sb) | ||
| 317 | { | ||
| 318 | return (struct ecryptfs_sb_info *)sb->s_fs_info; | ||
| 319 | } | ||
| 320 | |||
| 321 | static inline void | ||
| 322 | ecryptfs_set_superblock_private(struct super_block *sb, | ||
| 323 | struct ecryptfs_sb_info *sb_info) | ||
| 324 | { | ||
| 325 | sb->s_fs_info = sb_info; | ||
| 326 | } | ||
| 327 | |||
| 328 | static inline struct super_block * | ||
| 329 | ecryptfs_superblock_to_lower(struct super_block *sb) | ||
| 330 | { | ||
| 331 | return ((struct ecryptfs_sb_info *)sb->s_fs_info)->wsi_sb; | ||
| 332 | } | ||
| 333 | |||
| 334 | static inline void | ||
| 335 | ecryptfs_set_superblock_lower(struct super_block *sb, | ||
| 336 | struct super_block *lower_sb) | ||
| 337 | { | ||
| 338 | ((struct ecryptfs_sb_info *)sb->s_fs_info)->wsi_sb = lower_sb; | ||
| 339 | } | ||
| 340 | |||
| 341 | static inline struct ecryptfs_dentry_info * | ||
| 342 | ecryptfs_dentry_to_private(struct dentry *dentry) | ||
| 343 | { | ||
| 344 | return (struct ecryptfs_dentry_info *)dentry->d_fsdata; | ||
| 345 | } | ||
| 346 | |||
| 347 | static inline void | ||
| 348 | ecryptfs_set_dentry_private(struct dentry *dentry, | ||
| 349 | struct ecryptfs_dentry_info *dentry_info) | ||
| 350 | { | ||
| 351 | dentry->d_fsdata = dentry_info; | ||
| 352 | } | ||
| 353 | |||
| 354 | static inline struct dentry * | ||
| 355 | ecryptfs_dentry_to_lower(struct dentry *dentry) | ||
| 356 | { | ||
| 357 | return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->wdi_dentry; | ||
| 358 | } | ||
| 359 | |||
| 360 | static inline void | ||
| 361 | ecryptfs_set_dentry_lower(struct dentry *dentry, struct dentry *lower_dentry) | ||
| 362 | { | ||
| 363 | ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->wdi_dentry = | ||
| 364 | lower_dentry; | ||
| 365 | } | ||
| 366 | |||
| 367 | static inline struct vfsmount * | ||
| 368 | ecryptfs_dentry_to_lower_mnt(struct dentry *dentry) | ||
| 369 | { | ||
| 370 | return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_mnt; | ||
| 371 | } | ||
| 372 | |||
| 373 | static inline void | ||
| 374 | ecryptfs_set_dentry_lower_mnt(struct dentry *dentry, struct vfsmount *lower_mnt) | ||
| 375 | { | ||
| 376 | ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_mnt = | ||
| 377 | lower_mnt; | ||
| 378 | } | ||
| 379 | |||
| 380 | #define ecryptfs_printk(type, fmt, arg...) \ | ||
| 381 | __ecryptfs_printk(type "%s: " fmt, __FUNCTION__, ## arg); | ||
| 382 | void __ecryptfs_printk(const char *fmt, ...); | ||
| 383 | |||
| 384 | extern const struct file_operations ecryptfs_main_fops; | ||
| 385 | extern const struct file_operations ecryptfs_dir_fops; | ||
| 386 | extern struct inode_operations ecryptfs_main_iops; | ||
| 387 | extern struct inode_operations ecryptfs_dir_iops; | ||
| 388 | extern struct inode_operations ecryptfs_symlink_iops; | ||
| 389 | extern struct super_operations ecryptfs_sops; | ||
| 390 | extern struct dentry_operations ecryptfs_dops; | ||
| 391 | extern struct address_space_operations ecryptfs_aops; | ||
| 392 | extern int ecryptfs_verbosity; | ||
| 393 | |||
| 394 | extern struct kmem_cache *ecryptfs_auth_tok_list_item_cache; | ||
| 395 | extern struct kmem_cache *ecryptfs_file_info_cache; | ||
| 396 | extern struct kmem_cache *ecryptfs_dentry_info_cache; | ||
| 397 | extern struct kmem_cache *ecryptfs_inode_info_cache; | ||
| 398 | extern struct kmem_cache *ecryptfs_sb_info_cache; | ||
| 399 | extern struct kmem_cache *ecryptfs_header_cache_0; | ||
| 400 | extern struct kmem_cache *ecryptfs_header_cache_1; | ||
| 401 | extern struct kmem_cache *ecryptfs_header_cache_2; | ||
| 402 | extern struct kmem_cache *ecryptfs_lower_page_cache; | ||
| 403 | |||
| 404 | int ecryptfs_interpose(struct dentry *hidden_dentry, | ||
| 405 | struct dentry *this_dentry, struct super_block *sb, | ||
| 406 | int flag); | ||
| 407 | int ecryptfs_fill_zeros(struct file *file, loff_t new_length); | ||
| 408 | int ecryptfs_decode_filename(struct ecryptfs_crypt_stat *crypt_stat, | ||
| 409 | const char *name, int length, | ||
| 410 | char **decrypted_name); | ||
| 411 | int ecryptfs_encode_filename(struct ecryptfs_crypt_stat *crypt_stat, | ||
| 412 | const char *name, int length, | ||
| 413 | char **encoded_name); | ||
| 414 | struct dentry *ecryptfs_lower_dentry(struct dentry *this_dentry); | ||
| 415 | void ecryptfs_copy_attr_atime(struct inode *dest, const struct inode *src); | ||
| 416 | void ecryptfs_copy_attr_all(struct inode *dest, const struct inode *src); | ||
| 417 | void ecryptfs_copy_inode_size(struct inode *dst, const struct inode *src); | ||
| 418 | void ecryptfs_dump_hex(char *data, int bytes); | ||
| 419 | int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg, | ||
| 420 | int sg_size); | ||
| 421 | int ecryptfs_compute_root_iv(struct ecryptfs_crypt_stat *crypt_stat); | ||
| 422 | void ecryptfs_rotate_iv(unsigned char *iv); | ||
| 423 | void ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat); | ||
| 424 | void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat); | ||
| 425 | void ecryptfs_destruct_mount_crypt_stat( | ||
| 426 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat); | ||
| 427 | int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat); | ||
| 428 | int ecryptfs_write_inode_size_to_header(struct file *lower_file, | ||
| 429 | struct inode *lower_inode, | ||
| 430 | struct inode *inode); | ||
| 431 | int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode, | ||
| 432 | struct file *lower_file, | ||
| 433 | unsigned long lower_page_index, int byte_offset, | ||
| 434 | int region_bytes); | ||
| 435 | int | ||
| 436 | ecryptfs_commit_lower_page(struct page *lower_page, struct inode *lower_inode, | ||
| 437 | struct file *lower_file, int byte_offset, | ||
| 438 | int region_size); | ||
| 439 | int ecryptfs_copy_page_to_lower(struct page *page, struct inode *lower_inode, | ||
| 440 | struct file *lower_file); | ||
| 441 | int ecryptfs_do_readpage(struct file *file, struct page *page, | ||
| 442 | pgoff_t lower_page_index); | ||
| 443 | int ecryptfs_grab_and_map_lower_page(struct page **lower_page, | ||
| 444 | char **lower_virt, | ||
| 445 | struct inode *lower_inode, | ||
| 446 | unsigned long lower_page_index); | ||
| 447 | int ecryptfs_writepage_and_release_lower_page(struct page *lower_page, | ||
| 448 | struct inode *lower_inode, | ||
| 449 | struct writeback_control *wbc); | ||
| 450 | int ecryptfs_encrypt_page(struct ecryptfs_page_crypt_context *ctx); | ||
| 451 | int ecryptfs_decrypt_page(struct file *file, struct page *page); | ||
| 452 | int ecryptfs_write_headers(struct dentry *ecryptfs_dentry, | ||
| 453 | struct file *lower_file); | ||
| 454 | int ecryptfs_write_headers_virt(char *page_virt, | ||
| 455 | struct ecryptfs_crypt_stat *crypt_stat, | ||
| 456 | struct dentry *ecryptfs_dentry); | ||
| 457 | int ecryptfs_read_headers(struct dentry *ecryptfs_dentry, | ||
| 458 | struct file *lower_file); | ||
| 459 | int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry); | ||
| 460 | int contains_ecryptfs_marker(char *data); | ||
| 461 | int ecryptfs_read_header_region(char *data, struct dentry *dentry, | ||
| 462 | struct vfsmount *mnt); | ||
| 463 | u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat); | ||
| 464 | int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code); | ||
| 465 | void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat); | ||
| 466 | int ecryptfs_generate_key_packet_set(char *dest_base, | ||
| 467 | struct ecryptfs_crypt_stat *crypt_stat, | ||
| 468 | struct dentry *ecryptfs_dentry, | ||
| 469 | size_t *len, size_t max); | ||
| 470 | int process_request_key_err(long err_code); | ||
| 471 | int | ||
| 472 | ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | ||
| 473 | unsigned char *src, struct dentry *ecryptfs_dentry); | ||
| 474 | int ecryptfs_truncate(struct dentry *dentry, loff_t new_length); | ||
| 475 | int | ||
| 476 | ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm, | ||
| 477 | char *cipher_name, size_t key_size); | ||
| 478 | int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode); | ||
| 479 | int ecryptfs_inode_set(struct inode *inode, void *lower_inode); | ||
| 480 | void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode); | ||
| 481 | |||
| 482 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ | ||
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c new file mode 100644 index 000000000000..c8550c9f9cd2 --- /dev/null +++ b/fs/ecryptfs/file.c | |||
| @@ -0,0 +1,440 @@ | |||
| 1 | /** | ||
| 2 | * eCryptfs: Linux filesystem encryption layer | ||
| 3 | * | ||
| 4 | * Copyright (C) 1997-2004 Erez Zadok | ||
| 5 | * Copyright (C) 2001-2004 Stony Brook University | ||
| 6 | * Copyright (C) 2004-2006 International Business Machines Corp. | ||
| 7 | * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> | ||
| 8 | * Michael C. Thompson <mcthomps@us.ibm.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or | ||
| 11 | * modify it under the terms of the GNU General Public License as | ||
| 12 | * published by the Free Software Foundation; either version 2 of the | ||
| 13 | * License, or (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, but | ||
| 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 18 | * General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
| 23 | * 02111-1307, USA. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <linux/file.h> | ||
| 27 | #include <linux/poll.h> | ||
| 28 | #include <linux/mount.h> | ||
| 29 | #include <linux/pagemap.h> | ||
| 30 | #include <linux/security.h> | ||
| 31 | #include <linux/smp_lock.h> | ||
| 32 | #include <linux/compat.h> | ||
| 33 | #include "ecryptfs_kernel.h" | ||
| 34 | |||
| 35 | /** | ||
| 36 | * ecryptfs_llseek | ||
| 37 | * @file: File we are seeking in | ||
| 38 | * @offset: The offset to seek to | ||
| 39 | * @origin: 2 - offset from i_size; 1 - offset from f_pos | ||
| 40 | * | ||
| 41 | * Returns the position we have seeked to, or negative on error | ||
| 42 | */ | ||
| 43 | static loff_t ecryptfs_llseek(struct file *file, loff_t offset, int origin) | ||
| 44 | { | ||
| 45 | loff_t rv; | ||
| 46 | loff_t new_end_pos; | ||
| 47 | int rc; | ||
| 48 | int expanding_file = 0; | ||
| 49 | struct inode *inode = file->f_mapping->host; | ||
| 50 | |||
| 51 | /* If our offset is past the end of our file, we're going to | ||
| 52 | * need to grow it so we have a valid length of 0's */ | ||
| 53 | new_end_pos = offset; | ||
| 54 | switch (origin) { | ||
| 55 | case 2: | ||
| 56 | new_end_pos += i_size_read(inode); | ||
| 57 | expanding_file = 1; | ||
| 58 | break; | ||
| 59 | case 1: | ||
| 60 | new_end_pos += file->f_pos; | ||
| 61 | if (new_end_pos > i_size_read(inode)) { | ||
| 62 | ecryptfs_printk(KERN_DEBUG, "new_end_pos(=[0x%.16x]) " | ||
| 63 | "> i_size_read(inode)(=[0x%.16x])\n", | ||
| 64 | new_end_pos, i_size_read(inode)); | ||
| 65 | expanding_file = 1; | ||
| 66 | } | ||
| 67 | break; | ||
| 68 | default: | ||
| 69 | if (new_end_pos > i_size_read(inode)) { | ||
| 70 | ecryptfs_printk(KERN_DEBUG, "new_end_pos(=[0x%.16x]) " | ||
| 71 | "> i_size_read(inode)(=[0x%.16x])\n", | ||
| 72 | new_end_pos, i_size_read(inode)); | ||
| 73 | expanding_file = 1; | ||
| 74 | } | ||
| 75 | } | ||
| 76 | ecryptfs_printk(KERN_DEBUG, "new_end_pos = [0x%.16x]\n", new_end_pos); | ||
| 77 | if (expanding_file) { | ||
| 78 | rc = ecryptfs_truncate(file->f_dentry, new_end_pos); | ||
| 79 | if (rc) { | ||
| 80 | rv = rc; | ||
| 81 | ecryptfs_printk(KERN_ERR, "Error on attempt to " | ||
| 82 | "truncate to (higher) offset [0x%.16x];" | ||
| 83 | " rc = [%d]\n", new_end_pos, rc); | ||
| 84 | goto out; | ||
| 85 | } | ||
| 86 | } | ||
| 87 | rv = generic_file_llseek(file, offset, origin); | ||
| 88 | out: | ||
| 89 | return rv; | ||
| 90 | } | ||
| 91 | |||
| 92 | /** | ||
| 93 | * ecryptfs_read_update_atime | ||
| 94 | * | ||
| 95 | * generic_file_read updates the atime of upper layer inode. But, it | ||
| 96 | * doesn't give us a chance to update the atime of the lower layer | ||
| 97 | * inode. This function is a wrapper to generic_file_read. It | ||
| 98 | * updates the atime of the lower level inode if generic_file_read | ||
| 99 | * returns without any errors. This is to be used only for file reads. | ||
| 100 | * The function to be used for directory reads is ecryptfs_read. | ||
| 101 | */ | ||
| 102 | static ssize_t ecryptfs_read_update_atime(struct kiocb *iocb, | ||
| 103 | const struct iovec *iov, | ||
| 104 | unsigned long nr_segs, loff_t pos) | ||
| 105 | { | ||
| 106 | int rc; | ||
| 107 | struct dentry *lower_dentry; | ||
| 108 | struct vfsmount *lower_vfsmount; | ||
| 109 | struct file *file = iocb->ki_filp; | ||
| 110 | |||
| 111 | rc = generic_file_aio_read(iocb, iov, nr_segs, pos); | ||
| 112 | /* | ||
| 113 | * Even though this is a async interface, we need to wait | ||
| 114 | * for IO to finish to update atime | ||
| 115 | */ | ||
| 116 | if (-EIOCBQUEUED == rc) | ||
| 117 | rc = wait_on_sync_kiocb(iocb); | ||
| 118 | if (rc >= 0) { | ||
| 119 | lower_dentry = ecryptfs_dentry_to_lower(file->f_dentry); | ||
| 120 | lower_vfsmount = ecryptfs_dentry_to_lower_mnt(file->f_dentry); | ||
| 121 | touch_atime(lower_vfsmount, lower_dentry); | ||
| 122 | } | ||
| 123 | return rc; | ||
| 124 | } | ||
| 125 | |||
| 126 | struct ecryptfs_getdents_callback { | ||
| 127 | void *dirent; | ||
| 128 | struct dentry *dentry; | ||
| 129 | filldir_t filldir; | ||
| 130 | int err; | ||
| 131 | int filldir_called; | ||
| 132 | int entries_written; | ||
| 133 | }; | ||
| 134 | |||
| 135 | /* Inspired by generic filldir in fs/readir.c */ | ||
| 136 | static int | ||
| 137 | ecryptfs_filldir(void *dirent, const char *name, int namelen, loff_t offset, | ||
| 138 | u64 ino, unsigned int d_type) | ||
| 139 | { | ||
| 140 | struct ecryptfs_crypt_stat *crypt_stat; | ||
| 141 | struct ecryptfs_getdents_callback *buf = | ||
| 142 | (struct ecryptfs_getdents_callback *)dirent; | ||
| 143 | int rc; | ||
| 144 | int decoded_length; | ||
| 145 | char *decoded_name; | ||
| 146 | |||
| 147 | crypt_stat = ecryptfs_dentry_to_private(buf->dentry)->crypt_stat; | ||
| 148 | buf->filldir_called++; | ||
| 149 | decoded_length = ecryptfs_decode_filename(crypt_stat, name, namelen, | ||
| 150 | &decoded_name); | ||
| 151 | if (decoded_length < 0) { | ||
| 152 | rc = decoded_length; | ||
| 153 | goto out; | ||
| 154 | } | ||
| 155 | rc = buf->filldir(buf->dirent, decoded_name, decoded_length, offset, | ||
| 156 | ino, d_type); | ||
| 157 | kfree(decoded_name); | ||
| 158 | if (rc >= 0) | ||
| 159 | buf->entries_written++; | ||
| 160 | out: | ||
| 161 | return rc; | ||
| 162 | } | ||
| 163 | |||
| 164 | /** | ||
| 165 | * ecryptfs_readdir | ||
| 166 | * @file: The ecryptfs file struct | ||
| 167 | * @dirent: Directory entry | ||
| 168 | * @filldir: The filldir callback function | ||
| 169 | */ | ||
| 170 | static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir) | ||
| 171 | { | ||
| 172 | int rc; | ||
| 173 | struct file *lower_file; | ||
| 174 | struct inode *inode; | ||
| 175 | struct ecryptfs_getdents_callback buf; | ||
| 176 | |||
| 177 | lower_file = ecryptfs_file_to_lower(file); | ||
| 178 | lower_file->f_pos = file->f_pos; | ||
| 179 | inode = file->f_dentry->d_inode; | ||
| 180 | memset(&buf, 0, sizeof(buf)); | ||
| 181 | buf.dirent = dirent; | ||
| 182 | buf.dentry = file->f_dentry; | ||
| 183 | buf.filldir = filldir; | ||
| 184 | retry: | ||
| 185 | buf.filldir_called = 0; | ||
| 186 | buf.entries_written = 0; | ||
| 187 | buf.err = 0; | ||
| 188 | rc = vfs_readdir(lower_file, ecryptfs_filldir, (void *)&buf); | ||
| 189 | if (buf.err) | ||
| 190 | rc = buf.err; | ||
| 191 | if (buf.filldir_called && !buf.entries_written) | ||
| 192 | goto retry; | ||
| 193 | file->f_pos = lower_file->f_pos; | ||
| 194 | if (rc >= 0) | ||
| 195 | ecryptfs_copy_attr_atime(inode, lower_file->f_dentry->d_inode); | ||
| 196 | return rc; | ||
| 197 | } | ||
| 198 | |||
| 199 | struct kmem_cache *ecryptfs_file_info_cache; | ||
| 200 | |||
| 201 | /** | ||
| 202 | * ecryptfs_open | ||
| 203 | * @inode: inode speciying file to open | ||
| 204 | * @file: Structure to return filled in | ||
| 205 | * | ||
| 206 | * Opens the file specified by inode. | ||
| 207 | * | ||
| 208 | * Returns zero on success; non-zero otherwise | ||
| 209 | */ | ||
| 210 | static int ecryptfs_open(struct inode *inode, struct file *file) | ||
| 211 | { | ||
| 212 | int rc = 0; | ||
| 213 | struct ecryptfs_crypt_stat *crypt_stat = NULL; | ||
| 214 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | ||
| 215 | struct dentry *ecryptfs_dentry = file->f_dentry; | ||
| 216 | /* Private value of ecryptfs_dentry allocated in | ||
| 217 | * ecryptfs_lookup() */ | ||
| 218 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | ||
| 219 | struct inode *lower_inode = NULL; | ||
| 220 | struct file *lower_file = NULL; | ||
| 221 | struct vfsmount *lower_mnt; | ||
| 222 | struct ecryptfs_file_info *file_info; | ||
| 223 | int lower_flags; | ||
| 224 | |||
| 225 | /* Released in ecryptfs_release or end of function if failure */ | ||
| 226 | file_info = kmem_cache_alloc(ecryptfs_file_info_cache, SLAB_KERNEL); | ||
| 227 | ecryptfs_set_file_private(file, file_info); | ||
| 228 | if (!file_info) { | ||
| 229 | ecryptfs_printk(KERN_ERR, | ||
| 230 | "Error attempting to allocate memory\n"); | ||
| 231 | rc = -ENOMEM; | ||
| 232 | goto out; | ||
| 233 | } | ||
| 234 | memset(file_info, 0, sizeof(*file_info)); | ||
| 235 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | ||
| 236 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | ||
| 237 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
| 238 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | ||
| 239 | mutex_lock(&crypt_stat->cs_mutex); | ||
| 240 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) { | ||
| 241 | ecryptfs_printk(KERN_DEBUG, "Setting flags for stat...\n"); | ||
| 242 | /* Policy code enabled in future release */ | ||
| 243 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED); | ||
| 244 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); | ||
| 245 | } | ||
| 246 | mutex_unlock(&crypt_stat->cs_mutex); | ||
| 247 | /* This mntget & dget is undone via fput when the file is released */ | ||
| 248 | dget(lower_dentry); | ||
| 249 | lower_flags = file->f_flags; | ||
| 250 | if ((lower_flags & O_ACCMODE) == O_WRONLY) | ||
| 251 | lower_flags = (lower_flags & O_ACCMODE) | O_RDWR; | ||
| 252 | if (file->f_flags & O_APPEND) | ||
| 253 | lower_flags &= ~O_APPEND; | ||
| 254 | lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); | ||
| 255 | mntget(lower_mnt); | ||
| 256 | /* Corresponding fput() in ecryptfs_release() */ | ||
| 257 | lower_file = dentry_open(lower_dentry, lower_mnt, lower_flags); | ||
| 258 | if (IS_ERR(lower_file)) { | ||
| 259 | rc = PTR_ERR(lower_file); | ||
| 260 | ecryptfs_printk(KERN_ERR, "Error opening lower file\n"); | ||
| 261 | goto out_puts; | ||
| 262 | } | ||
| 263 | ecryptfs_set_file_lower(file, lower_file); | ||
| 264 | /* Isn't this check the same as the one in lookup? */ | ||
| 265 | lower_inode = lower_dentry->d_inode; | ||
| 266 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { | ||
| 267 | ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); | ||
| 268 | ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); | ||
| 269 | rc = 0; | ||
| 270 | goto out; | ||
| 271 | } | ||
| 272 | mutex_lock(&crypt_stat->cs_mutex); | ||
| 273 | if (i_size_read(lower_inode) < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) { | ||
| 274 | if (!(mount_crypt_stat->flags | ||
| 275 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { | ||
| 276 | rc = -EIO; | ||
| 277 | printk(KERN_WARNING "Attempt to read file that is " | ||
| 278 | "not in a valid eCryptfs format, and plaintext " | ||
| 279 | "passthrough mode is not enabled; returning " | ||
| 280 | "-EIO\n"); | ||
| 281 | mutex_unlock(&crypt_stat->cs_mutex); | ||
| 282 | goto out_puts; | ||
| 283 | } | ||
| 284 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | ||
| 285 | rc = 0; | ||
| 286 | mutex_unlock(&crypt_stat->cs_mutex); | ||
| 287 | goto out; | ||
| 288 | } else if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, | ||
| 289 | ECRYPTFS_POLICY_APPLIED) | ||
| 290 | || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags, | ||
| 291 | ECRYPTFS_KEY_VALID)) { | ||
| 292 | rc = ecryptfs_read_headers(ecryptfs_dentry, lower_file); | ||
| 293 | if (rc) { | ||
| 294 | ecryptfs_printk(KERN_DEBUG, | ||
| 295 | "Valid headers not found\n"); | ||
| 296 | if (!(mount_crypt_stat->flags | ||
| 297 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { | ||
| 298 | rc = -EIO; | ||
| 299 | printk(KERN_WARNING "Attempt to read file that " | ||
| 300 | "is not in a valid eCryptfs format, " | ||
| 301 | "and plaintext passthrough mode is not " | ||
| 302 | "enabled; returning -EIO\n"); | ||
| 303 | mutex_unlock(&crypt_stat->cs_mutex); | ||
| 304 | goto out_puts; | ||
| 305 | } | ||
| 306 | ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, | ||
| 307 | ECRYPTFS_ENCRYPTED); | ||
| 308 | rc = 0; | ||
| 309 | mutex_unlock(&crypt_stat->cs_mutex); | ||
| 310 | goto out; | ||
| 311 | } | ||
| 312 | } | ||
| 313 | mutex_unlock(&crypt_stat->cs_mutex); | ||
| 314 | ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = [0x%.16x] " | ||
| 315 | "size: [0x%.16x]\n", inode, inode->i_ino, | ||
| 316 | i_size_read(inode)); | ||
| 317 | ecryptfs_set_file_lower(file, lower_file); | ||
| 318 | goto out; | ||
| 319 | out_puts: | ||
| 320 | mntput(lower_mnt); | ||
| 321 | dput(lower_dentry); | ||
| 322 | kmem_cache_free(ecryptfs_file_info_cache, | ||
| 323 | ecryptfs_file_to_private(file)); | ||
| 324 | out: | ||
| 325 | return rc; | ||
| 326 | } | ||
| 327 | |||
| 328 | static int ecryptfs_flush(struct file *file, fl_owner_t td) | ||
| 329 | { | ||
| 330 | int rc = 0; | ||
| 331 | struct file *lower_file = NULL; | ||
| 332 | |||
| 333 | lower_file = ecryptfs_file_to_lower(file); | ||
| 334 | if (lower_file->f_op && lower_file->f_op->flush) | ||
| 335 | rc = lower_file->f_op->flush(lower_file, td); | ||
| 336 | return rc; | ||
| 337 | } | ||
| 338 | |||
| 339 | static int ecryptfs_release(struct inode *inode, struct file *file) | ||
| 340 | { | ||
| 341 | struct file *lower_file = ecryptfs_file_to_lower(file); | ||
| 342 | struct ecryptfs_file_info *file_info = ecryptfs_file_to_private(file); | ||
| 343 | struct inode *lower_inode = ecryptfs_inode_to_lower(inode); | ||
| 344 | |||
| 345 | fput(lower_file); | ||
| 346 | inode->i_blocks = lower_inode->i_blocks; | ||
| 347 | kmem_cache_free(ecryptfs_file_info_cache, file_info); | ||
| 348 | return 0; | ||
| 349 | } | ||
| 350 | |||
| 351 | static int | ||
| 352 | ecryptfs_fsync(struct file *file, struct dentry *dentry, int datasync) | ||
| 353 | { | ||
| 354 | struct file *lower_file = ecryptfs_file_to_lower(file); | ||
| 355 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 356 | struct inode *lower_inode = lower_dentry->d_inode; | ||
| 357 | int rc = -EINVAL; | ||
| 358 | |||
| 359 | if (lower_inode->i_fop->fsync) { | ||
| 360 | mutex_lock(&lower_inode->i_mutex); | ||
| 361 | rc = lower_inode->i_fop->fsync(lower_file, lower_dentry, | ||
| 362 | datasync); | ||
| 363 | mutex_unlock(&lower_inode->i_mutex); | ||
| 364 | } | ||
| 365 | return rc; | ||
| 366 | } | ||
| 367 | |||
| 368 | static int ecryptfs_fasync(int fd, struct file *file, int flag) | ||
| 369 | { | ||
| 370 | int rc = 0; | ||
| 371 | struct file *lower_file = NULL; | ||
| 372 | |||
| 373 | lower_file = ecryptfs_file_to_lower(file); | ||
| 374 | if (lower_file->f_op && lower_file->f_op->fasync) | ||
| 375 | rc = lower_file->f_op->fasync(fd, lower_file, flag); | ||
| 376 | return rc; | ||
| 377 | } | ||
| 378 | |||
| 379 | static ssize_t ecryptfs_sendfile(struct file *file, loff_t * ppos, | ||
| 380 | size_t count, read_actor_t actor, void *target) | ||
| 381 | { | ||
| 382 | struct file *lower_file = NULL; | ||
| 383 | int rc = -EINVAL; | ||
| 384 | |||
| 385 | lower_file = ecryptfs_file_to_lower(file); | ||
| 386 | if (lower_file->f_op && lower_file->f_op->sendfile) | ||
| 387 | rc = lower_file->f_op->sendfile(lower_file, ppos, count, | ||
| 388 | actor, target); | ||
| 389 | |||
| 390 | return rc; | ||
| 391 | } | ||
| 392 | |||
| 393 | static int ecryptfs_ioctl(struct inode *inode, struct file *file, | ||
| 394 | unsigned int cmd, unsigned long arg); | ||
| 395 | |||
| 396 | const struct file_operations ecryptfs_dir_fops = { | ||
| 397 | .readdir = ecryptfs_readdir, | ||
| 398 | .ioctl = ecryptfs_ioctl, | ||
| 399 | .mmap = generic_file_mmap, | ||
| 400 | .open = ecryptfs_open, | ||
| 401 | .flush = ecryptfs_flush, | ||
| 402 | .release = ecryptfs_release, | ||
| 403 | .fsync = ecryptfs_fsync, | ||
| 404 | .fasync = ecryptfs_fasync, | ||
| 405 | .sendfile = ecryptfs_sendfile, | ||
| 406 | }; | ||
| 407 | |||
| 408 | const struct file_operations ecryptfs_main_fops = { | ||
| 409 | .llseek = ecryptfs_llseek, | ||
| 410 | .read = do_sync_read, | ||
| 411 | .aio_read = ecryptfs_read_update_atime, | ||
| 412 | .write = do_sync_write, | ||
| 413 | .aio_write = generic_file_aio_write, | ||
| 414 | .readdir = ecryptfs_readdir, | ||
| 415 | .ioctl = ecryptfs_ioctl, | ||
| 416 | .mmap = generic_file_mmap, | ||
| 417 | .open = ecryptfs_open, | ||
| 418 | .flush = ecryptfs_flush, | ||
| 419 | .release = ecryptfs_release, | ||
| 420 | .fsync = ecryptfs_fsync, | ||
| 421 | .fasync = ecryptfs_fasync, | ||
| 422 | .sendfile = ecryptfs_sendfile, | ||
| 423 | }; | ||
| 424 | |||
| 425 | static int | ||
| 426 | ecryptfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | ||
| 427 | unsigned long arg) | ||
| 428 | { | ||
| 429 | int rc = 0; | ||
| 430 | struct file *lower_file = NULL; | ||
| 431 | |||
| 432 | if (ecryptfs_file_to_private(file)) | ||
| 433 | lower_file = ecryptfs_file_to_lower(file); | ||
| 434 | if (lower_file && lower_file->f_op && lower_file->f_op->ioctl) | ||
| 435 | rc = lower_file->f_op->ioctl(ecryptfs_inode_to_lower(inode), | ||
| 436 | lower_file, cmd, arg); | ||
| 437 | else | ||
| 438 | rc = -ENOTTY; | ||
| 439 | return rc; | ||
| 440 | } | ||
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c new file mode 100644 index 000000000000..efdd2b7b62d7 --- /dev/null +++ b/fs/ecryptfs/inode.c | |||
| @@ -0,0 +1,1079 @@ | |||
| 1 | /** | ||
| 2 | * eCryptfs: Linux filesystem encryption layer | ||
| 3 | * | ||
| 4 | * Copyright (C) 1997-2004 Erez Zadok | ||
| 5 | * Copyright (C) 2001-2004 Stony Brook University | ||
| 6 | * Copyright (C) 2004-2006 International Business Machines Corp. | ||
| 7 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> | ||
| 8 | * Michael C. Thompsion <mcthomps@us.ibm.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or | ||
| 11 | * modify it under the terms of the GNU General Public License as | ||
| 12 | * published by the Free Software Foundation; either version 2 of the | ||
| 13 | * License, or (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, but | ||
| 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 18 | * General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
| 23 | * 02111-1307, USA. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <linux/file.h> | ||
| 27 | #include <linux/vmalloc.h> | ||
| 28 | #include <linux/pagemap.h> | ||
| 29 | #include <linux/dcache.h> | ||
| 30 | #include <linux/namei.h> | ||
| 31 | #include <linux/mount.h> | ||
| 32 | #include <linux/crypto.h> | ||
| 33 | #include "ecryptfs_kernel.h" | ||
| 34 | |||
| 35 | static struct dentry *lock_parent(struct dentry *dentry) | ||
| 36 | { | ||
| 37 | struct dentry *dir; | ||
| 38 | |||
| 39 | dir = dget(dentry->d_parent); | ||
| 40 | mutex_lock(&(dir->d_inode->i_mutex)); | ||
| 41 | return dir; | ||
| 42 | } | ||
| 43 | |||
| 44 | static void unlock_parent(struct dentry *dentry) | ||
| 45 | { | ||
| 46 | mutex_unlock(&(dentry->d_parent->d_inode->i_mutex)); | ||
| 47 | dput(dentry->d_parent); | ||
| 48 | } | ||
| 49 | |||
| 50 | static void unlock_dir(struct dentry *dir) | ||
| 51 | { | ||
| 52 | mutex_unlock(&dir->d_inode->i_mutex); | ||
| 53 | dput(dir); | ||
| 54 | } | ||
| 55 | |||
| 56 | void ecryptfs_copy_inode_size(struct inode *dst, const struct inode *src) | ||
| 57 | { | ||
| 58 | i_size_write(dst, i_size_read((struct inode *)src)); | ||
| 59 | dst->i_blocks = src->i_blocks; | ||
| 60 | } | ||
| 61 | |||
| 62 | void ecryptfs_copy_attr_atime(struct inode *dest, const struct inode *src) | ||
| 63 | { | ||
| 64 | dest->i_atime = src->i_atime; | ||
| 65 | } | ||
| 66 | |||
| 67 | static void ecryptfs_copy_attr_times(struct inode *dest, | ||
| 68 | const struct inode *src) | ||
| 69 | { | ||
| 70 | dest->i_atime = src->i_atime; | ||
| 71 | dest->i_mtime = src->i_mtime; | ||
| 72 | dest->i_ctime = src->i_ctime; | ||
| 73 | } | ||
| 74 | |||
| 75 | static void ecryptfs_copy_attr_timesizes(struct inode *dest, | ||
| 76 | const struct inode *src) | ||
| 77 | { | ||
| 78 | dest->i_atime = src->i_atime; | ||
| 79 | dest->i_mtime = src->i_mtime; | ||
| 80 | dest->i_ctime = src->i_ctime; | ||
| 81 | ecryptfs_copy_inode_size(dest, src); | ||
| 82 | } | ||
| 83 | |||
| 84 | void ecryptfs_copy_attr_all(struct inode *dest, const struct inode *src) | ||
| 85 | { | ||
| 86 | dest->i_mode = src->i_mode; | ||
| 87 | dest->i_nlink = src->i_nlink; | ||
| 88 | dest->i_uid = src->i_uid; | ||
| 89 | dest->i_gid = src->i_gid; | ||
| 90 | dest->i_rdev = src->i_rdev; | ||
| 91 | dest->i_atime = src->i_atime; | ||
| 92 | dest->i_mtime = src->i_mtime; | ||
| 93 | dest->i_ctime = src->i_ctime; | ||
| 94 | dest->i_blkbits = src->i_blkbits; | ||
| 95 | dest->i_flags = src->i_flags; | ||
| 96 | } | ||
| 97 | |||
| 98 | /** | ||
| 99 | * ecryptfs_create_underlying_file | ||
| 100 | * @lower_dir_inode: inode of the parent in the lower fs of the new file | ||
| 101 | * @lower_dentry: New file's dentry in the lower fs | ||
| 102 | * @ecryptfs_dentry: New file's dentry in ecryptfs | ||
| 103 | * @mode: The mode of the new file | ||
| 104 | * @nd: nameidata of ecryptfs' parent's dentry & vfsmount | ||
| 105 | * | ||
| 106 | * Creates the file in the lower file system. | ||
| 107 | * | ||
| 108 | * Returns zero on success; non-zero on error condition | ||
| 109 | */ | ||
| 110 | static int | ||
| 111 | ecryptfs_create_underlying_file(struct inode *lower_dir_inode, | ||
| 112 | struct dentry *dentry, int mode, | ||
| 113 | struct nameidata *nd) | ||
| 114 | { | ||
| 115 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 116 | struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); | ||
| 117 | struct dentry *dentry_save; | ||
| 118 | struct vfsmount *vfsmount_save; | ||
| 119 | int rc; | ||
| 120 | |||
| 121 | dentry_save = nd->dentry; | ||
| 122 | vfsmount_save = nd->mnt; | ||
| 123 | nd->dentry = lower_dentry; | ||
| 124 | nd->mnt = lower_mnt; | ||
| 125 | rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd); | ||
| 126 | nd->dentry = dentry_save; | ||
| 127 | nd->mnt = vfsmount_save; | ||
| 128 | return rc; | ||
| 129 | } | ||
| 130 | |||
| 131 | /** | ||
| 132 | * ecryptfs_do_create | ||
| 133 | * @directory_inode: inode of the new file's dentry's parent in ecryptfs | ||
| 134 | * @ecryptfs_dentry: New file's dentry in ecryptfs | ||
| 135 | * @mode: The mode of the new file | ||
| 136 | * @nd: nameidata of ecryptfs' parent's dentry & vfsmount | ||
| 137 | * | ||
| 138 | * Creates the underlying file and the eCryptfs inode which will link to | ||
| 139 | * it. It will also update the eCryptfs directory inode to mimic the | ||
| 140 | * stat of the lower directory inode. | ||
| 141 | * | ||
| 142 | * Returns zero on success; non-zero on error condition | ||
| 143 | */ | ||
| 144 | static int | ||
| 145 | ecryptfs_do_create(struct inode *directory_inode, | ||
| 146 | struct dentry *ecryptfs_dentry, int mode, | ||
| 147 | struct nameidata *nd) | ||
| 148 | { | ||
| 149 | int rc; | ||
| 150 | struct dentry *lower_dentry; | ||
| 151 | struct dentry *lower_dir_dentry; | ||
| 152 | |||
| 153 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | ||
| 154 | lower_dir_dentry = lock_parent(lower_dentry); | ||
| 155 | if (unlikely(IS_ERR(lower_dir_dentry))) { | ||
| 156 | ecryptfs_printk(KERN_ERR, "Error locking directory of " | ||
| 157 | "dentry\n"); | ||
| 158 | rc = PTR_ERR(lower_dir_dentry); | ||
| 159 | goto out; | ||
| 160 | } | ||
| 161 | rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode, | ||
| 162 | ecryptfs_dentry, mode, nd); | ||
| 163 | if (unlikely(rc)) { | ||
| 164 | ecryptfs_printk(KERN_ERR, | ||
| 165 | "Failure to create underlying file\n"); | ||
| 166 | goto out_lock; | ||
| 167 | } | ||
| 168 | rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry, | ||
| 169 | directory_inode->i_sb, 0); | ||
| 170 | if (rc) { | ||
| 171 | ecryptfs_printk(KERN_ERR, "Failure in ecryptfs_interpose\n"); | ||
| 172 | goto out_lock; | ||
| 173 | } | ||
| 174 | ecryptfs_copy_attr_timesizes(directory_inode, | ||
| 175 | lower_dir_dentry->d_inode); | ||
| 176 | out_lock: | ||
| 177 | unlock_dir(lower_dir_dentry); | ||
| 178 | out: | ||
| 179 | return rc; | ||
| 180 | } | ||
| 181 | |||
| 182 | /** | ||
| 183 | * grow_file | ||
| 184 | * @ecryptfs_dentry: the ecryptfs dentry | ||
| 185 | * @lower_file: The lower file | ||
| 186 | * @inode: The ecryptfs inode | ||
| 187 | * @lower_inode: The lower inode | ||
| 188 | * | ||
| 189 | * This is the code which will grow the file to its correct size. | ||
| 190 | */ | ||
| 191 | static int grow_file(struct dentry *ecryptfs_dentry, struct file *lower_file, | ||
| 192 | struct inode *inode, struct inode *lower_inode) | ||
| 193 | { | ||
| 194 | int rc = 0; | ||
| 195 | struct file fake_file; | ||
| 196 | struct ecryptfs_file_info tmp_file_info; | ||
| 197 | |||
| 198 | memset(&fake_file, 0, sizeof(fake_file)); | ||
| 199 | fake_file.f_dentry = ecryptfs_dentry; | ||
| 200 | memset(&tmp_file_info, 0, sizeof(tmp_file_info)); | ||
| 201 | ecryptfs_set_file_private(&fake_file, &tmp_file_info); | ||
| 202 | ecryptfs_set_file_lower(&fake_file, lower_file); | ||
| 203 | rc = ecryptfs_fill_zeros(&fake_file, 1); | ||
| 204 | if (rc) { | ||
| 205 | ECRYPTFS_SET_FLAG( | ||
| 206 | ecryptfs_inode_to_private(inode)->crypt_stat.flags, | ||
| 207 | ECRYPTFS_SECURITY_WARNING); | ||
| 208 | ecryptfs_printk(KERN_WARNING, "Error attempting to fill zeros " | ||
| 209 | "in file; rc = [%d]\n", rc); | ||
| 210 | goto out; | ||
| 211 | } | ||
| 212 | i_size_write(inode, 0); | ||
| 213 | ecryptfs_write_inode_size_to_header(lower_file, lower_inode, inode); | ||
| 214 | ECRYPTFS_SET_FLAG(ecryptfs_inode_to_private(inode)->crypt_stat.flags, | ||
| 215 | ECRYPTFS_NEW_FILE); | ||
| 216 | out: | ||
| 217 | return rc; | ||
| 218 | } | ||
| 219 | |||
| 220 | /** | ||
| 221 | * ecryptfs_initialize_file | ||
| 222 | * | ||
| 223 | * Cause the file to be changed from a basic empty file to an ecryptfs | ||
| 224 | * file with a header and first data page. | ||
| 225 | * | ||
| 226 | * Returns zero on success | ||
| 227 | */ | ||
| 228 | static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | ||
| 229 | { | ||
| 230 | int rc = 0; | ||
| 231 | int lower_flags; | ||
| 232 | struct ecryptfs_crypt_stat *crypt_stat; | ||
| 233 | struct dentry *lower_dentry; | ||
| 234 | struct dentry *tlower_dentry = NULL; | ||
| 235 | struct file *lower_file; | ||
| 236 | struct inode *inode, *lower_inode; | ||
| 237 | struct vfsmount *lower_mnt; | ||
| 238 | |||
| 239 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | ||
| 240 | ecryptfs_printk(KERN_DEBUG, "lower_dentry->d_name.name = [%s]\n", | ||
| 241 | lower_dentry->d_name.name); | ||
| 242 | inode = ecryptfs_dentry->d_inode; | ||
| 243 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | ||
| 244 | tlower_dentry = dget(lower_dentry); | ||
| 245 | if (!tlower_dentry) { | ||
| 246 | rc = -ENOMEM; | ||
| 247 | ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry\n"); | ||
| 248 | goto out; | ||
| 249 | } | ||
| 250 | lower_flags = ((O_CREAT | O_WRONLY | O_TRUNC) & O_ACCMODE) | O_RDWR; | ||
| 251 | #if BITS_PER_LONG != 32 | ||
| 252 | lower_flags |= O_LARGEFILE; | ||
| 253 | #endif | ||
| 254 | lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); | ||
| 255 | mntget(lower_mnt); | ||
| 256 | /* Corresponding fput() at end of this function */ | ||
| 257 | lower_file = dentry_open(tlower_dentry, lower_mnt, lower_flags); | ||
| 258 | if (IS_ERR(lower_file)) { | ||
| 259 | rc = PTR_ERR(lower_file); | ||
| 260 | ecryptfs_printk(KERN_ERR, | ||
| 261 | "Error opening dentry; rc = [%i]\n", rc); | ||
| 262 | goto out; | ||
| 263 | } | ||
| 264 | /* fput(lower_file) should handle the puts if we do this */ | ||
| 265 | lower_file->f_dentry = tlower_dentry; | ||
| 266 | lower_file->f_vfsmnt = lower_mnt; | ||
| 267 | lower_inode = tlower_dentry->d_inode; | ||
| 268 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { | ||
| 269 | ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); | ||
| 270 | ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); | ||
| 271 | goto out_fput; | ||
| 272 | } | ||
| 273 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE); | ||
| 274 | ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n"); | ||
| 275 | rc = ecryptfs_new_file_context(ecryptfs_dentry); | ||
| 276 | if (rc) { | ||
| 277 | ecryptfs_printk(KERN_DEBUG, "Error creating new file " | ||
| 278 | "context\n"); | ||
| 279 | goto out_fput; | ||
| 280 | } | ||
| 281 | rc = ecryptfs_write_headers(ecryptfs_dentry, lower_file); | ||
| 282 | if (rc) { | ||
| 283 | ecryptfs_printk(KERN_DEBUG, "Error writing headers\n"); | ||
| 284 | goto out_fput; | ||
| 285 | } | ||
| 286 | rc = grow_file(ecryptfs_dentry, lower_file, inode, lower_inode); | ||
| 287 | out_fput: | ||
| 288 | fput(lower_file); | ||
| 289 | out: | ||
| 290 | return rc; | ||
| 291 | } | ||
| 292 | |||
| 293 | /** | ||
| 294 | * ecryptfs_create | ||
| 295 | * @dir: The inode of the directory in which to create the file. | ||
| 296 | * @dentry: The eCryptfs dentry | ||
| 297 | * @mode: The mode of the new file. | ||
| 298 | * @nd: nameidata | ||
| 299 | * | ||
| 300 | * Creates a new file. | ||
| 301 | * | ||
| 302 | * Returns zero on success; non-zero on error condition | ||
| 303 | */ | ||
| 304 | static int | ||
| 305 | ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, | ||
| 306 | int mode, struct nameidata *nd) | ||
| 307 | { | ||
| 308 | int rc; | ||
| 309 | |||
| 310 | rc = ecryptfs_do_create(directory_inode, ecryptfs_dentry, mode, nd); | ||
| 311 | if (unlikely(rc)) { | ||
| 312 | ecryptfs_printk(KERN_WARNING, "Failed to create file in" | ||
| 313 | "lower filesystem\n"); | ||
| 314 | goto out; | ||
| 315 | } | ||
| 316 | /* At this point, a file exists on "disk"; we need to make sure | ||
| 317 | * that this on disk file is prepared to be an ecryptfs file */ | ||
| 318 | rc = ecryptfs_initialize_file(ecryptfs_dentry); | ||
| 319 | out: | ||
| 320 | return rc; | ||
| 321 | } | ||
| 322 | |||
| 323 | /** | ||
| 324 | * ecryptfs_lookup | ||
| 325 | * @dir: inode | ||
| 326 | * @dentry: The dentry | ||
| 327 | * @nd: nameidata, may be NULL | ||
| 328 | * | ||
| 329 | * Find a file on disk. If the file does not exist, then we'll add it to the | ||
| 330 | * dentry cache and continue on to read it from the disk. | ||
| 331 | */ | ||
| 332 | static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | ||
| 333 | struct nameidata *nd) | ||
| 334 | { | ||
| 335 | int rc = 0; | ||
| 336 | struct dentry *lower_dir_dentry; | ||
| 337 | struct dentry *lower_dentry; | ||
| 338 | struct vfsmount *lower_mnt; | ||
| 339 | struct dentry *tlower_dentry = NULL; | ||
| 340 | char *encoded_name; | ||
| 341 | unsigned int encoded_namelen; | ||
| 342 | struct ecryptfs_crypt_stat *crypt_stat = NULL; | ||
| 343 | char *page_virt = NULL; | ||
| 344 | struct inode *lower_inode; | ||
| 345 | u64 file_size; | ||
| 346 | |||
| 347 | lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent); | ||
| 348 | dentry->d_op = &ecryptfs_dops; | ||
| 349 | if ((dentry->d_name.len == 1 && !strcmp(dentry->d_name.name, ".")) | ||
| 350 | || (dentry->d_name.len == 2 && !strcmp(dentry->d_name.name, ".."))) | ||
| 351 | goto out_drop; | ||
| 352 | encoded_namelen = ecryptfs_encode_filename(crypt_stat, | ||
| 353 | dentry->d_name.name, | ||
| 354 | dentry->d_name.len, | ||
| 355 | &encoded_name); | ||
| 356 | if (encoded_namelen < 0) { | ||
| 357 | rc = encoded_namelen; | ||
| 358 | goto out_drop; | ||
| 359 | } | ||
| 360 | ecryptfs_printk(KERN_DEBUG, "encoded_name = [%s]; encoded_namelen " | ||
| 361 | "= [%d]\n", encoded_name, encoded_namelen); | ||
| 362 | lower_dentry = lookup_one_len(encoded_name, lower_dir_dentry, | ||
| 363 | encoded_namelen - 1); | ||
| 364 | kfree(encoded_name); | ||
| 365 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent)); | ||
| 366 | if (IS_ERR(lower_dentry)) { | ||
| 367 | ecryptfs_printk(KERN_ERR, "ERR from lower_dentry\n"); | ||
| 368 | rc = PTR_ERR(lower_dentry); | ||
| 369 | goto out_drop; | ||
| 370 | } | ||
| 371 | ecryptfs_printk(KERN_DEBUG, "lower_dentry = [%p]; lower_dentry->" | ||
| 372 | "d_name.name = [%s]\n", lower_dentry, | ||
| 373 | lower_dentry->d_name.name); | ||
| 374 | lower_inode = lower_dentry->d_inode; | ||
| 375 | ecryptfs_copy_attr_atime(dir, lower_dir_dentry->d_inode); | ||
| 376 | BUG_ON(!atomic_read(&lower_dentry->d_count)); | ||
| 377 | ecryptfs_set_dentry_private(dentry, | ||
| 378 | kmem_cache_alloc(ecryptfs_dentry_info_cache, | ||
| 379 | SLAB_KERNEL)); | ||
| 380 | if (!ecryptfs_dentry_to_private(dentry)) { | ||
| 381 | rc = -ENOMEM; | ||
| 382 | ecryptfs_printk(KERN_ERR, "Out of memory whilst attempting " | ||
| 383 | "to allocate ecryptfs_dentry_info struct\n"); | ||
| 384 | goto out_dput; | ||
| 385 | } | ||
| 386 | ecryptfs_set_dentry_lower(dentry, lower_dentry); | ||
| 387 | ecryptfs_set_dentry_lower_mnt(dentry, lower_mnt); | ||
| 388 | if (!lower_dentry->d_inode) { | ||
| 389 | /* We want to add because we couldn't find in lower */ | ||
| 390 | d_add(dentry, NULL); | ||
| 391 | goto out; | ||
| 392 | } | ||
| 393 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 1); | ||
| 394 | if (rc) { | ||
| 395 | ecryptfs_printk(KERN_ERR, "Error interposing\n"); | ||
| 396 | goto out_dput; | ||
| 397 | } | ||
| 398 | if (S_ISDIR(lower_inode->i_mode)) { | ||
| 399 | ecryptfs_printk(KERN_DEBUG, "Is a directory; returning\n"); | ||
| 400 | goto out; | ||
| 401 | } | ||
| 402 | if (S_ISLNK(lower_inode->i_mode)) { | ||
| 403 | ecryptfs_printk(KERN_DEBUG, "Is a symlink; returning\n"); | ||
| 404 | goto out; | ||
| 405 | } | ||
| 406 | if (!nd) { | ||
| 407 | ecryptfs_printk(KERN_DEBUG, "We have a NULL nd, just leave" | ||
| 408 | "as we *think* we are about to unlink\n"); | ||
| 409 | goto out; | ||
| 410 | } | ||
| 411 | tlower_dentry = dget(lower_dentry); | ||
| 412 | if (!tlower_dentry || IS_ERR(tlower_dentry)) { | ||
| 413 | rc = -ENOMEM; | ||
| 414 | ecryptfs_printk(KERN_ERR, "Cannot dget lower_dentry\n"); | ||
| 415 | goto out_dput; | ||
| 416 | } | ||
| 417 | /* Released in this function */ | ||
| 418 | page_virt = | ||
| 419 | (char *)kmem_cache_alloc(ecryptfs_header_cache_2, | ||
| 420 | SLAB_USER); | ||
| 421 | if (!page_virt) { | ||
| 422 | rc = -ENOMEM; | ||
| 423 | ecryptfs_printk(KERN_ERR, | ||
| 424 | "Cannot ecryptfs_kmalloc a page\n"); | ||
| 425 | goto out_dput; | ||
| 426 | } | ||
| 427 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
| 428 | rc = ecryptfs_read_header_region(page_virt, tlower_dentry, nd->mnt); | ||
| 429 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | ||
| 430 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) | ||
| 431 | ecryptfs_set_default_sizes(crypt_stat); | ||
| 432 | if (rc) { | ||
| 433 | rc = 0; | ||
| 434 | ecryptfs_printk(KERN_WARNING, "Error reading header region;" | ||
| 435 | " assuming unencrypted\n"); | ||
| 436 | } else { | ||
| 437 | if (!contains_ecryptfs_marker(page_virt | ||
| 438 | + ECRYPTFS_FILE_SIZE_BYTES)) { | ||
| 439 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); | ||
| 440 | goto out; | ||
| 441 | } | ||
| 442 | memcpy(&file_size, page_virt, sizeof(file_size)); | ||
| 443 | file_size = be64_to_cpu(file_size); | ||
| 444 | i_size_write(dentry->d_inode, (loff_t)file_size); | ||
| 445 | } | ||
| 446 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); | ||
| 447 | goto out; | ||
| 448 | |||
| 449 | out_dput: | ||
| 450 | dput(lower_dentry); | ||
| 451 | if (tlower_dentry) | ||
| 452 | dput(tlower_dentry); | ||
| 453 | out_drop: | ||
| 454 | d_drop(dentry); | ||
| 455 | out: | ||
| 456 | return ERR_PTR(rc); | ||
| 457 | } | ||
| 458 | |||
| 459 | static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir, | ||
| 460 | struct dentry *new_dentry) | ||
| 461 | { | ||
| 462 | struct dentry *lower_old_dentry; | ||
| 463 | struct dentry *lower_new_dentry; | ||
| 464 | struct dentry *lower_dir_dentry; | ||
| 465 | u64 file_size_save; | ||
| 466 | int rc; | ||
| 467 | |||
| 468 | file_size_save = i_size_read(old_dentry->d_inode); | ||
| 469 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); | ||
| 470 | lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); | ||
| 471 | dget(lower_old_dentry); | ||
| 472 | dget(lower_new_dentry); | ||
| 473 | lower_dir_dentry = lock_parent(lower_new_dentry); | ||
| 474 | rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode, | ||
| 475 | lower_new_dentry); | ||
| 476 | if (rc || !lower_new_dentry->d_inode) | ||
| 477 | goto out_lock; | ||
| 478 | rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0); | ||
| 479 | if (rc) | ||
| 480 | goto out_lock; | ||
| 481 | ecryptfs_copy_attr_timesizes(dir, lower_new_dentry->d_inode); | ||
| 482 | old_dentry->d_inode->i_nlink = | ||
| 483 | ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink; | ||
| 484 | i_size_write(new_dentry->d_inode, file_size_save); | ||
| 485 | out_lock: | ||
| 486 | unlock_dir(lower_dir_dentry); | ||
| 487 | dput(lower_new_dentry); | ||
| 488 | dput(lower_old_dentry); | ||
| 489 | if (!new_dentry->d_inode) | ||
| 490 | d_drop(new_dentry); | ||
| 491 | return rc; | ||
| 492 | } | ||
| 493 | |||
| 494 | static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) | ||
| 495 | { | ||
| 496 | int rc = 0; | ||
| 497 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 498 | struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); | ||
| 499 | |||
| 500 | lock_parent(lower_dentry); | ||
| 501 | rc = vfs_unlink(lower_dir_inode, lower_dentry); | ||
| 502 | if (rc) { | ||
| 503 | ecryptfs_printk(KERN_ERR, "Error in vfs_unlink\n"); | ||
| 504 | goto out_unlock; | ||
| 505 | } | ||
| 506 | ecryptfs_copy_attr_times(dir, lower_dir_inode); | ||
| 507 | dentry->d_inode->i_nlink = | ||
| 508 | ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink; | ||
| 509 | dentry->d_inode->i_ctime = dir->i_ctime; | ||
| 510 | out_unlock: | ||
| 511 | unlock_parent(lower_dentry); | ||
| 512 | return rc; | ||
| 513 | } | ||
| 514 | |||
| 515 | static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, | ||
| 516 | const char *symname) | ||
| 517 | { | ||
| 518 | int rc; | ||
| 519 | struct dentry *lower_dentry; | ||
| 520 | struct dentry *lower_dir_dentry; | ||
| 521 | umode_t mode; | ||
| 522 | char *encoded_symname; | ||
| 523 | unsigned int encoded_symlen; | ||
| 524 | struct ecryptfs_crypt_stat *crypt_stat = NULL; | ||
| 525 | |||
| 526 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 527 | dget(lower_dentry); | ||
| 528 | lower_dir_dentry = lock_parent(lower_dentry); | ||
| 529 | mode = S_IALLUGO; | ||
| 530 | encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname, | ||
| 531 | strlen(symname), | ||
| 532 | &encoded_symname); | ||
| 533 | if (encoded_symlen < 0) { | ||
| 534 | rc = encoded_symlen; | ||
| 535 | goto out_lock; | ||
| 536 | } | ||
| 537 | rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, | ||
| 538 | encoded_symname, mode); | ||
| 539 | kfree(encoded_symname); | ||
| 540 | if (rc || !lower_dentry->d_inode) | ||
| 541 | goto out_lock; | ||
| 542 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); | ||
| 543 | if (rc) | ||
| 544 | goto out_lock; | ||
| 545 | ecryptfs_copy_attr_timesizes(dir, lower_dir_dentry->d_inode); | ||
| 546 | out_lock: | ||
| 547 | unlock_dir(lower_dir_dentry); | ||
| 548 | dput(lower_dentry); | ||
| 549 | if (!dentry->d_inode) | ||
| 550 | d_drop(dentry); | ||
| 551 | return rc; | ||
| 552 | } | ||
| 553 | |||
| 554 | static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | ||
| 555 | { | ||
| 556 | int rc; | ||
| 557 | struct dentry *lower_dentry; | ||
| 558 | struct dentry *lower_dir_dentry; | ||
| 559 | |||
| 560 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 561 | lower_dir_dentry = lock_parent(lower_dentry); | ||
| 562 | rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode); | ||
| 563 | if (rc || !lower_dentry->d_inode) | ||
| 564 | goto out; | ||
| 565 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); | ||
| 566 | if (rc) | ||
| 567 | goto out; | ||
| 568 | ecryptfs_copy_attr_timesizes(dir, lower_dir_dentry->d_inode); | ||
| 569 | dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; | ||
| 570 | out: | ||
| 571 | unlock_dir(lower_dir_dentry); | ||
| 572 | if (!dentry->d_inode) | ||
| 573 | d_drop(dentry); | ||
| 574 | return rc; | ||
| 575 | } | ||
| 576 | |||
| 577 | static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) | ||
| 578 | { | ||
| 579 | int rc = 0; | ||
| 580 | struct dentry *tdentry = NULL; | ||
| 581 | struct dentry *lower_dentry; | ||
| 582 | struct dentry *tlower_dentry = NULL; | ||
| 583 | struct dentry *lower_dir_dentry; | ||
| 584 | |||
| 585 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 586 | if (!(tdentry = dget(dentry))) { | ||
| 587 | rc = -EINVAL; | ||
| 588 | ecryptfs_printk(KERN_ERR, "Error dget'ing dentry [%p]\n", | ||
| 589 | dentry); | ||
| 590 | goto out; | ||
| 591 | } | ||
| 592 | lower_dir_dentry = lock_parent(lower_dentry); | ||
| 593 | if (!(tlower_dentry = dget(lower_dentry))) { | ||
| 594 | rc = -EINVAL; | ||
| 595 | ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry " | ||
| 596 | "[%p]\n", lower_dentry); | ||
| 597 | goto out; | ||
| 598 | } | ||
| 599 | rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); | ||
| 600 | if (!rc) { | ||
| 601 | d_delete(tlower_dentry); | ||
| 602 | tlower_dentry = NULL; | ||
| 603 | } | ||
| 604 | ecryptfs_copy_attr_times(dir, lower_dir_dentry->d_inode); | ||
| 605 | dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; | ||
| 606 | unlock_dir(lower_dir_dentry); | ||
| 607 | if (!rc) | ||
| 608 | d_drop(dentry); | ||
| 609 | out: | ||
| 610 | if (tdentry) | ||
| 611 | dput(tdentry); | ||
| 612 | if (tlower_dentry) | ||
| 613 | dput(tlower_dentry); | ||
| 614 | return rc; | ||
| 615 | } | ||
| 616 | |||
| 617 | static int | ||
| 618 | ecryptfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | ||
| 619 | { | ||
| 620 | int rc; | ||
| 621 | struct dentry *lower_dentry; | ||
| 622 | struct dentry *lower_dir_dentry; | ||
| 623 | |||
| 624 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 625 | lower_dir_dentry = lock_parent(lower_dentry); | ||
| 626 | rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev); | ||
| 627 | if (rc || !lower_dentry->d_inode) | ||
| 628 | goto out; | ||
| 629 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); | ||
| 630 | if (rc) | ||
| 631 | goto out; | ||
| 632 | ecryptfs_copy_attr_timesizes(dir, lower_dir_dentry->d_inode); | ||
| 633 | out: | ||
| 634 | unlock_dir(lower_dir_dentry); | ||
| 635 | if (!dentry->d_inode) | ||
| 636 | d_drop(dentry); | ||
| 637 | return rc; | ||
| 638 | } | ||
| 639 | |||
| 640 | static int | ||
| 641 | ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, | ||
| 642 | struct inode *new_dir, struct dentry *new_dentry) | ||
| 643 | { | ||
| 644 | int rc; | ||
| 645 | struct dentry *lower_old_dentry; | ||
| 646 | struct dentry *lower_new_dentry; | ||
| 647 | struct dentry *lower_old_dir_dentry; | ||
| 648 | struct dentry *lower_new_dir_dentry; | ||
| 649 | |||
| 650 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); | ||
| 651 | lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); | ||
| 652 | dget(lower_old_dentry); | ||
| 653 | dget(lower_new_dentry); | ||
| 654 | lower_old_dir_dentry = dget_parent(lower_old_dentry); | ||
| 655 | lower_new_dir_dentry = dget_parent(lower_new_dentry); | ||
| 656 | lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); | ||
| 657 | rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry, | ||
| 658 | lower_new_dir_dentry->d_inode, lower_new_dentry); | ||
| 659 | if (rc) | ||
| 660 | goto out_lock; | ||
| 661 | ecryptfs_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode); | ||
| 662 | if (new_dir != old_dir) | ||
| 663 | ecryptfs_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); | ||
| 664 | out_lock: | ||
| 665 | unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); | ||
| 666 | dput(lower_new_dentry); | ||
| 667 | dput(lower_old_dentry); | ||
| 668 | return rc; | ||
| 669 | } | ||
| 670 | |||
| 671 | static int | ||
| 672 | ecryptfs_readlink(struct dentry *dentry, char __user * buf, int bufsiz) | ||
| 673 | { | ||
| 674 | int rc; | ||
| 675 | struct dentry *lower_dentry; | ||
| 676 | char *decoded_name; | ||
| 677 | char *lower_buf; | ||
| 678 | mm_segment_t old_fs; | ||
| 679 | struct ecryptfs_crypt_stat *crypt_stat; | ||
| 680 | |||
| 681 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 682 | if (!lower_dentry->d_inode->i_op || | ||
| 683 | !lower_dentry->d_inode->i_op->readlink) { | ||
| 684 | rc = -EINVAL; | ||
| 685 | goto out; | ||
| 686 | } | ||
| 687 | /* Released in this function */ | ||
| 688 | lower_buf = kmalloc(bufsiz, GFP_KERNEL); | ||
| 689 | if (lower_buf == NULL) { | ||
| 690 | ecryptfs_printk(KERN_ERR, "Out of memory\n"); | ||
| 691 | rc = -ENOMEM; | ||
| 692 | goto out; | ||
| 693 | } | ||
| 694 | old_fs = get_fs(); | ||
| 695 | set_fs(get_ds()); | ||
| 696 | ecryptfs_printk(KERN_DEBUG, "Calling readlink w/ " | ||
| 697 | "lower_dentry->d_name.name = [%s]\n", | ||
| 698 | lower_dentry->d_name.name); | ||
| 699 | rc = lower_dentry->d_inode->i_op->readlink(lower_dentry, | ||
| 700 | (char __user *)lower_buf, | ||
| 701 | bufsiz); | ||
| 702 | set_fs(old_fs); | ||
| 703 | if (rc >= 0) { | ||
| 704 | crypt_stat = NULL; | ||
| 705 | rc = ecryptfs_decode_filename(crypt_stat, lower_buf, rc, | ||
| 706 | &decoded_name); | ||
| 707 | if (rc == -ENOMEM) | ||
| 708 | goto out_free_lower_buf; | ||
| 709 | if (rc > 0) { | ||
| 710 | ecryptfs_printk(KERN_DEBUG, "Copying [%d] bytes " | ||
| 711 | "to userspace: [%*s]\n", rc, | ||
| 712 | decoded_name); | ||
| 713 | if (copy_to_user(buf, decoded_name, rc)) | ||
| 714 | rc = -EFAULT; | ||
| 715 | } | ||
| 716 | kfree(decoded_name); | ||
| 717 | ecryptfs_copy_attr_atime(dentry->d_inode, | ||
| 718 | lower_dentry->d_inode); | ||
| 719 | } | ||
| 720 | out_free_lower_buf: | ||
| 721 | kfree(lower_buf); | ||
| 722 | out: | ||
| 723 | return rc; | ||
| 724 | } | ||
| 725 | |||
| 726 | static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd) | ||
| 727 | { | ||
| 728 | char *buf; | ||
| 729 | int len = PAGE_SIZE, rc; | ||
| 730 | mm_segment_t old_fs; | ||
| 731 | |||
| 732 | /* Released in ecryptfs_put_link(); only release here on error */ | ||
| 733 | buf = kmalloc(len, GFP_KERNEL); | ||
| 734 | if (!buf) { | ||
| 735 | rc = -ENOMEM; | ||
| 736 | goto out; | ||
| 737 | } | ||
| 738 | old_fs = get_fs(); | ||
| 739 | set_fs(get_ds()); | ||
| 740 | ecryptfs_printk(KERN_DEBUG, "Calling readlink w/ " | ||
| 741 | "dentry->d_name.name = [%s]\n", dentry->d_name.name); | ||
| 742 | rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len); | ||
| 743 | buf[rc] = '\0'; | ||
| 744 | set_fs(old_fs); | ||
| 745 | if (rc < 0) | ||
| 746 | goto out_free; | ||
| 747 | rc = 0; | ||
| 748 | nd_set_link(nd, buf); | ||
| 749 | goto out; | ||
| 750 | out_free: | ||
| 751 | kfree(buf); | ||
| 752 | out: | ||
| 753 | return ERR_PTR(rc); | ||
| 754 | } | ||
| 755 | |||
| 756 | static void | ||
| 757 | ecryptfs_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr) | ||
| 758 | { | ||
| 759 | /* Free the char* */ | ||
| 760 | kfree(nd_get_link(nd)); | ||
| 761 | } | ||
| 762 | |||
| 763 | /** | ||
| 764 | * upper_size_to_lower_size | ||
| 765 | * @crypt_stat: Crypt_stat associated with file | ||
| 766 | * @upper_size: Size of the upper file | ||
| 767 | * | ||
| 768 | * Calculate the requried size of the lower file based on the | ||
| 769 | * specified size of the upper file. This calculation is based on the | ||
| 770 | * number of headers in the underlying file and the extent size. | ||
| 771 | * | ||
| 772 | * Returns Calculated size of the lower file. | ||
| 773 | */ | ||
| 774 | static loff_t | ||
| 775 | upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat, | ||
| 776 | loff_t upper_size) | ||
| 777 | { | ||
| 778 | loff_t lower_size; | ||
| 779 | |||
| 780 | lower_size = ( crypt_stat->header_extent_size | ||
| 781 | * crypt_stat->num_header_extents_at_front ); | ||
| 782 | if (upper_size != 0) { | ||
| 783 | loff_t num_extents; | ||
| 784 | |||
| 785 | num_extents = upper_size >> crypt_stat->extent_shift; | ||
| 786 | if (upper_size & ~crypt_stat->extent_mask) | ||
| 787 | num_extents++; | ||
| 788 | lower_size += (num_extents * crypt_stat->extent_size); | ||
| 789 | } | ||
| 790 | return lower_size; | ||
| 791 | } | ||
| 792 | |||
| 793 | /** | ||
| 794 | * ecryptfs_truncate | ||
| 795 | * @dentry: The ecryptfs layer dentry | ||
| 796 | * @new_length: The length to expand the file to | ||
| 797 | * | ||
| 798 | * Function to handle truncations modifying the size of the file. Note | ||
| 799 | * that the file sizes are interpolated. When expanding, we are simply | ||
| 800 | * writing strings of 0's out. When truncating, we need to modify the | ||
| 801 | * underlying file size according to the page index interpolations. | ||
| 802 | * | ||
| 803 | * Returns zero on success; non-zero otherwise | ||
| 804 | */ | ||
| 805 | int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | ||
| 806 | { | ||
| 807 | int rc = 0; | ||
| 808 | struct inode *inode = dentry->d_inode; | ||
| 809 | struct dentry *lower_dentry; | ||
| 810 | struct vfsmount *lower_mnt; | ||
| 811 | struct file fake_ecryptfs_file, *lower_file = NULL; | ||
| 812 | struct ecryptfs_crypt_stat *crypt_stat; | ||
| 813 | loff_t i_size = i_size_read(inode); | ||
| 814 | loff_t lower_size_before_truncate; | ||
| 815 | loff_t lower_size_after_truncate; | ||
| 816 | |||
| 817 | if (unlikely((new_length == i_size))) | ||
| 818 | goto out; | ||
| 819 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | ||
| 820 | /* Set up a fake ecryptfs file, this is used to interface with | ||
| 821 | * the file in the underlying filesystem so that the | ||
| 822 | * truncation has an effect there as well. */ | ||
| 823 | memset(&fake_ecryptfs_file, 0, sizeof(fake_ecryptfs_file)); | ||
| 824 | fake_ecryptfs_file.f_dentry = dentry; | ||
| 825 | /* Released at out_free: label */ | ||
| 826 | ecryptfs_set_file_private(&fake_ecryptfs_file, | ||
| 827 | kmem_cache_alloc(ecryptfs_file_info_cache, | ||
| 828 | SLAB_KERNEL)); | ||
| 829 | if (unlikely(!ecryptfs_file_to_private(&fake_ecryptfs_file))) { | ||
| 830 | rc = -ENOMEM; | ||
| 831 | goto out; | ||
| 832 | } | ||
| 833 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 834 | /* This dget & mntget is released through fput at out_fput: */ | ||
| 835 | dget(lower_dentry); | ||
| 836 | lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); | ||
| 837 | mntget(lower_mnt); | ||
| 838 | lower_file = dentry_open(lower_dentry, lower_mnt, O_RDWR); | ||
| 839 | if (unlikely(IS_ERR(lower_file))) { | ||
| 840 | rc = PTR_ERR(lower_file); | ||
| 841 | goto out_free; | ||
| 842 | } | ||
| 843 | ecryptfs_set_file_lower(&fake_ecryptfs_file, lower_file); | ||
| 844 | /* Switch on growing or shrinking file */ | ||
| 845 | if (new_length > i_size) { | ||
| 846 | rc = ecryptfs_fill_zeros(&fake_ecryptfs_file, new_length); | ||
| 847 | if (rc) { | ||
| 848 | ecryptfs_printk(KERN_ERR, | ||
| 849 | "Problem with fill_zeros\n"); | ||
| 850 | goto out_fput; | ||
| 851 | } | ||
| 852 | i_size_write(inode, new_length); | ||
| 853 | rc = ecryptfs_write_inode_size_to_header(lower_file, | ||
| 854 | lower_dentry->d_inode, | ||
| 855 | inode); | ||
| 856 | if (rc) { | ||
| 857 | ecryptfs_printk(KERN_ERR, | ||
| 858 | "Problem with ecryptfs_write" | ||
| 859 | "_inode_size\n"); | ||
| 860 | goto out_fput; | ||
| 861 | } | ||
| 862 | } else { /* new_length < i_size_read(inode) */ | ||
| 863 | vmtruncate(inode, new_length); | ||
| 864 | ecryptfs_write_inode_size_to_header(lower_file, | ||
| 865 | lower_dentry->d_inode, | ||
| 866 | inode); | ||
| 867 | /* We are reducing the size of the ecryptfs file, and need to | ||
| 868 | * know if we need to reduce the size of the lower file. */ | ||
| 869 | lower_size_before_truncate = | ||
| 870 | upper_size_to_lower_size(crypt_stat, i_size); | ||
| 871 | lower_size_after_truncate = | ||
| 872 | upper_size_to_lower_size(crypt_stat, new_length); | ||
| 873 | if (lower_size_after_truncate < lower_size_before_truncate) | ||
| 874 | vmtruncate(lower_dentry->d_inode, | ||
| 875 | lower_size_after_truncate); | ||
| 876 | } | ||
| 877 | /* Update the access times */ | ||
| 878 | lower_dentry->d_inode->i_mtime = lower_dentry->d_inode->i_ctime | ||
| 879 | = CURRENT_TIME; | ||
| 880 | mark_inode_dirty_sync(inode); | ||
| 881 | out_fput: | ||
| 882 | fput(lower_file); | ||
| 883 | out_free: | ||
| 884 | if (ecryptfs_file_to_private(&fake_ecryptfs_file)) | ||
| 885 | kmem_cache_free(ecryptfs_file_info_cache, | ||
| 886 | ecryptfs_file_to_private(&fake_ecryptfs_file)); | ||
| 887 | out: | ||
| 888 | return rc; | ||
| 889 | } | ||
| 890 | |||
| 891 | static int | ||
| 892 | ecryptfs_permission(struct inode *inode, int mask, struct nameidata *nd) | ||
| 893 | { | ||
| 894 | int rc; | ||
| 895 | |||
| 896 | if (nd) { | ||
| 897 | struct vfsmount *vfsmnt_save = nd->mnt; | ||
| 898 | struct dentry *dentry_save = nd->dentry; | ||
| 899 | |||
| 900 | nd->mnt = ecryptfs_dentry_to_lower_mnt(nd->dentry); | ||
| 901 | nd->dentry = ecryptfs_dentry_to_lower(nd->dentry); | ||
| 902 | rc = permission(ecryptfs_inode_to_lower(inode), mask, nd); | ||
| 903 | nd->mnt = vfsmnt_save; | ||
| 904 | nd->dentry = dentry_save; | ||
| 905 | } else | ||
| 906 | rc = permission(ecryptfs_inode_to_lower(inode), mask, NULL); | ||
| 907 | return rc; | ||
| 908 | } | ||
| 909 | |||
| 910 | /** | ||
| 911 | * ecryptfs_setattr | ||
| 912 | * @dentry: dentry handle to the inode to modify | ||
| 913 | * @ia: Structure with flags of what to change and values | ||
| 914 | * | ||
| 915 | * Updates the metadata of an inode. If the update is to the size | ||
| 916 | * i.e. truncation, then ecryptfs_truncate will handle the size modification | ||
| 917 | * of both the ecryptfs inode and the lower inode. | ||
| 918 | * | ||
| 919 | * All other metadata changes will be passed right to the lower filesystem, | ||
| 920 | * and we will just update our inode to look like the lower. | ||
| 921 | */ | ||
| 922 | static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | ||
| 923 | { | ||
| 924 | int rc = 0; | ||
| 925 | struct dentry *lower_dentry; | ||
| 926 | struct inode *inode; | ||
| 927 | struct inode *lower_inode; | ||
| 928 | struct ecryptfs_crypt_stat *crypt_stat; | ||
| 929 | |||
| 930 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | ||
| 931 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 932 | inode = dentry->d_inode; | ||
| 933 | lower_inode = ecryptfs_inode_to_lower(inode); | ||
| 934 | if (ia->ia_valid & ATTR_SIZE) { | ||
| 935 | ecryptfs_printk(KERN_DEBUG, | ||
| 936 | "ia->ia_valid = [0x%x] ATTR_SIZE" " = [0x%x]\n", | ||
| 937 | ia->ia_valid, ATTR_SIZE); | ||
| 938 | rc = ecryptfs_truncate(dentry, ia->ia_size); | ||
| 939 | /* ecryptfs_truncate handles resizing of the lower file */ | ||
| 940 | ia->ia_valid &= ~ATTR_SIZE; | ||
| 941 | ecryptfs_printk(KERN_DEBUG, "ia->ia_valid = [%x]\n", | ||
| 942 | ia->ia_valid); | ||
| 943 | if (rc < 0) | ||
| 944 | goto out; | ||
| 945 | } | ||
| 946 | rc = notify_change(lower_dentry, ia); | ||
| 947 | out: | ||
| 948 | ecryptfs_copy_attr_all(inode, lower_inode); | ||
| 949 | return rc; | ||
| 950 | } | ||
| 951 | |||
| 952 | static int | ||
| 953 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, | ||
| 954 | size_t size, int flags) | ||
| 955 | { | ||
| 956 | int rc = 0; | ||
| 957 | struct dentry *lower_dentry; | ||
| 958 | |||
| 959 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 960 | if (!lower_dentry->d_inode->i_op->setxattr) { | ||
| 961 | rc = -ENOSYS; | ||
| 962 | goto out; | ||
| 963 | } | ||
| 964 | mutex_lock(&lower_dentry->d_inode->i_mutex); | ||
| 965 | rc = lower_dentry->d_inode->i_op->setxattr(lower_dentry, name, value, | ||
| 966 | size, flags); | ||
| 967 | mutex_unlock(&lower_dentry->d_inode->i_mutex); | ||
| 968 | out: | ||
| 969 | return rc; | ||
| 970 | } | ||
| 971 | |||
| 972 | static ssize_t | ||
| 973 | ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value, | ||
| 974 | size_t size) | ||
| 975 | { | ||
| 976 | int rc = 0; | ||
| 977 | struct dentry *lower_dentry; | ||
| 978 | |||
| 979 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 980 | if (!lower_dentry->d_inode->i_op->getxattr) { | ||
| 981 | rc = -ENOSYS; | ||
| 982 | goto out; | ||
| 983 | } | ||
| 984 | mutex_lock(&lower_dentry->d_inode->i_mutex); | ||
| 985 | rc = lower_dentry->d_inode->i_op->getxattr(lower_dentry, name, value, | ||
| 986 | size); | ||
| 987 | mutex_unlock(&lower_dentry->d_inode->i_mutex); | ||
| 988 | out: | ||
| 989 | return rc; | ||
| 990 | } | ||
| 991 | |||
| 992 | static ssize_t | ||
| 993 | ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size) | ||
| 994 | { | ||
| 995 | int rc = 0; | ||
| 996 | struct dentry *lower_dentry; | ||
| 997 | |||
| 998 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 999 | if (!lower_dentry->d_inode->i_op->listxattr) { | ||
| 1000 | rc = -ENOSYS; | ||
| 1001 | goto out; | ||
| 1002 | } | ||
| 1003 | mutex_lock(&lower_dentry->d_inode->i_mutex); | ||
| 1004 | rc = lower_dentry->d_inode->i_op->listxattr(lower_dentry, list, size); | ||
| 1005 | mutex_unlock(&lower_dentry->d_inode->i_mutex); | ||
| 1006 | out: | ||
| 1007 | return rc; | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | static int ecryptfs_removexattr(struct dentry *dentry, const char *name) | ||
| 1011 | { | ||
| 1012 | int rc = 0; | ||
| 1013 | struct dentry *lower_dentry; | ||
| 1014 | |||
| 1015 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 1016 | if (!lower_dentry->d_inode->i_op->removexattr) { | ||
| 1017 | rc = -ENOSYS; | ||
| 1018 | goto out; | ||
| 1019 | } | ||
| 1020 | mutex_lock(&lower_dentry->d_inode->i_mutex); | ||
| 1021 | rc = lower_dentry->d_inode->i_op->removexattr(lower_dentry, name); | ||
| 1022 | mutex_unlock(&lower_dentry->d_inode->i_mutex); | ||
| 1023 | out: | ||
| 1024 | return rc; | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode) | ||
| 1028 | { | ||
| 1029 | if ((ecryptfs_inode_to_lower(inode) | ||
| 1030 | == (struct inode *)candidate_lower_inode)) | ||
| 1031 | return 1; | ||
| 1032 | else | ||
| 1033 | return 0; | ||
| 1034 | } | ||
| 1035 | |||
| 1036 | int ecryptfs_inode_set(struct inode *inode, void *lower_inode) | ||
| 1037 | { | ||
| 1038 | ecryptfs_init_inode(inode, (struct inode *)lower_inode); | ||
| 1039 | return 0; | ||
| 1040 | } | ||
| 1041 | |||
| 1042 | struct inode_operations ecryptfs_symlink_iops = { | ||
| 1043 | .readlink = ecryptfs_readlink, | ||
| 1044 | .follow_link = ecryptfs_follow_link, | ||
| 1045 | .put_link = ecryptfs_put_link, | ||
| 1046 | .permission = ecryptfs_permission, | ||
| 1047 | .setattr = ecryptfs_setattr, | ||
| 1048 | .setxattr = ecryptfs_setxattr, | ||
| 1049 | .getxattr = ecryptfs_getxattr, | ||
| 1050 | .listxattr = ecryptfs_listxattr, | ||
| 1051 | .removexattr = ecryptfs_removexattr | ||
| 1052 | }; | ||
| 1053 | |||
| 1054 | struct inode_operations ecryptfs_dir_iops = { | ||
| 1055 | .create = ecryptfs_create, | ||
| 1056 | .lookup = ecryptfs_lookup, | ||
| 1057 | .link = ecryptfs_link, | ||
| 1058 | .unlink = ecryptfs_unlink, | ||
| 1059 | .symlink = ecryptfs_symlink, | ||
| 1060 | .mkdir = ecryptfs_mkdir, | ||
| 1061 | .rmdir = ecryptfs_rmdir, | ||
| 1062 | .mknod = ecryptfs_mknod, | ||
| 1063 | .rename = ecryptfs_rename, | ||
| 1064 | .permission = ecryptfs_permission, | ||
| 1065 | .setattr = ecryptfs_setattr, | ||
| 1066 | .setxattr = ecryptfs_setxattr, | ||
| 1067 | .getxattr = ecryptfs_getxattr, | ||
| 1068 | .listxattr = ecryptfs_listxattr, | ||
| 1069 | .removexattr = ecryptfs_removexattr | ||
| 1070 | }; | ||
| 1071 | |||
| 1072 | struct inode_operations ecryptfs_main_iops = { | ||
| 1073 | .permission = ecryptfs_permission, | ||
| 1074 | .setattr = ecryptfs_setattr, | ||
| 1075 | .setxattr = ecryptfs_setxattr, | ||
| 1076 | .getxattr = ecryptfs_getxattr, | ||
| 1077 | .listxattr = ecryptfs_listxattr, | ||
| 1078 | .removexattr = ecryptfs_removexattr | ||
| 1079 | }; | ||
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c new file mode 100644 index 000000000000..ba454785a0c5 --- /dev/null +++ b/fs/ecryptfs/keystore.c | |||
| @@ -0,0 +1,1061 @@ | |||
| 1 | /** | ||
| 2 | * eCryptfs: Linux filesystem encryption layer | ||
| 3 | * In-kernel key management code. Includes functions to parse and | ||
| 4 | * write authentication token-related packets with the underlying | ||
| 5 | * file. | ||
| 6 | * | ||
| 7 | * Copyright (C) 2004-2006 International Business Machines Corp. | ||
| 8 | * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> | ||
| 9 | * Michael C. Thompson <mcthomps@us.ibm.com> | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or | ||
| 12 | * modify it under the terms of the GNU General Public License as | ||
| 13 | * published by the Free Software Foundation; either version 2 of the | ||
| 14 | * License, or (at your option) any later version. | ||
| 15 | * | ||
| 16 | * This program is distributed in the hope that it will be useful, but | ||
| 17 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 19 | * General Public License for more details. | ||
| 20 | * | ||
| 21 | * You should have received a copy of the GNU General Public License | ||
| 22 | * along with this program; if not, write to the Free Software | ||
| 23 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
| 24 | * 02111-1307, USA. | ||
| 25 | */ | ||
| 26 | |||
| 27 | #include <linux/string.h> | ||
| 28 | #include <linux/sched.h> | ||
| 29 | #include <linux/syscalls.h> | ||
| 30 | #include <linux/pagemap.h> | ||
| 31 | #include <linux/key.h> | ||
| 32 | #include <linux/random.h> | ||
| 33 | #include <linux/crypto.h> | ||
| 34 | #include <linux/scatterlist.h> | ||
| 35 | #include "ecryptfs_kernel.h" | ||
| 36 | |||
| 37 | /** | ||
| 38 | * request_key returned an error instead of a valid key address; | ||
| 39 | * determine the type of error, make appropriate log entries, and | ||
| 40 | * return an error code. | ||
| 41 | */ | ||
| 42 | int process_request_key_err(long err_code) | ||
| 43 | { | ||
| 44 | int rc = 0; | ||
| 45 | |||
| 46 | switch (err_code) { | ||
| 47 | case ENOKEY: | ||
| 48 | ecryptfs_printk(KERN_WARNING, "No key\n"); | ||
| 49 | rc = -ENOENT; | ||
| 50 | break; | ||
| 51 | case EKEYEXPIRED: | ||
| 52 | ecryptfs_printk(KERN_WARNING, "Key expired\n"); | ||
| 53 | rc = -ETIME; | ||
| 54 | break; | ||
| 55 | case EKEYREVOKED: | ||
| 56 | ecryptfs_printk(KERN_WARNING, "Key revoked\n"); | ||
| 57 | rc = -EINVAL; | ||
| 58 | break; | ||
| 59 | default: | ||
| 60 | ecryptfs_printk(KERN_WARNING, "Unknown error code: " | ||
| 61 | "[0x%.16x]\n", err_code); | ||
| 62 | rc = -EINVAL; | ||
| 63 | } | ||
| 64 | return rc; | ||
| 65 | } | ||
| 66 | |||
| 67 | static void wipe_auth_tok_list(struct list_head *auth_tok_list_head) | ||
| 68 | { | ||
| 69 | struct list_head *walker; | ||
| 70 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | ||
| 71 | |||
| 72 | walker = auth_tok_list_head->next; | ||
| 73 | while (walker != auth_tok_list_head) { | ||
| 74 | auth_tok_list_item = | ||
| 75 | list_entry(walker, struct ecryptfs_auth_tok_list_item, | ||
| 76 | list); | ||
| 77 | walker = auth_tok_list_item->list.next; | ||
| 78 | memset(auth_tok_list_item, 0, | ||
| 79 | sizeof(struct ecryptfs_auth_tok_list_item)); | ||
| 80 | kmem_cache_free(ecryptfs_auth_tok_list_item_cache, | ||
| 81 | auth_tok_list_item); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | struct kmem_cache *ecryptfs_auth_tok_list_item_cache; | ||
| 86 | |||
| 87 | /** | ||
| 88 | * parse_packet_length | ||
| 89 | * @data: Pointer to memory containing length at offset | ||
| 90 | * @size: This function writes the decoded size to this memory | ||
| 91 | * address; zero on error | ||
| 92 | * @length_size: The number of bytes occupied by the encoded length | ||
| 93 | * | ||
| 94 | * Returns Zero on success | ||
| 95 | */ | ||
| 96 | static int parse_packet_length(unsigned char *data, size_t *size, | ||
| 97 | size_t *length_size) | ||
| 98 | { | ||
| 99 | int rc = 0; | ||
| 100 | |||
| 101 | (*length_size) = 0; | ||
| 102 | (*size) = 0; | ||
| 103 | if (data[0] < 192) { | ||
| 104 | /* One-byte length */ | ||
| 105 | (*size) = data[0]; | ||
| 106 | (*length_size) = 1; | ||
| 107 | } else if (data[0] < 224) { | ||
| 108 | /* Two-byte length */ | ||
| 109 | (*size) = ((data[0] - 192) * 256); | ||
| 110 | (*size) += (data[1] + 192); | ||
| 111 | (*length_size) = 2; | ||
| 112 | } else if (data[0] == 255) { | ||
| 113 | /* Five-byte length; we're not supposed to see this */ | ||
| 114 | ecryptfs_printk(KERN_ERR, "Five-byte packet length not " | ||
| 115 | "supported\n"); | ||
| 116 | rc = -EINVAL; | ||
| 117 | goto out; | ||
| 118 | } else { | ||
| 119 | ecryptfs_printk(KERN_ERR, "Error parsing packet length\n"); | ||
| 120 | rc = -EINVAL; | ||
| 121 | goto out; | ||
| 122 | } | ||
| 123 | out: | ||
| 124 | return rc; | ||
| 125 | } | ||
| 126 | |||
| 127 | /** | ||
| 128 | * write_packet_length | ||
| 129 | * @dest: The byte array target into which to write the | ||
| 130 | * length. Must have at least 5 bytes allocated. | ||
| 131 | * @size: The length to write. | ||
| 132 | * @packet_size_length: The number of bytes used to encode the | ||
| 133 | * packet length is written to this address. | ||
| 134 | * | ||
| 135 | * Returns zero on success; non-zero on error. | ||
| 136 | */ | ||
| 137 | static int write_packet_length(char *dest, size_t size, | ||
| 138 | size_t *packet_size_length) | ||
| 139 | { | ||
| 140 | int rc = 0; | ||
| 141 | |||
| 142 | if (size < 192) { | ||
| 143 | dest[0] = size; | ||
| 144 | (*packet_size_length) = 1; | ||
| 145 | } else if (size < 65536) { | ||
| 146 | dest[0] = (((size - 192) / 256) + 192); | ||
| 147 | dest[1] = ((size - 192) % 256); | ||
| 148 | (*packet_size_length) = 2; | ||
| 149 | } else { | ||
| 150 | rc = -EINVAL; | ||
| 151 | ecryptfs_printk(KERN_WARNING, | ||
| 152 | "Unsupported packet size: [%d]\n", size); | ||
| 153 | } | ||
| 154 | return rc; | ||
| 155 | } | ||
| 156 | |||
| 157 | /** | ||
| 158 | * parse_tag_3_packet | ||
| 159 | * @crypt_stat: The cryptographic context to modify based on packet | ||
| 160 | * contents. | ||
| 161 | * @data: The raw bytes of the packet. | ||
| 162 | * @auth_tok_list: eCryptfs parses packets into authentication tokens; | ||
| 163 | * a new authentication token will be placed at the end | ||
| 164 | * of this list for this packet. | ||
| 165 | * @new_auth_tok: Pointer to a pointer to memory that this function | ||
| 166 | * allocates; sets the memory address of the pointer to | ||
| 167 | * NULL on error. This object is added to the | ||
| 168 | * auth_tok_list. | ||
| 169 | * @packet_size: This function writes the size of the parsed packet | ||
| 170 | * into this memory location; zero on error. | ||
| 171 | * @max_packet_size: maximum number of bytes to parse | ||
| 172 | * | ||
| 173 | * Returns zero on success; non-zero on error. | ||
| 174 | */ | ||
| 175 | static int | ||
| 176 | parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat, | ||
| 177 | unsigned char *data, struct list_head *auth_tok_list, | ||
| 178 | struct ecryptfs_auth_tok **new_auth_tok, | ||
| 179 | size_t *packet_size, size_t max_packet_size) | ||
| 180 | { | ||
| 181 | int rc = 0; | ||
| 182 | size_t body_size; | ||
| 183 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | ||
| 184 | size_t length_size; | ||
| 185 | |||
| 186 | (*packet_size) = 0; | ||
| 187 | (*new_auth_tok) = NULL; | ||
| 188 | |||
| 189 | /* we check that: | ||
| 190 | * one byte for the Tag 3 ID flag | ||
| 191 | * two bytes for the body size | ||
| 192 | * do not exceed the maximum_packet_size | ||
| 193 | */ | ||
| 194 | if (unlikely((*packet_size) + 3 > max_packet_size)) { | ||
| 195 | ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); | ||
| 196 | rc = -EINVAL; | ||
| 197 | goto out; | ||
| 198 | } | ||
| 199 | |||
| 200 | /* check for Tag 3 identifyer - one byte */ | ||
| 201 | if (data[(*packet_size)++] != ECRYPTFS_TAG_3_PACKET_TYPE) { | ||
| 202 | ecryptfs_printk(KERN_ERR, "Enter w/ first byte != 0x%.2x\n", | ||
| 203 | ECRYPTFS_TAG_3_PACKET_TYPE); | ||
| 204 | rc = -EINVAL; | ||
| 205 | goto out; | ||
| 206 | } | ||
| 207 | /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or | ||
| 208 | * at end of function upon failure */ | ||
| 209 | auth_tok_list_item = | ||
| 210 | kmem_cache_alloc(ecryptfs_auth_tok_list_item_cache, SLAB_KERNEL); | ||
| 211 | if (!auth_tok_list_item) { | ||
| 212 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); | ||
| 213 | rc = -ENOMEM; | ||
| 214 | goto out; | ||
| 215 | } | ||
| 216 | memset(auth_tok_list_item, 0, | ||
| 217 | sizeof(struct ecryptfs_auth_tok_list_item)); | ||
| 218 | (*new_auth_tok) = &auth_tok_list_item->auth_tok; | ||
| 219 | |||
| 220 | /* check for body size - one to two bytes */ | ||
| 221 | rc = parse_packet_length(&data[(*packet_size)], &body_size, | ||
| 222 | &length_size); | ||
| 223 | if (rc) { | ||
| 224 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " | ||
| 225 | "rc = [%d]\n", rc); | ||
| 226 | goto out_free; | ||
| 227 | } | ||
| 228 | if (unlikely(body_size < (0x05 + ECRYPTFS_SALT_SIZE))) { | ||
| 229 | ecryptfs_printk(KERN_WARNING, "Invalid body size ([%d])\n", | ||
| 230 | body_size); | ||
| 231 | rc = -EINVAL; | ||
| 232 | goto out_free; | ||
| 233 | } | ||
| 234 | (*packet_size) += length_size; | ||
| 235 | |||
| 236 | /* now we know the length of the remainting Tag 3 packet size: | ||
| 237 | * 5 fix bytes for: version string, cipher, S2K ID, hash algo, | ||
| 238 | * number of hash iterations | ||
| 239 | * ECRYPTFS_SALT_SIZE bytes for salt | ||
| 240 | * body_size bytes minus the stuff above is the encrypted key size | ||
| 241 | */ | ||
| 242 | if (unlikely((*packet_size) + body_size > max_packet_size)) { | ||
| 243 | ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); | ||
| 244 | rc = -EINVAL; | ||
| 245 | goto out_free; | ||
| 246 | } | ||
| 247 | |||
| 248 | /* There are 5 characters of additional information in the | ||
| 249 | * packet */ | ||
| 250 | (*new_auth_tok)->session_key.encrypted_key_size = | ||
| 251 | body_size - (0x05 + ECRYPTFS_SALT_SIZE); | ||
| 252 | ecryptfs_printk(KERN_DEBUG, "Encrypted key size = [%d]\n", | ||
| 253 | (*new_auth_tok)->session_key.encrypted_key_size); | ||
| 254 | |||
| 255 | /* Version 4 (from RFC2440) - one byte */ | ||
| 256 | if (unlikely(data[(*packet_size)++] != 0x04)) { | ||
| 257 | ecryptfs_printk(KERN_DEBUG, "Unknown version number " | ||
| 258 | "[%d]\n", data[(*packet_size) - 1]); | ||
| 259 | rc = -EINVAL; | ||
| 260 | goto out_free; | ||
| 261 | } | ||
| 262 | |||
| 263 | /* cipher - one byte */ | ||
| 264 | ecryptfs_cipher_code_to_string(crypt_stat->cipher, | ||
| 265 | (u16)data[(*packet_size)]); | ||
| 266 | /* A little extra work to differentiate among the AES key | ||
| 267 | * sizes; see RFC2440 */ | ||
| 268 | switch(data[(*packet_size)++]) { | ||
| 269 | case RFC2440_CIPHER_AES_192: | ||
| 270 | crypt_stat->key_size = 24; | ||
| 271 | break; | ||
| 272 | default: | ||
| 273 | crypt_stat->key_size = | ||
| 274 | (*new_auth_tok)->session_key.encrypted_key_size; | ||
| 275 | } | ||
| 276 | ecryptfs_init_crypt_ctx(crypt_stat); | ||
| 277 | /* S2K identifier 3 (from RFC2440) */ | ||
| 278 | if (unlikely(data[(*packet_size)++] != 0x03)) { | ||
| 279 | ecryptfs_printk(KERN_ERR, "Only S2K ID 3 is currently " | ||
| 280 | "supported\n"); | ||
| 281 | rc = -ENOSYS; | ||
| 282 | goto out_free; | ||
| 283 | } | ||
| 284 | |||
| 285 | /* TODO: finish the hash mapping */ | ||
| 286 | /* hash algorithm - one byte */ | ||
| 287 | switch (data[(*packet_size)++]) { | ||
| 288 | case 0x01: /* See RFC2440 for these numbers and their mappings */ | ||
| 289 | /* Choose MD5 */ | ||
| 290 | /* salt - ECRYPTFS_SALT_SIZE bytes */ | ||
| 291 | memcpy((*new_auth_tok)->token.password.salt, | ||
| 292 | &data[(*packet_size)], ECRYPTFS_SALT_SIZE); | ||
| 293 | (*packet_size) += ECRYPTFS_SALT_SIZE; | ||
| 294 | |||
| 295 | /* This conversion was taken straight from RFC2440 */ | ||
| 296 | /* number of hash iterations - one byte */ | ||
| 297 | (*new_auth_tok)->token.password.hash_iterations = | ||
| 298 | ((u32) 16 + (data[(*packet_size)] & 15)) | ||
| 299 | << ((data[(*packet_size)] >> 4) + 6); | ||
| 300 | (*packet_size)++; | ||
| 301 | |||
| 302 | /* encrypted session key - | ||
| 303 | * (body_size-5-ECRYPTFS_SALT_SIZE) bytes */ | ||
| 304 | memcpy((*new_auth_tok)->session_key.encrypted_key, | ||
| 305 | &data[(*packet_size)], | ||
| 306 | (*new_auth_tok)->session_key.encrypted_key_size); | ||
| 307 | (*packet_size) += | ||
| 308 | (*new_auth_tok)->session_key.encrypted_key_size; | ||
| 309 | (*new_auth_tok)->session_key.flags &= | ||
| 310 | ~ECRYPTFS_CONTAINS_DECRYPTED_KEY; | ||
| 311 | (*new_auth_tok)->session_key.flags |= | ||
| 312 | ECRYPTFS_CONTAINS_ENCRYPTED_KEY; | ||
| 313 | (*new_auth_tok)->token.password.hash_algo = 0x01; | ||
| 314 | break; | ||
| 315 | default: | ||
| 316 | ecryptfs_printk(KERN_ERR, "Unsupported hash algorithm: " | ||
| 317 | "[%d]\n", data[(*packet_size) - 1]); | ||
| 318 | rc = -ENOSYS; | ||
| 319 | goto out_free; | ||
| 320 | } | ||
| 321 | (*new_auth_tok)->token_type = ECRYPTFS_PASSWORD; | ||
| 322 | /* TODO: Parametarize; we might actually want userspace to | ||
| 323 | * decrypt the session key. */ | ||
| 324 | ECRYPTFS_CLEAR_FLAG((*new_auth_tok)->session_key.flags, | ||
| 325 | ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT); | ||
| 326 | ECRYPTFS_CLEAR_FLAG((*new_auth_tok)->session_key.flags, | ||
| 327 | ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT); | ||
| 328 | list_add(&auth_tok_list_item->list, auth_tok_list); | ||
| 329 | goto out; | ||
| 330 | out_free: | ||
| 331 | (*new_auth_tok) = NULL; | ||
| 332 | memset(auth_tok_list_item, 0, | ||
| 333 | sizeof(struct ecryptfs_auth_tok_list_item)); | ||
| 334 | kmem_cache_free(ecryptfs_auth_tok_list_item_cache, | ||
| 335 | auth_tok_list_item); | ||
| 336 | out: | ||
| 337 | if (rc) | ||
| 338 | (*packet_size) = 0; | ||
| 339 | return rc; | ||
| 340 | } | ||
| 341 | |||
| 342 | /** | ||
| 343 | * parse_tag_11_packet | ||
| 344 | * @data: The raw bytes of the packet | ||
| 345 | * @contents: This function writes the data contents of the literal | ||
| 346 | * packet into this memory location | ||
| 347 | * @max_contents_bytes: The maximum number of bytes that this function | ||
| 348 | * is allowed to write into contents | ||
| 349 | * @tag_11_contents_size: This function writes the size of the parsed | ||
| 350 | * contents into this memory location; zero on | ||
| 351 | * error | ||
| 352 | * @packet_size: This function writes the size of the parsed packet | ||
| 353 | * into this memory location; zero on error | ||
| 354 | * @max_packet_size: maximum number of bytes to parse | ||
| 355 | * | ||
| 356 | * Returns zero on success; non-zero on error. | ||
| 357 | */ | ||
| 358 | static int | ||
| 359 | parse_tag_11_packet(unsigned char *data, unsigned char *contents, | ||
| 360 | size_t max_contents_bytes, size_t *tag_11_contents_size, | ||
| 361 | size_t *packet_size, size_t max_packet_size) | ||
| 362 | { | ||
| 363 | int rc = 0; | ||
| 364 | size_t body_size; | ||
| 365 | size_t length_size; | ||
| 366 | |||
| 367 | (*packet_size) = 0; | ||
| 368 | (*tag_11_contents_size) = 0; | ||
| 369 | |||
| 370 | /* check that: | ||
| 371 | * one byte for the Tag 11 ID flag | ||
| 372 | * two bytes for the Tag 11 length | ||
| 373 | * do not exceed the maximum_packet_size | ||
| 374 | */ | ||
| 375 | if (unlikely((*packet_size) + 3 > max_packet_size)) { | ||
| 376 | ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); | ||
| 377 | rc = -EINVAL; | ||
| 378 | goto out; | ||
| 379 | } | ||
| 380 | |||
| 381 | /* check for Tag 11 identifyer - one byte */ | ||
| 382 | if (data[(*packet_size)++] != ECRYPTFS_TAG_11_PACKET_TYPE) { | ||
| 383 | ecryptfs_printk(KERN_WARNING, | ||
| 384 | "Invalid tag 11 packet format\n"); | ||
| 385 | rc = -EINVAL; | ||
| 386 | goto out; | ||
| 387 | } | ||
| 388 | |||
| 389 | /* get Tag 11 content length - one or two bytes */ | ||
| 390 | rc = parse_packet_length(&data[(*packet_size)], &body_size, | ||
| 391 | &length_size); | ||
| 392 | if (rc) { | ||
| 393 | ecryptfs_printk(KERN_WARNING, | ||
| 394 | "Invalid tag 11 packet format\n"); | ||
| 395 | goto out; | ||
| 396 | } | ||
| 397 | (*packet_size) += length_size; | ||
| 398 | |||
| 399 | if (body_size < 13) { | ||
| 400 | ecryptfs_printk(KERN_WARNING, "Invalid body size ([%d])\n", | ||
| 401 | body_size); | ||
| 402 | rc = -EINVAL; | ||
| 403 | goto out; | ||
| 404 | } | ||
| 405 | /* We have 13 bytes of surrounding packet values */ | ||
| 406 | (*tag_11_contents_size) = (body_size - 13); | ||
| 407 | |||
| 408 | /* now we know the length of the remainting Tag 11 packet size: | ||
| 409 | * 14 fix bytes for: special flag one, special flag two, | ||
| 410 | * 12 skipped bytes | ||
| 411 | * body_size bytes minus the stuff above is the Tag 11 content | ||
| 412 | */ | ||
| 413 | /* FIXME why is the body size one byte smaller than the actual | ||
| 414 | * size of the body? | ||
| 415 | * this seems to be an error here as well as in | ||
| 416 | * write_tag_11_packet() */ | ||
| 417 | if (unlikely((*packet_size) + body_size + 1 > max_packet_size)) { | ||
| 418 | ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); | ||
| 419 | rc = -EINVAL; | ||
| 420 | goto out; | ||
| 421 | } | ||
| 422 | |||
| 423 | /* special flag one - one byte */ | ||
| 424 | if (data[(*packet_size)++] != 0x62) { | ||
| 425 | ecryptfs_printk(KERN_WARNING, "Unrecognizable packet\n"); | ||
| 426 | rc = -EINVAL; | ||
| 427 | goto out; | ||
| 428 | } | ||
| 429 | |||
| 430 | /* special flag two - one byte */ | ||
| 431 | if (data[(*packet_size)++] != 0x08) { | ||
| 432 | ecryptfs_printk(KERN_WARNING, "Unrecognizable packet\n"); | ||
| 433 | rc = -EINVAL; | ||
| 434 | goto out; | ||
| 435 | } | ||
| 436 | |||
| 437 | /* skip the next 12 bytes */ | ||
| 438 | (*packet_size) += 12; /* We don't care about the filename or | ||
| 439 | * the timestamp */ | ||
| 440 | |||
| 441 | /* get the Tag 11 contents - tag_11_contents_size bytes */ | ||
| 442 | memcpy(contents, &data[(*packet_size)], (*tag_11_contents_size)); | ||
| 443 | (*packet_size) += (*tag_11_contents_size); | ||
| 444 | |||
| 445 | out: | ||
| 446 | if (rc) { | ||
| 447 | (*packet_size) = 0; | ||
| 448 | (*tag_11_contents_size) = 0; | ||
| 449 | } | ||
| 450 | return rc; | ||
| 451 | } | ||
| 452 | |||
| 453 | /** | ||
| 454 | * decrypt_session_key - Decrypt the session key with the given auth_tok. | ||
| 455 | * | ||
| 456 | * Returns Zero on success; non-zero error otherwise. | ||
| 457 | */ | ||
| 458 | static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | ||
| 459 | struct ecryptfs_crypt_stat *crypt_stat) | ||
| 460 | { | ||
| 461 | int rc = 0; | ||
| 462 | struct ecryptfs_password *password_s_ptr; | ||
| 463 | struct crypto_tfm *tfm = NULL; | ||
| 464 | struct scatterlist src_sg[2], dst_sg[2]; | ||
| 465 | struct mutex *tfm_mutex = NULL; | ||
| 466 | /* TODO: Use virt_to_scatterlist for these */ | ||
| 467 | char *encrypted_session_key; | ||
| 468 | char *session_key; | ||
| 469 | |||
| 470 | password_s_ptr = &auth_tok->token.password; | ||
| 471 | if (ECRYPTFS_CHECK_FLAG(password_s_ptr->flags, | ||
| 472 | ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET)) | ||
| 473 | ecryptfs_printk(KERN_DEBUG, "Session key encryption key " | ||
| 474 | "set; skipping key generation\n"); | ||
| 475 | ecryptfs_printk(KERN_DEBUG, "Session key encryption key (size [%d])" | ||
| 476 | ":\n", | ||
| 477 | password_s_ptr->session_key_encryption_key_bytes); | ||
| 478 | if (ecryptfs_verbosity > 0) | ||
| 479 | ecryptfs_dump_hex(password_s_ptr->session_key_encryption_key, | ||
| 480 | password_s_ptr-> | ||
| 481 | session_key_encryption_key_bytes); | ||
| 482 | if (!strcmp(crypt_stat->cipher, | ||
| 483 | crypt_stat->mount_crypt_stat->global_default_cipher_name) | ||
| 484 | && crypt_stat->mount_crypt_stat->global_key_tfm) { | ||
| 485 | tfm = crypt_stat->mount_crypt_stat->global_key_tfm; | ||
| 486 | tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex; | ||
| 487 | } else { | ||
| 488 | tfm = crypto_alloc_tfm(crypt_stat->cipher, | ||
| 489 | CRYPTO_TFM_REQ_WEAK_KEY); | ||
| 490 | if (!tfm) { | ||
| 491 | printk(KERN_ERR "Error allocating crypto context\n"); | ||
| 492 | rc = -ENOMEM; | ||
| 493 | goto out; | ||
| 494 | } | ||
| 495 | } | ||
| 496 | if (password_s_ptr->session_key_encryption_key_bytes | ||
| 497 | < crypto_tfm_alg_min_keysize(tfm)) { | ||
| 498 | printk(KERN_WARNING "Session key encryption key is [%d] bytes; " | ||
| 499 | "minimum keysize for selected cipher is [%d] bytes.\n", | ||
| 500 | password_s_ptr->session_key_encryption_key_bytes, | ||
| 501 | crypto_tfm_alg_min_keysize(tfm)); | ||
| 502 | rc = -EINVAL; | ||
| 503 | goto out; | ||
| 504 | } | ||
| 505 | if (tfm_mutex) | ||
| 506 | mutex_lock(tfm_mutex); | ||
| 507 | crypto_cipher_setkey(tfm, password_s_ptr->session_key_encryption_key, | ||
| 508 | crypt_stat->key_size); | ||
| 509 | /* TODO: virt_to_scatterlist */ | ||
| 510 | encrypted_session_key = (char *)__get_free_page(GFP_KERNEL); | ||
| 511 | if (!encrypted_session_key) { | ||
| 512 | ecryptfs_printk(KERN_ERR, "Out of memory\n"); | ||
| 513 | rc = -ENOMEM; | ||
| 514 | goto out_free_tfm; | ||
| 515 | } | ||
| 516 | session_key = (char *)__get_free_page(GFP_KERNEL); | ||
| 517 | if (!session_key) { | ||
| 518 | kfree(encrypted_session_key); | ||
| 519 | ecryptfs_printk(KERN_ERR, "Out of memory\n"); | ||
| 520 | rc = -ENOMEM; | ||
| 521 | goto out_free_tfm; | ||
| 522 | } | ||
| 523 | memcpy(encrypted_session_key, auth_tok->session_key.encrypted_key, | ||
| 524 | auth_tok->session_key.encrypted_key_size); | ||
| 525 | src_sg[0].page = virt_to_page(encrypted_session_key); | ||
| 526 | src_sg[0].offset = 0; | ||
| 527 | BUG_ON(auth_tok->session_key.encrypted_key_size > PAGE_CACHE_SIZE); | ||
| 528 | src_sg[0].length = auth_tok->session_key.encrypted_key_size; | ||
| 529 | dst_sg[0].page = virt_to_page(session_key); | ||
| 530 | dst_sg[0].offset = 0; | ||
| 531 | auth_tok->session_key.decrypted_key_size = | ||
| 532 | auth_tok->session_key.encrypted_key_size; | ||
| 533 | dst_sg[0].length = auth_tok->session_key.encrypted_key_size; | ||
| 534 | /* TODO: Handle error condition */ | ||
| 535 | crypto_cipher_decrypt(tfm, dst_sg, src_sg, | ||
| 536 | auth_tok->session_key.encrypted_key_size); | ||
| 537 | auth_tok->session_key.decrypted_key_size = | ||
| 538 | auth_tok->session_key.encrypted_key_size; | ||
| 539 | memcpy(auth_tok->session_key.decrypted_key, session_key, | ||
| 540 | auth_tok->session_key.decrypted_key_size); | ||
| 541 | auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY; | ||
| 542 | memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key, | ||
| 543 | auth_tok->session_key.decrypted_key_size); | ||
| 544 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID); | ||
| 545 | ecryptfs_printk(KERN_DEBUG, "Decrypted session key:\n"); | ||
| 546 | if (ecryptfs_verbosity > 0) | ||
| 547 | ecryptfs_dump_hex(crypt_stat->key, | ||
| 548 | crypt_stat->key_size); | ||
| 549 | memset(encrypted_session_key, 0, PAGE_CACHE_SIZE); | ||
| 550 | free_page((unsigned long)encrypted_session_key); | ||
| 551 | memset(session_key, 0, PAGE_CACHE_SIZE); | ||
| 552 | free_page((unsigned long)session_key); | ||
| 553 | out_free_tfm: | ||
| 554 | if (tfm_mutex) | ||
| 555 | mutex_unlock(tfm_mutex); | ||
| 556 | else | ||
| 557 | crypto_free_tfm(tfm); | ||
| 558 | out: | ||
| 559 | return rc; | ||
| 560 | } | ||
| 561 | |||
| 562 | /** | ||
| 563 | * ecryptfs_parse_packet_set | ||
| 564 | * @dest: The header page in memory | ||
| 565 | * @version: Version of file format, to guide parsing behavior | ||
| 566 | * | ||
| 567 | * Get crypt_stat to have the file's session key if the requisite key | ||
| 568 | * is available to decrypt the session key. | ||
| 569 | * | ||
| 570 | * Returns Zero if a valid authentication token was retrieved and | ||
| 571 | * processed; negative value for file not encrypted or for error | ||
| 572 | * conditions. | ||
| 573 | */ | ||
| 574 | int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | ||
| 575 | unsigned char *src, | ||
| 576 | struct dentry *ecryptfs_dentry) | ||
| 577 | { | ||
| 578 | size_t i = 0; | ||
| 579 | int rc = 0; | ||
| 580 | size_t found_auth_tok = 0; | ||
| 581 | size_t next_packet_is_auth_tok_packet; | ||
| 582 | char sig[ECRYPTFS_SIG_SIZE_HEX]; | ||
| 583 | struct list_head auth_tok_list; | ||
| 584 | struct list_head *walker; | ||
| 585 | struct ecryptfs_auth_tok *chosen_auth_tok = NULL; | ||
| 586 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | ||
| 587 | &ecryptfs_superblock_to_private( | ||
| 588 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | ||
| 589 | struct ecryptfs_auth_tok *candidate_auth_tok = NULL; | ||
| 590 | size_t packet_size; | ||
| 591 | struct ecryptfs_auth_tok *new_auth_tok; | ||
| 592 | unsigned char sig_tmp_space[ECRYPTFS_SIG_SIZE]; | ||
| 593 | size_t tag_11_contents_size; | ||
| 594 | size_t tag_11_packet_size; | ||
| 595 | |||
| 596 | INIT_LIST_HEAD(&auth_tok_list); | ||
| 597 | /* Parse the header to find as many packets as we can, these will be | ||
| 598 | * added the our &auth_tok_list */ | ||
| 599 | next_packet_is_auth_tok_packet = 1; | ||
| 600 | while (next_packet_is_auth_tok_packet) { | ||
| 601 | size_t max_packet_size = ((PAGE_CACHE_SIZE - 8) - i); | ||
| 602 | |||
| 603 | switch (src[i]) { | ||
| 604 | case ECRYPTFS_TAG_3_PACKET_TYPE: | ||
| 605 | rc = parse_tag_3_packet(crypt_stat, | ||
| 606 | (unsigned char *)&src[i], | ||
| 607 | &auth_tok_list, &new_auth_tok, | ||
| 608 | &packet_size, max_packet_size); | ||
| 609 | if (rc) { | ||
| 610 | ecryptfs_printk(KERN_ERR, "Error parsing " | ||
| 611 | "tag 3 packet\n"); | ||
| 612 | rc = -EIO; | ||
| 613 | goto out_wipe_list; | ||
| 614 | } | ||
| 615 | i += packet_size; | ||
| 616 | rc = parse_tag_11_packet((unsigned char *)&src[i], | ||
| 617 | sig_tmp_space, | ||
| 618 | ECRYPTFS_SIG_SIZE, | ||
| 619 | &tag_11_contents_size, | ||
| 620 | &tag_11_packet_size, | ||
| 621 | max_packet_size); | ||
| 622 | if (rc) { | ||
| 623 | ecryptfs_printk(KERN_ERR, "No valid " | ||
| 624 | "(ecryptfs-specific) literal " | ||
| 625 | "packet containing " | ||
| 626 | "authentication token " | ||
| 627 | "signature found after " | ||
| 628 | "tag 3 packet\n"); | ||
| 629 | rc = -EIO; | ||
| 630 | goto out_wipe_list; | ||
| 631 | } | ||
| 632 | i += tag_11_packet_size; | ||
| 633 | if (ECRYPTFS_SIG_SIZE != tag_11_contents_size) { | ||
| 634 | ecryptfs_printk(KERN_ERR, "Expected " | ||
| 635 | "signature of size [%d]; " | ||
| 636 | "read size [%d]\n", | ||
| 637 | ECRYPTFS_SIG_SIZE, | ||
| 638 | tag_11_contents_size); | ||
| 639 | rc = -EIO; | ||
| 640 | goto out_wipe_list; | ||
| 641 | } | ||
| 642 | ecryptfs_to_hex(new_auth_tok->token.password.signature, | ||
| 643 | sig_tmp_space, tag_11_contents_size); | ||
| 644 | new_auth_tok->token.password.signature[ | ||
| 645 | ECRYPTFS_PASSWORD_SIG_SIZE] = '\0'; | ||
| 646 | ECRYPTFS_SET_FLAG(crypt_stat->flags, | ||
| 647 | ECRYPTFS_ENCRYPTED); | ||
| 648 | break; | ||
| 649 | case ECRYPTFS_TAG_11_PACKET_TYPE: | ||
| 650 | ecryptfs_printk(KERN_WARNING, "Invalid packet set " | ||
| 651 | "(Tag 11 not allowed by itself)\n"); | ||
| 652 | rc = -EIO; | ||
| 653 | goto out_wipe_list; | ||
| 654 | break; | ||
| 655 | default: | ||
| 656 | ecryptfs_printk(KERN_DEBUG, "No packet at offset " | ||
| 657 | "[%d] of the file header; hex value of " | ||
| 658 | "character is [0x%.2x]\n", i, src[i]); | ||
| 659 | next_packet_is_auth_tok_packet = 0; | ||
| 660 | } | ||
| 661 | } | ||
| 662 | if (list_empty(&auth_tok_list)) { | ||
| 663 | rc = -EINVAL; /* Do not support non-encrypted files in | ||
| 664 | * the 0.1 release */ | ||
| 665 | goto out; | ||
| 666 | } | ||
| 667 | /* If we have a global auth tok, then we should try to use | ||
| 668 | * it */ | ||
| 669 | if (mount_crypt_stat->global_auth_tok) { | ||
| 670 | memcpy(sig, mount_crypt_stat->global_auth_tok_sig, | ||
| 671 | ECRYPTFS_SIG_SIZE_HEX); | ||
| 672 | chosen_auth_tok = mount_crypt_stat->global_auth_tok; | ||
| 673 | } else | ||
| 674 | BUG(); /* We should always have a global auth tok in | ||
| 675 | * the 0.1 release */ | ||
| 676 | /* Scan list to see if our chosen_auth_tok works */ | ||
| 677 | list_for_each(walker, &auth_tok_list) { | ||
| 678 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | ||
| 679 | auth_tok_list_item = | ||
| 680 | list_entry(walker, struct ecryptfs_auth_tok_list_item, | ||
| 681 | list); | ||
| 682 | candidate_auth_tok = &auth_tok_list_item->auth_tok; | ||
| 683 | if (unlikely(ecryptfs_verbosity > 0)) { | ||
| 684 | ecryptfs_printk(KERN_DEBUG, | ||
| 685 | "Considering cadidate auth tok:\n"); | ||
| 686 | ecryptfs_dump_auth_tok(candidate_auth_tok); | ||
| 687 | } | ||
| 688 | /* TODO: Replace ECRYPTFS_SIG_SIZE_HEX w/ dynamic value */ | ||
| 689 | if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD | ||
| 690 | && !strncmp(candidate_auth_tok->token.password.signature, | ||
| 691 | sig, ECRYPTFS_SIG_SIZE_HEX)) { | ||
| 692 | found_auth_tok = 1; | ||
| 693 | goto leave_list; | ||
| 694 | /* TODO: Transfer the common salt into the | ||
| 695 | * crypt_stat salt */ | ||
| 696 | } | ||
| 697 | } | ||
| 698 | leave_list: | ||
| 699 | if (!found_auth_tok) { | ||
| 700 | ecryptfs_printk(KERN_ERR, "Could not find authentication " | ||
| 701 | "token on temporary list for sig [%.*s]\n", | ||
| 702 | ECRYPTFS_SIG_SIZE_HEX, sig); | ||
| 703 | rc = -EIO; | ||
| 704 | goto out_wipe_list; | ||
| 705 | } else { | ||
| 706 | memcpy(&(candidate_auth_tok->token.password), | ||
| 707 | &(chosen_auth_tok->token.password), | ||
| 708 | sizeof(struct ecryptfs_password)); | ||
| 709 | rc = decrypt_session_key(candidate_auth_tok, crypt_stat); | ||
| 710 | if (rc) { | ||
| 711 | ecryptfs_printk(KERN_ERR, "Error decrypting the " | ||
| 712 | "session key\n"); | ||
| 713 | goto out_wipe_list; | ||
| 714 | } | ||
| 715 | rc = ecryptfs_compute_root_iv(crypt_stat); | ||
| 716 | if (rc) { | ||
| 717 | ecryptfs_printk(KERN_ERR, "Error computing " | ||
| 718 | "the root IV\n"); | ||
| 719 | goto out_wipe_list; | ||
| 720 | } | ||
| 721 | } | ||
| 722 | rc = ecryptfs_init_crypt_ctx(crypt_stat); | ||
| 723 | if (rc) { | ||
| 724 | ecryptfs_printk(KERN_ERR, "Error initializing crypto " | ||
| 725 | "context for cipher [%s]; rc = [%d]\n", | ||
| 726 | crypt_stat->cipher, rc); | ||
| 727 | } | ||
| 728 | out_wipe_list: | ||
| 729 | wipe_auth_tok_list(&auth_tok_list); | ||
| 730 | out: | ||
| 731 | return rc; | ||
| 732 | } | ||
| 733 | |||
| 734 | /** | ||
| 735 | * write_tag_11_packet | ||
| 736 | * @dest: Target into which Tag 11 packet is to be written | ||
| 737 | * @max: Maximum packet length | ||
| 738 | * @contents: Byte array of contents to copy in | ||
| 739 | * @contents_length: Number of bytes in contents | ||
| 740 | * @packet_length: Length of the Tag 11 packet written; zero on error | ||
| 741 | * | ||
| 742 | * Returns zero on success; non-zero on error. | ||
| 743 | */ | ||
| 744 | static int | ||
| 745 | write_tag_11_packet(char *dest, int max, char *contents, size_t contents_length, | ||
| 746 | size_t *packet_length) | ||
| 747 | { | ||
| 748 | int rc = 0; | ||
| 749 | size_t packet_size_length; | ||
| 750 | |||
| 751 | (*packet_length) = 0; | ||
| 752 | if ((13 + contents_length) > max) { | ||
| 753 | rc = -EINVAL; | ||
| 754 | ecryptfs_printk(KERN_ERR, "Packet length larger than " | ||
| 755 | "maximum allowable\n"); | ||
| 756 | goto out; | ||
| 757 | } | ||
| 758 | /* General packet header */ | ||
| 759 | /* Packet tag */ | ||
| 760 | dest[(*packet_length)++] = ECRYPTFS_TAG_11_PACKET_TYPE; | ||
| 761 | /* Packet length */ | ||
| 762 | rc = write_packet_length(&dest[(*packet_length)], | ||
| 763 | (13 + contents_length), &packet_size_length); | ||
| 764 | if (rc) { | ||
| 765 | ecryptfs_printk(KERN_ERR, "Error generating tag 11 packet " | ||
| 766 | "header; cannot generate packet length\n"); | ||
| 767 | goto out; | ||
| 768 | } | ||
| 769 | (*packet_length) += packet_size_length; | ||
| 770 | /* Tag 11 specific */ | ||
| 771 | /* One-octet field that describes how the data is formatted */ | ||
| 772 | dest[(*packet_length)++] = 0x62; /* binary data */ | ||
| 773 | /* One-octet filename length followed by filename */ | ||
| 774 | dest[(*packet_length)++] = 8; | ||
| 775 | memcpy(&dest[(*packet_length)], "_CONSOLE", 8); | ||
| 776 | (*packet_length) += 8; | ||
| 777 | /* Four-octet number indicating modification date */ | ||
| 778 | memset(&dest[(*packet_length)], 0x00, 4); | ||
| 779 | (*packet_length) += 4; | ||
| 780 | /* Remainder is literal data */ | ||
| 781 | memcpy(&dest[(*packet_length)], contents, contents_length); | ||
| 782 | (*packet_length) += contents_length; | ||
| 783 | out: | ||
| 784 | if (rc) | ||
| 785 | (*packet_length) = 0; | ||
| 786 | return rc; | ||
| 787 | } | ||
| 788 | |||
| 789 | /** | ||
| 790 | * write_tag_3_packet | ||
| 791 | * @dest: Buffer into which to write the packet | ||
| 792 | * @max: Maximum number of bytes that can be written | ||
| 793 | * @auth_tok: Authentication token | ||
| 794 | * @crypt_stat: The cryptographic context | ||
| 795 | * @key_rec: encrypted key | ||
| 796 | * @packet_size: This function will write the number of bytes that end | ||
| 797 | * up constituting the packet; set to zero on error | ||
| 798 | * | ||
| 799 | * Returns zero on success; non-zero on error. | ||
| 800 | */ | ||
| 801 | static int | ||
| 802 | write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | ||
| 803 | struct ecryptfs_crypt_stat *crypt_stat, | ||
| 804 | struct ecryptfs_key_record *key_rec, size_t *packet_size) | ||
| 805 | { | ||
| 806 | int rc = 0; | ||
| 807 | |||
| 808 | size_t i; | ||
| 809 | size_t signature_is_valid = 0; | ||
| 810 | size_t encrypted_session_key_valid = 0; | ||
| 811 | char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; | ||
| 812 | struct scatterlist dest_sg[2]; | ||
| 813 | struct scatterlist src_sg[2]; | ||
| 814 | struct crypto_tfm *tfm = NULL; | ||
| 815 | struct mutex *tfm_mutex = NULL; | ||
| 816 | size_t key_rec_size; | ||
| 817 | size_t packet_size_length; | ||
| 818 | size_t cipher_code; | ||
| 819 | |||
| 820 | (*packet_size) = 0; | ||
| 821 | /* Check for a valid signature on the auth_tok */ | ||
| 822 | for (i = 0; i < ECRYPTFS_SIG_SIZE_HEX; i++) | ||
| 823 | signature_is_valid |= auth_tok->token.password.signature[i]; | ||
| 824 | if (!signature_is_valid) | ||
| 825 | BUG(); | ||
| 826 | ecryptfs_from_hex((*key_rec).sig, auth_tok->token.password.signature, | ||
| 827 | ECRYPTFS_SIG_SIZE); | ||
| 828 | encrypted_session_key_valid = 0; | ||
| 829 | for (i = 0; i < crypt_stat->key_size; i++) | ||
| 830 | encrypted_session_key_valid |= | ||
| 831 | auth_tok->session_key.encrypted_key[i]; | ||
| 832 | if (encrypted_session_key_valid) { | ||
| 833 | memcpy((*key_rec).enc_key, | ||
| 834 | auth_tok->session_key.encrypted_key, | ||
| 835 | auth_tok->session_key.encrypted_key_size); | ||
| 836 | goto encrypted_session_key_set; | ||
| 837 | } | ||
| 838 | if (auth_tok->session_key.encrypted_key_size == 0) | ||
| 839 | auth_tok->session_key.encrypted_key_size = | ||
| 840 | crypt_stat->key_size; | ||
| 841 | if (crypt_stat->key_size == 24 | ||
| 842 | && strcmp("aes", crypt_stat->cipher) == 0) { | ||
| 843 | memset((crypt_stat->key + 24), 0, 8); | ||
| 844 | auth_tok->session_key.encrypted_key_size = 32; | ||
| 845 | } | ||
| 846 | (*key_rec).enc_key_size = | ||
| 847 | auth_tok->session_key.encrypted_key_size; | ||
| 848 | if (ECRYPTFS_CHECK_FLAG(auth_tok->token.password.flags, | ||
| 849 | ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET)) { | ||
| 850 | ecryptfs_printk(KERN_DEBUG, "Using previously generated " | ||
| 851 | "session key encryption key of size [%d]\n", | ||
| 852 | auth_tok->token.password. | ||
| 853 | session_key_encryption_key_bytes); | ||
| 854 | memcpy(session_key_encryption_key, | ||
| 855 | auth_tok->token.password.session_key_encryption_key, | ||
| 856 | crypt_stat->key_size); | ||
| 857 | ecryptfs_printk(KERN_DEBUG, | ||
| 858 | "Cached session key " "encryption key: \n"); | ||
| 859 | if (ecryptfs_verbosity > 0) | ||
| 860 | ecryptfs_dump_hex(session_key_encryption_key, 16); | ||
| 861 | } | ||
| 862 | if (unlikely(ecryptfs_verbosity > 0)) { | ||
| 863 | ecryptfs_printk(KERN_DEBUG, "Session key encryption key:\n"); | ||
| 864 | ecryptfs_dump_hex(session_key_encryption_key, 16); | ||
| 865 | } | ||
| 866 | rc = virt_to_scatterlist(crypt_stat->key, | ||
| 867 | (*key_rec).enc_key_size, src_sg, 2); | ||
| 868 | if (!rc) { | ||
| 869 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " | ||
| 870 | "for crypt_stat session key\n"); | ||
| 871 | rc = -ENOMEM; | ||
| 872 | goto out; | ||
| 873 | } | ||
| 874 | rc = virt_to_scatterlist((*key_rec).enc_key, | ||
| 875 | (*key_rec).enc_key_size, dest_sg, 2); | ||
| 876 | if (!rc) { | ||
| 877 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " | ||
| 878 | "for crypt_stat encrypted session key\n"); | ||
| 879 | rc = -ENOMEM; | ||
| 880 | goto out; | ||
| 881 | } | ||
| 882 | if (!strcmp(crypt_stat->cipher, | ||
| 883 | crypt_stat->mount_crypt_stat->global_default_cipher_name) | ||
| 884 | && crypt_stat->mount_crypt_stat->global_key_tfm) { | ||
| 885 | tfm = crypt_stat->mount_crypt_stat->global_key_tfm; | ||
| 886 | tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex; | ||
| 887 | } else | ||
| 888 | tfm = crypto_alloc_tfm(crypt_stat->cipher, 0); | ||
| 889 | if (!tfm) { | ||
| 890 | ecryptfs_printk(KERN_ERR, "Could not initialize crypto " | ||
| 891 | "context for cipher [%s]\n", | ||
| 892 | crypt_stat->cipher); | ||
| 893 | rc = -EINVAL; | ||
| 894 | goto out; | ||
| 895 | } | ||
| 896 | if (tfm_mutex) | ||
| 897 | mutex_lock(tfm_mutex); | ||
| 898 | rc = crypto_cipher_setkey(tfm, session_key_encryption_key, | ||
| 899 | crypt_stat->key_size); | ||
| 900 | if (rc < 0) { | ||
| 901 | if (tfm_mutex) | ||
| 902 | mutex_unlock(tfm_mutex); | ||
| 903 | ecryptfs_printk(KERN_ERR, "Error setting key for crypto " | ||
| 904 | "context\n"); | ||
| 905 | goto out; | ||
| 906 | } | ||
| 907 | rc = 0; | ||
| 908 | ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n", | ||
| 909 | crypt_stat->key_size); | ||
| 910 | crypto_cipher_encrypt(tfm, dest_sg, src_sg, | ||
| 911 | (*key_rec).enc_key_size); | ||
| 912 | if (tfm_mutex) | ||
| 913 | mutex_unlock(tfm_mutex); | ||
| 914 | ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); | ||
| 915 | if (ecryptfs_verbosity > 0) | ||
| 916 | ecryptfs_dump_hex((*key_rec).enc_key, | ||
| 917 | (*key_rec).enc_key_size); | ||
| 918 | encrypted_session_key_set: | ||
| 919 | /* Now we have a valid key_rec. Append it to the | ||
| 920 | * key_rec set. */ | ||
| 921 | key_rec_size = (sizeof(struct ecryptfs_key_record) | ||
| 922 | - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES | ||
| 923 | + ((*key_rec).enc_key_size)); | ||
| 924 | /* TODO: Include a packet size limit as a parameter to this | ||
| 925 | * function once we have multi-packet headers (for versions | ||
| 926 | * later than 0.1 */ | ||
| 927 | if (key_rec_size >= ECRYPTFS_MAX_KEYSET_SIZE) { | ||
| 928 | ecryptfs_printk(KERN_ERR, "Keyset too large\n"); | ||
| 929 | rc = -EINVAL; | ||
| 930 | goto out; | ||
| 931 | } | ||
| 932 | /* TODO: Packet size limit */ | ||
| 933 | /* We have 5 bytes of surrounding packet data */ | ||
| 934 | if ((0x05 + ECRYPTFS_SALT_SIZE | ||
| 935 | + (*key_rec).enc_key_size) >= max) { | ||
| 936 | ecryptfs_printk(KERN_ERR, "Authentication token is too " | ||
| 937 | "large\n"); | ||
| 938 | rc = -EINVAL; | ||
| 939 | goto out; | ||
| 940 | } | ||
| 941 | /* This format is inspired by OpenPGP; see RFC 2440 | ||
| 942 | * packet tag 3 */ | ||
| 943 | dest[(*packet_size)++] = ECRYPTFS_TAG_3_PACKET_TYPE; | ||
| 944 | /* ver+cipher+s2k+hash+salt+iter+enc_key */ | ||
| 945 | rc = write_packet_length(&dest[(*packet_size)], | ||
| 946 | (0x05 + ECRYPTFS_SALT_SIZE | ||
| 947 | + (*key_rec).enc_key_size), | ||
| 948 | &packet_size_length); | ||
| 949 | if (rc) { | ||
| 950 | ecryptfs_printk(KERN_ERR, "Error generating tag 3 packet " | ||
| 951 | "header; cannot generate packet length\n"); | ||
| 952 | goto out; | ||
| 953 | } | ||
| 954 | (*packet_size) += packet_size_length; | ||
| 955 | dest[(*packet_size)++] = 0x04; /* version 4 */ | ||
| 956 | cipher_code = ecryptfs_code_for_cipher_string(crypt_stat); | ||
| 957 | if (cipher_code == 0) { | ||
| 958 | ecryptfs_printk(KERN_WARNING, "Unable to generate code for " | ||
| 959 | "cipher [%s]\n", crypt_stat->cipher); | ||
| 960 | rc = -EINVAL; | ||
| 961 | goto out; | ||
| 962 | } | ||
| 963 | dest[(*packet_size)++] = cipher_code; | ||
| 964 | dest[(*packet_size)++] = 0x03; /* S2K */ | ||
| 965 | dest[(*packet_size)++] = 0x01; /* MD5 (TODO: parameterize) */ | ||
| 966 | memcpy(&dest[(*packet_size)], auth_tok->token.password.salt, | ||
| 967 | ECRYPTFS_SALT_SIZE); | ||
| 968 | (*packet_size) += ECRYPTFS_SALT_SIZE; /* salt */ | ||
| 969 | dest[(*packet_size)++] = 0x60; /* hash iterations (65536) */ | ||
| 970 | memcpy(&dest[(*packet_size)], (*key_rec).enc_key, | ||
| 971 | (*key_rec).enc_key_size); | ||
| 972 | (*packet_size) += (*key_rec).enc_key_size; | ||
| 973 | out: | ||
| 974 | if (tfm && !tfm_mutex) | ||
| 975 | crypto_free_tfm(tfm); | ||
| 976 | if (rc) | ||
| 977 | (*packet_size) = 0; | ||
| 978 | return rc; | ||
| 979 | } | ||
| 980 | |||
| 981 | /** | ||
| 982 | * ecryptfs_generate_key_packet_set | ||
| 983 | * @dest: Virtual address from which to write the key record set | ||
| 984 | * @crypt_stat: The cryptographic context from which the | ||
| 985 | * authentication tokens will be retrieved | ||
| 986 | * @ecryptfs_dentry: The dentry, used to retrieve the mount crypt stat | ||
| 987 | * for the global parameters | ||
| 988 | * @len: The amount written | ||
| 989 | * @max: The maximum amount of data allowed to be written | ||
| 990 | * | ||
| 991 | * Generates a key packet set and writes it to the virtual address | ||
| 992 | * passed in. | ||
| 993 | * | ||
| 994 | * Returns zero on success; non-zero on error. | ||
| 995 | */ | ||
| 996 | int | ||
| 997 | ecryptfs_generate_key_packet_set(char *dest_base, | ||
| 998 | struct ecryptfs_crypt_stat *crypt_stat, | ||
| 999 | struct dentry *ecryptfs_dentry, size_t *len, | ||
| 1000 | size_t max) | ||
| 1001 | { | ||
| 1002 | int rc = 0; | ||
| 1003 | struct ecryptfs_auth_tok *auth_tok; | ||
| 1004 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | ||
| 1005 | &ecryptfs_superblock_to_private( | ||
| 1006 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | ||
| 1007 | size_t written; | ||
| 1008 | struct ecryptfs_key_record key_rec; | ||
| 1009 | |||
| 1010 | (*len) = 0; | ||
| 1011 | if (mount_crypt_stat->global_auth_tok) { | ||
| 1012 | auth_tok = mount_crypt_stat->global_auth_tok; | ||
| 1013 | if (auth_tok->token_type == ECRYPTFS_PASSWORD) { | ||
| 1014 | rc = write_tag_3_packet((dest_base + (*len)), | ||
| 1015 | max, auth_tok, | ||
| 1016 | crypt_stat, &key_rec, | ||
| 1017 | &written); | ||
| 1018 | if (rc) { | ||
| 1019 | ecryptfs_printk(KERN_WARNING, "Error " | ||
| 1020 | "writing tag 3 packet\n"); | ||
| 1021 | goto out; | ||
| 1022 | } | ||
| 1023 | (*len) += written; | ||
| 1024 | /* Write auth tok signature packet */ | ||
| 1025 | rc = write_tag_11_packet( | ||
| 1026 | (dest_base + (*len)), | ||
| 1027 | (max - (*len)), | ||
| 1028 | key_rec.sig, ECRYPTFS_SIG_SIZE, &written); | ||
| 1029 | if (rc) { | ||
| 1030 | ecryptfs_printk(KERN_ERR, "Error writing " | ||
| 1031 | "auth tok signature packet\n"); | ||
| 1032 | goto out; | ||
| 1033 | } | ||
| 1034 | (*len) += written; | ||
| 1035 | } else { | ||
| 1036 | ecryptfs_printk(KERN_WARNING, "Unsupported " | ||
| 1037 | "authentication token type\n"); | ||
| 1038 | rc = -EINVAL; | ||
| 1039 | goto out; | ||
| 1040 | } | ||
| 1041 | if (rc) { | ||
| 1042 | ecryptfs_printk(KERN_WARNING, "Error writing " | ||
| 1043 | "authentication token packet with sig " | ||
| 1044 | "= [%s]\n", | ||
| 1045 | mount_crypt_stat->global_auth_tok_sig); | ||
| 1046 | rc = -EIO; | ||
| 1047 | goto out; | ||
| 1048 | } | ||
| 1049 | } else | ||
| 1050 | BUG(); | ||
| 1051 | if (likely((max - (*len)) > 0)) { | ||
| 1052 | dest_base[(*len)] = 0x00; | ||
| 1053 | } else { | ||
| 1054 | ecryptfs_printk(KERN_ERR, "Error writing boundary byte\n"); | ||
| 1055 | rc = -EIO; | ||
| 1056 | } | ||
| 1057 | out: | ||
| 1058 | if (rc) | ||
| 1059 | (*len) = 0; | ||
| 1060 | return rc; | ||
| 1061 | } | ||
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c new file mode 100644 index 000000000000..7a11b8ae6644 --- /dev/null +++ b/fs/ecryptfs/main.c | |||
| @@ -0,0 +1,831 @@ | |||
| 1 | /** | ||
| 2 | * eCryptfs: Linux filesystem encryption layer | ||
| 3 | * | ||
| 4 | * Copyright (C) 1997-2003 Erez Zadok | ||
| 5 | * Copyright (C) 2001-2003 Stony Brook University | ||
| 6 | * Copyright (C) 2004-2006 International Business Machines Corp. | ||
| 7 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> | ||
| 8 | * Michael C. Thompson <mcthomps@us.ibm.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or | ||
| 11 | * modify it under the terms of the GNU General Public License as | ||
| 12 | * published by the Free Software Foundation; either version 2 of the | ||
| 13 | * License, or (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, but | ||
| 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 18 | * General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
| 23 | * 02111-1307, USA. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <linux/dcache.h> | ||
| 27 | #include <linux/file.h> | ||
| 28 | #include <linux/module.h> | ||
| 29 | #include <linux/namei.h> | ||
| 30 | #include <linux/skbuff.h> | ||
| 31 | #include <linux/crypto.h> | ||
| 32 | #include <linux/netlink.h> | ||
| 33 | #include <linux/mount.h> | ||
| 34 | #include <linux/dcache.h> | ||
| 35 | #include <linux/pagemap.h> | ||
| 36 | #include <linux/key.h> | ||
| 37 | #include <linux/parser.h> | ||
| 38 | #include "ecryptfs_kernel.h" | ||
| 39 | |||
| 40 | /** | ||
| 41 | * Module parameter that defines the ecryptfs_verbosity level. | ||
| 42 | */ | ||
| 43 | int ecryptfs_verbosity = 0; | ||
| 44 | |||
| 45 | module_param(ecryptfs_verbosity, int, 0); | ||
| 46 | MODULE_PARM_DESC(ecryptfs_verbosity, | ||
| 47 | "Initial verbosity level (0 or 1; defaults to " | ||
| 48 | "0, which is Quiet)"); | ||
| 49 | |||
| 50 | void __ecryptfs_printk(const char *fmt, ...) | ||
| 51 | { | ||
| 52 | va_list args; | ||
| 53 | va_start(args, fmt); | ||
| 54 | if (fmt[1] == '7') { /* KERN_DEBUG */ | ||
| 55 | if (ecryptfs_verbosity >= 1) | ||
| 56 | vprintk(fmt, args); | ||
| 57 | } else | ||
| 58 | vprintk(fmt, args); | ||
| 59 | va_end(args); | ||
| 60 | } | ||
| 61 | |||
| 62 | /** | ||
| 63 | * ecryptfs_interpose | ||
| 64 | * @lower_dentry: Existing dentry in the lower filesystem | ||
| 65 | * @dentry: ecryptfs' dentry | ||
| 66 | * @sb: ecryptfs's super_block | ||
| 67 | * @flag: If set to true, then d_add is called, else d_instantiate is called | ||
| 68 | * | ||
| 69 | * Interposes upper and lower dentries. | ||
| 70 | * | ||
| 71 | * Returns zero on success; non-zero otherwise | ||
| 72 | */ | ||
| 73 | int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, | ||
| 74 | struct super_block *sb, int flag) | ||
| 75 | { | ||
| 76 | struct inode *lower_inode; | ||
| 77 | struct inode *inode; | ||
| 78 | int rc = 0; | ||
| 79 | |||
| 80 | lower_inode = lower_dentry->d_inode; | ||
| 81 | if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb)) { | ||
| 82 | rc = -EXDEV; | ||
| 83 | goto out; | ||
| 84 | } | ||
| 85 | if (!igrab(lower_inode)) { | ||
| 86 | rc = -ESTALE; | ||
| 87 | goto out; | ||
| 88 | } | ||
| 89 | inode = iget5_locked(sb, (unsigned long)lower_inode, | ||
| 90 | ecryptfs_inode_test, ecryptfs_inode_set, | ||
| 91 | lower_inode); | ||
| 92 | if (!inode) { | ||
| 93 | rc = -EACCES; | ||
| 94 | iput(lower_inode); | ||
| 95 | goto out; | ||
| 96 | } | ||
| 97 | if (inode->i_state & I_NEW) | ||
| 98 | unlock_new_inode(inode); | ||
| 99 | else | ||
| 100 | iput(lower_inode); | ||
| 101 | if (S_ISLNK(lower_inode->i_mode)) | ||
| 102 | inode->i_op = &ecryptfs_symlink_iops; | ||
| 103 | else if (S_ISDIR(lower_inode->i_mode)) | ||
| 104 | inode->i_op = &ecryptfs_dir_iops; | ||
| 105 | if (S_ISDIR(lower_inode->i_mode)) | ||
| 106 | inode->i_fop = &ecryptfs_dir_fops; | ||
| 107 | /* TODO: Is there a better way to identify if the inode is | ||
| 108 | * special? */ | ||
| 109 | if (S_ISBLK(lower_inode->i_mode) || S_ISCHR(lower_inode->i_mode) || | ||
| 110 | S_ISFIFO(lower_inode->i_mode) || S_ISSOCK(lower_inode->i_mode)) | ||
| 111 | init_special_inode(inode, lower_inode->i_mode, | ||
| 112 | lower_inode->i_rdev); | ||
| 113 | dentry->d_op = &ecryptfs_dops; | ||
| 114 | if (flag) | ||
| 115 | d_add(dentry, inode); | ||
| 116 | else | ||
| 117 | d_instantiate(dentry, inode); | ||
| 118 | ecryptfs_copy_attr_all(inode, lower_inode); | ||
| 119 | /* This size will be overwritten for real files w/ headers and | ||
| 120 | * other metadata */ | ||
| 121 | ecryptfs_copy_inode_size(inode, lower_inode); | ||
| 122 | out: | ||
| 123 | return rc; | ||
| 124 | } | ||
| 125 | |||
| 126 | enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, ecryptfs_opt_debug, | ||
| 127 | ecryptfs_opt_ecryptfs_debug, ecryptfs_opt_cipher, | ||
| 128 | ecryptfs_opt_ecryptfs_cipher, ecryptfs_opt_ecryptfs_key_bytes, | ||
| 129 | ecryptfs_opt_passthrough, ecryptfs_opt_err }; | ||
| 130 | |||
| 131 | static match_table_t tokens = { | ||
| 132 | {ecryptfs_opt_sig, "sig=%s"}, | ||
| 133 | {ecryptfs_opt_ecryptfs_sig, "ecryptfs_sig=%s"}, | ||
| 134 | {ecryptfs_opt_debug, "debug=%u"}, | ||
| 135 | {ecryptfs_opt_ecryptfs_debug, "ecryptfs_debug=%u"}, | ||
| 136 | {ecryptfs_opt_cipher, "cipher=%s"}, | ||
| 137 | {ecryptfs_opt_ecryptfs_cipher, "ecryptfs_cipher=%s"}, | ||
| 138 | {ecryptfs_opt_ecryptfs_key_bytes, "ecryptfs_key_bytes=%u"}, | ||
| 139 | {ecryptfs_opt_passthrough, "ecryptfs_passthrough"}, | ||
| 140 | {ecryptfs_opt_err, NULL} | ||
| 141 | }; | ||
| 142 | |||
| 143 | /** | ||
| 144 | * ecryptfs_verify_version | ||
| 145 | * @version: The version number to confirm | ||
| 146 | * | ||
| 147 | * Returns zero on good version; non-zero otherwise | ||
| 148 | */ | ||
| 149 | static int ecryptfs_verify_version(u16 version) | ||
| 150 | { | ||
| 151 | int rc = 0; | ||
| 152 | unsigned char major; | ||
| 153 | unsigned char minor; | ||
| 154 | |||
| 155 | major = ((version >> 8) & 0xFF); | ||
| 156 | minor = (version & 0xFF); | ||
| 157 | if (major != ECRYPTFS_VERSION_MAJOR) { | ||
| 158 | ecryptfs_printk(KERN_ERR, "Major version number mismatch. " | ||
| 159 | "Expected [%d]; got [%d]\n", | ||
| 160 | ECRYPTFS_VERSION_MAJOR, major); | ||
| 161 | rc = -EINVAL; | ||
| 162 | goto out; | ||
| 163 | } | ||
| 164 | if (minor != ECRYPTFS_VERSION_MINOR) { | ||
| 165 | ecryptfs_printk(KERN_ERR, "Minor version number mismatch. " | ||
| 166 | "Expected [%d]; got [%d]\n", | ||
| 167 | ECRYPTFS_VERSION_MINOR, minor); | ||
| 168 | rc = -EINVAL; | ||
| 169 | goto out; | ||
| 170 | } | ||
| 171 | out: | ||
| 172 | return rc; | ||
| 173 | } | ||
| 174 | |||
| 175 | /** | ||
| 176 | * ecryptfs_parse_options | ||
| 177 | * @sb: The ecryptfs super block | ||
| 178 | * @options: The options pased to the kernel | ||
| 179 | * | ||
| 180 | * Parse mount options: | ||
| 181 | * debug=N - ecryptfs_verbosity level for debug output | ||
| 182 | * sig=XXX - description(signature) of the key to use | ||
| 183 | * | ||
| 184 | * Returns the dentry object of the lower-level (lower/interposed) | ||
| 185 | * directory; We want to mount our stackable file system on top of | ||
| 186 | * that lower directory. | ||
| 187 | * | ||
| 188 | * The signature of the key to use must be the description of a key | ||
| 189 | * already in the keyring. Mounting will fail if the key can not be | ||
| 190 | * found. | ||
| 191 | * | ||
| 192 | * Returns zero on success; non-zero on error | ||
| 193 | */ | ||
| 194 | static int ecryptfs_parse_options(struct super_block *sb, char *options) | ||
| 195 | { | ||
| 196 | char *p; | ||
| 197 | int rc = 0; | ||
| 198 | int sig_set = 0; | ||
| 199 | int cipher_name_set = 0; | ||
| 200 | int cipher_key_bytes; | ||
| 201 | int cipher_key_bytes_set = 0; | ||
| 202 | struct key *auth_tok_key = NULL; | ||
| 203 | struct ecryptfs_auth_tok *auth_tok = NULL; | ||
| 204 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | ||
| 205 | &ecryptfs_superblock_to_private(sb)->mount_crypt_stat; | ||
| 206 | substring_t args[MAX_OPT_ARGS]; | ||
| 207 | int token; | ||
| 208 | char *sig_src; | ||
| 209 | char *sig_dst; | ||
| 210 | char *debug_src; | ||
| 211 | char *cipher_name_dst; | ||
| 212 | char *cipher_name_src; | ||
| 213 | char *cipher_key_bytes_src; | ||
| 214 | struct crypto_tfm *tmp_tfm; | ||
| 215 | int cipher_name_len; | ||
| 216 | |||
| 217 | if (!options) { | ||
| 218 | rc = -EINVAL; | ||
| 219 | goto out; | ||
| 220 | } | ||
| 221 | while ((p = strsep(&options, ",")) != NULL) { | ||
| 222 | if (!*p) | ||
| 223 | continue; | ||
| 224 | token = match_token(p, tokens, args); | ||
| 225 | switch (token) { | ||
| 226 | case ecryptfs_opt_sig: | ||
| 227 | case ecryptfs_opt_ecryptfs_sig: | ||
| 228 | sig_src = args[0].from; | ||
| 229 | sig_dst = | ||
| 230 | mount_crypt_stat->global_auth_tok_sig; | ||
| 231 | memcpy(sig_dst, sig_src, ECRYPTFS_SIG_SIZE_HEX); | ||
| 232 | sig_dst[ECRYPTFS_SIG_SIZE_HEX] = '\0'; | ||
| 233 | ecryptfs_printk(KERN_DEBUG, | ||
| 234 | "The mount_crypt_stat " | ||
| 235 | "global_auth_tok_sig set to: " | ||
| 236 | "[%s]\n", sig_dst); | ||
| 237 | sig_set = 1; | ||
| 238 | break; | ||
| 239 | case ecryptfs_opt_debug: | ||
| 240 | case ecryptfs_opt_ecryptfs_debug: | ||
| 241 | debug_src = args[0].from; | ||
| 242 | ecryptfs_verbosity = | ||
| 243 | (int)simple_strtol(debug_src, &debug_src, | ||
| 244 | 0); | ||
| 245 | ecryptfs_printk(KERN_DEBUG, | ||
| 246 | "Verbosity set to [%d]" "\n", | ||
| 247 | ecryptfs_verbosity); | ||
| 248 | break; | ||
| 249 | case ecryptfs_opt_cipher: | ||
| 250 | case ecryptfs_opt_ecryptfs_cipher: | ||
| 251 | cipher_name_src = args[0].from; | ||
| 252 | cipher_name_dst = | ||
| 253 | mount_crypt_stat-> | ||
| 254 | global_default_cipher_name; | ||
| 255 | strncpy(cipher_name_dst, cipher_name_src, | ||
| 256 | ECRYPTFS_MAX_CIPHER_NAME_SIZE); | ||
| 257 | ecryptfs_printk(KERN_DEBUG, | ||
| 258 | "The mount_crypt_stat " | ||
| 259 | "global_default_cipher_name set to: " | ||
| 260 | "[%s]\n", cipher_name_dst); | ||
| 261 | cipher_name_set = 1; | ||
| 262 | break; | ||
| 263 | case ecryptfs_opt_ecryptfs_key_bytes: | ||
| 264 | cipher_key_bytes_src = args[0].from; | ||
| 265 | cipher_key_bytes = | ||
| 266 | (int)simple_strtol(cipher_key_bytes_src, | ||
| 267 | &cipher_key_bytes_src, 0); | ||
| 268 | mount_crypt_stat->global_default_cipher_key_size = | ||
| 269 | cipher_key_bytes; | ||
| 270 | ecryptfs_printk(KERN_DEBUG, | ||
| 271 | "The mount_crypt_stat " | ||
| 272 | "global_default_cipher_key_size " | ||
| 273 | "set to: [%d]\n", mount_crypt_stat-> | ||
| 274 | global_default_cipher_key_size); | ||
| 275 | cipher_key_bytes_set = 1; | ||
| 276 | break; | ||
| 277 | case ecryptfs_opt_passthrough: | ||
| 278 | mount_crypt_stat->flags |= | ||
| 279 | ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED; | ||
| 280 | break; | ||
| 281 | case ecryptfs_opt_err: | ||
| 282 | default: | ||
| 283 | ecryptfs_printk(KERN_WARNING, | ||
| 284 | "eCryptfs: unrecognized option '%s'\n", | ||
| 285 | p); | ||
| 286 | } | ||
| 287 | } | ||
| 288 | /* Do not support lack of mount-wide signature in 0.1 | ||
| 289 | * release */ | ||
| 290 | if (!sig_set) { | ||
| 291 | rc = -EINVAL; | ||
| 292 | ecryptfs_printk(KERN_ERR, "You must supply a valid " | ||
| 293 | "passphrase auth tok signature as a mount " | ||
| 294 | "parameter; see the eCryptfs README\n"); | ||
| 295 | goto out; | ||
| 296 | } | ||
| 297 | if (!cipher_name_set) { | ||
| 298 | cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER); | ||
| 299 | if (unlikely(cipher_name_len | ||
| 300 | >= ECRYPTFS_MAX_CIPHER_NAME_SIZE)) { | ||
| 301 | rc = -EINVAL; | ||
| 302 | BUG(); | ||
| 303 | goto out; | ||
| 304 | } | ||
| 305 | memcpy(mount_crypt_stat->global_default_cipher_name, | ||
| 306 | ECRYPTFS_DEFAULT_CIPHER, cipher_name_len); | ||
| 307 | mount_crypt_stat->global_default_cipher_name[cipher_name_len] | ||
| 308 | = '\0'; | ||
| 309 | } | ||
| 310 | if (!cipher_key_bytes_set) { | ||
| 311 | mount_crypt_stat->global_default_cipher_key_size = | ||
| 312 | ECRYPTFS_DEFAULT_KEY_BYTES; | ||
| 313 | ecryptfs_printk(KERN_DEBUG, "Cipher key size was not " | ||
| 314 | "specified. Defaulting to [%d]\n", | ||
| 315 | mount_crypt_stat-> | ||
| 316 | global_default_cipher_key_size); | ||
| 317 | } | ||
| 318 | rc = ecryptfs_process_cipher( | ||
| 319 | &tmp_tfm, | ||
| 320 | &mount_crypt_stat->global_key_tfm, | ||
| 321 | mount_crypt_stat->global_default_cipher_name, | ||
| 322 | mount_crypt_stat->global_default_cipher_key_size); | ||
| 323 | if (tmp_tfm) | ||
| 324 | crypto_free_tfm(tmp_tfm); | ||
| 325 | if (rc) { | ||
| 326 | printk(KERN_ERR "Error attempting to initialize cipher [%s] " | ||
| 327 | "with key size [%Zd] bytes; rc = [%d]\n", | ||
| 328 | mount_crypt_stat->global_default_cipher_name, | ||
| 329 | mount_crypt_stat->global_default_cipher_key_size, rc); | ||
| 330 | rc = -EINVAL; | ||
| 331 | goto out; | ||
| 332 | } | ||
| 333 | mutex_init(&mount_crypt_stat->global_key_tfm_mutex); | ||
| 334 | ecryptfs_printk(KERN_DEBUG, "Requesting the key with description: " | ||
| 335 | "[%s]\n", mount_crypt_stat->global_auth_tok_sig); | ||
| 336 | /* The reference to this key is held until umount is done The | ||
| 337 | * call to key_put is done in ecryptfs_put_super() */ | ||
| 338 | auth_tok_key = request_key(&key_type_user, | ||
| 339 | mount_crypt_stat->global_auth_tok_sig, | ||
| 340 | NULL); | ||
| 341 | if (!auth_tok_key || IS_ERR(auth_tok_key)) { | ||
| 342 | ecryptfs_printk(KERN_ERR, "Could not find key with " | ||
| 343 | "description: [%s]\n", | ||
| 344 | mount_crypt_stat->global_auth_tok_sig); | ||
| 345 | process_request_key_err(PTR_ERR(auth_tok_key)); | ||
| 346 | rc = -EINVAL; | ||
| 347 | goto out; | ||
| 348 | } | ||
| 349 | auth_tok = ecryptfs_get_key_payload_data(auth_tok_key); | ||
| 350 | if (ecryptfs_verify_version(auth_tok->version)) { | ||
| 351 | ecryptfs_printk(KERN_ERR, "Data structure version mismatch. " | ||
| 352 | "Userspace tools must match eCryptfs kernel " | ||
| 353 | "module with major version [%d] and minor " | ||
| 354 | "version [%d]\n", ECRYPTFS_VERSION_MAJOR, | ||
| 355 | ECRYPTFS_VERSION_MINOR); | ||
| 356 | rc = -EINVAL; | ||
| 357 | goto out; | ||
| 358 | } | ||
| 359 | if (auth_tok->token_type != ECRYPTFS_PASSWORD) { | ||
| 360 | ecryptfs_printk(KERN_ERR, "Invalid auth_tok structure " | ||
| 361 | "returned from key\n"); | ||
| 362 | rc = -EINVAL; | ||
| 363 | goto out; | ||
| 364 | } | ||
| 365 | mount_crypt_stat->global_auth_tok_key = auth_tok_key; | ||
| 366 | mount_crypt_stat->global_auth_tok = auth_tok; | ||
| 367 | out: | ||
| 368 | return rc; | ||
| 369 | } | ||
| 370 | |||
| 371 | struct kmem_cache *ecryptfs_sb_info_cache; | ||
| 372 | |||
| 373 | /** | ||
| 374 | * ecryptfs_fill_super | ||
| 375 | * @sb: The ecryptfs super block | ||
| 376 | * @raw_data: The options passed to mount | ||
| 377 | * @silent: Not used but required by function prototype | ||
| 378 | * | ||
| 379 | * Sets up what we can of the sb, rest is done in ecryptfs_read_super | ||
| 380 | * | ||
| 381 | * Returns zero on success; non-zero otherwise | ||
| 382 | */ | ||
| 383 | static int | ||
| 384 | ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent) | ||
| 385 | { | ||
| 386 | int rc = 0; | ||
| 387 | |||
| 388 | /* Released in ecryptfs_put_super() */ | ||
| 389 | ecryptfs_set_superblock_private(sb, | ||
| 390 | kmem_cache_alloc(ecryptfs_sb_info_cache, | ||
| 391 | SLAB_KERNEL)); | ||
| 392 | if (!ecryptfs_superblock_to_private(sb)) { | ||
| 393 | ecryptfs_printk(KERN_WARNING, "Out of memory\n"); | ||
| 394 | rc = -ENOMEM; | ||
| 395 | goto out; | ||
| 396 | } | ||
| 397 | memset(ecryptfs_superblock_to_private(sb), 0, | ||
| 398 | sizeof(struct ecryptfs_sb_info)); | ||
| 399 | sb->s_op = &ecryptfs_sops; | ||
| 400 | /* Released through deactivate_super(sb) from get_sb_nodev */ | ||
| 401 | sb->s_root = d_alloc(NULL, &(const struct qstr) { | ||
| 402 | .hash = 0,.name = "/",.len = 1}); | ||
| 403 | if (!sb->s_root) { | ||
| 404 | ecryptfs_printk(KERN_ERR, "d_alloc failed\n"); | ||
| 405 | rc = -ENOMEM; | ||
| 406 | goto out; | ||
| 407 | } | ||
| 408 | sb->s_root->d_op = &ecryptfs_dops; | ||
| 409 | sb->s_root->d_sb = sb; | ||
| 410 | sb->s_root->d_parent = sb->s_root; | ||
| 411 | /* Released in d_release when dput(sb->s_root) is called */ | ||
| 412 | /* through deactivate_super(sb) from get_sb_nodev() */ | ||
| 413 | ecryptfs_set_dentry_private(sb->s_root, | ||
| 414 | kmem_cache_alloc(ecryptfs_dentry_info_cache, | ||
| 415 | SLAB_KERNEL)); | ||
| 416 | if (!ecryptfs_dentry_to_private(sb->s_root)) { | ||
| 417 | ecryptfs_printk(KERN_ERR, | ||
| 418 | "dentry_info_cache alloc failed\n"); | ||
| 419 | rc = -ENOMEM; | ||
| 420 | goto out; | ||
| 421 | } | ||
| 422 | memset(ecryptfs_dentry_to_private(sb->s_root), 0, | ||
| 423 | sizeof(struct ecryptfs_dentry_info)); | ||
| 424 | rc = 0; | ||
| 425 | out: | ||
| 426 | /* Should be able to rely on deactivate_super called from | ||
| 427 | * get_sb_nodev */ | ||
| 428 | return rc; | ||
| 429 | } | ||
| 430 | |||
| 431 | /** | ||
| 432 | * ecryptfs_read_super | ||
| 433 | * @sb: The ecryptfs super block | ||
| 434 | * @dev_name: The path to mount over | ||
| 435 | * | ||
| 436 | * Read the super block of the lower filesystem, and use | ||
| 437 | * ecryptfs_interpose to create our initial inode and super block | ||
| 438 | * struct. | ||
| 439 | */ | ||
| 440 | static int ecryptfs_read_super(struct super_block *sb, const char *dev_name) | ||
| 441 | { | ||
| 442 | int rc; | ||
| 443 | struct nameidata nd; | ||
| 444 | struct dentry *lower_root; | ||
| 445 | struct vfsmount *lower_mnt; | ||
| 446 | |||
| 447 | memset(&nd, 0, sizeof(struct nameidata)); | ||
| 448 | rc = path_lookup(dev_name, LOOKUP_FOLLOW, &nd); | ||
| 449 | if (rc) { | ||
| 450 | ecryptfs_printk(KERN_WARNING, "path_lookup() failed\n"); | ||
| 451 | goto out_free; | ||
| 452 | } | ||
| 453 | lower_root = nd.dentry; | ||
| 454 | if (!lower_root->d_inode) { | ||
| 455 | ecryptfs_printk(KERN_WARNING, | ||
| 456 | "No directory to interpose on\n"); | ||
| 457 | rc = -ENOENT; | ||
| 458 | goto out_free; | ||
| 459 | } | ||
| 460 | lower_mnt = nd.mnt; | ||
| 461 | ecryptfs_set_superblock_lower(sb, lower_root->d_sb); | ||
| 462 | sb->s_maxbytes = lower_root->d_sb->s_maxbytes; | ||
| 463 | ecryptfs_set_dentry_lower(sb->s_root, lower_root); | ||
| 464 | ecryptfs_set_dentry_lower_mnt(sb->s_root, lower_mnt); | ||
| 465 | if ((rc = ecryptfs_interpose(lower_root, sb->s_root, sb, 0))) | ||
| 466 | goto out_free; | ||
| 467 | rc = 0; | ||
| 468 | goto out; | ||
| 469 | out_free: | ||
| 470 | path_release(&nd); | ||
| 471 | out: | ||
| 472 | return rc; | ||
| 473 | } | ||
| 474 | |||
| 475 | /** | ||
| 476 | * ecryptfs_get_sb | ||
| 477 | * @fs_type | ||
| 478 | * @flags | ||
| 479 | * @dev_name: The path to mount over | ||
| 480 | * @raw_data: The options passed into the kernel | ||
| 481 | * | ||
| 482 | * The whole ecryptfs_get_sb process is broken into 4 functions: | ||
| 483 | * ecryptfs_parse_options(): handle options passed to ecryptfs, if any | ||
| 484 | * ecryptfs_fill_super(): used by get_sb_nodev, fills out the super_block | ||
| 485 | * with as much information as it can before needing | ||
| 486 | * the lower filesystem. | ||
| 487 | * ecryptfs_read_super(): this accesses the lower filesystem and uses | ||
| 488 | * ecryptfs_interpolate to perform most of the linking | ||
| 489 | * ecryptfs_interpolate(): links the lower filesystem into ecryptfs | ||
| 490 | */ | ||
| 491 | static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags, | ||
| 492 | const char *dev_name, void *raw_data, | ||
| 493 | struct vfsmount *mnt) | ||
| 494 | { | ||
| 495 | int rc; | ||
| 496 | struct super_block *sb; | ||
| 497 | |||
| 498 | rc = get_sb_nodev(fs_type, flags, raw_data, ecryptfs_fill_super, mnt); | ||
| 499 | if (rc < 0) { | ||
| 500 | printk(KERN_ERR "Getting sb failed; rc = [%d]\n", rc); | ||
| 501 | goto out; | ||
| 502 | } | ||
| 503 | sb = mnt->mnt_sb; | ||
| 504 | rc = ecryptfs_parse_options(sb, raw_data); | ||
| 505 | if (rc) { | ||
| 506 | printk(KERN_ERR "Error parsing options; rc = [%d]\n", rc); | ||
| 507 | goto out_abort; | ||
| 508 | } | ||
| 509 | rc = ecryptfs_read_super(sb, dev_name); | ||
| 510 | if (rc) { | ||
| 511 | printk(KERN_ERR "Reading sb failed; rc = [%d]\n", rc); | ||
| 512 | goto out_abort; | ||
| 513 | } | ||
| 514 | goto out; | ||
| 515 | out_abort: | ||
| 516 | dput(sb->s_root); | ||
| 517 | up_write(&sb->s_umount); | ||
| 518 | deactivate_super(sb); | ||
| 519 | out: | ||
| 520 | return rc; | ||
| 521 | } | ||
| 522 | |||
| 523 | /** | ||
| 524 | * ecryptfs_kill_block_super | ||
| 525 | * @sb: The ecryptfs super block | ||
| 526 | * | ||
| 527 | * Used to bring the superblock down and free the private data. | ||
| 528 | * Private data is free'd in ecryptfs_put_super() | ||
| 529 | */ | ||
| 530 | static void ecryptfs_kill_block_super(struct super_block *sb) | ||
| 531 | { | ||
| 532 | generic_shutdown_super(sb); | ||
| 533 | } | ||
| 534 | |||
| 535 | static struct file_system_type ecryptfs_fs_type = { | ||
| 536 | .owner = THIS_MODULE, | ||
| 537 | .name = "ecryptfs", | ||
| 538 | .get_sb = ecryptfs_get_sb, | ||
| 539 | .kill_sb = ecryptfs_kill_block_super, | ||
| 540 | .fs_flags = 0 | ||
| 541 | }; | ||
| 542 | |||
| 543 | /** | ||
| 544 | * inode_info_init_once | ||
| 545 | * | ||
| 546 | * Initializes the ecryptfs_inode_info_cache when it is created | ||
| 547 | */ | ||
| 548 | static void | ||
| 549 | inode_info_init_once(void *vptr, struct kmem_cache *cachep, unsigned long flags) | ||
| 550 | { | ||
| 551 | struct ecryptfs_inode_info *ei = (struct ecryptfs_inode_info *)vptr; | ||
| 552 | |||
| 553 | if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) == | ||
| 554 | SLAB_CTOR_CONSTRUCTOR) | ||
| 555 | inode_init_once(&ei->vfs_inode); | ||
| 556 | } | ||
| 557 | |||
| 558 | static struct ecryptfs_cache_info { | ||
| 559 | kmem_cache_t **cache; | ||
| 560 | const char *name; | ||
| 561 | size_t size; | ||
| 562 | void (*ctor)(void*, struct kmem_cache *, unsigned long); | ||
| 563 | } ecryptfs_cache_infos[] = { | ||
| 564 | { | ||
| 565 | .cache = &ecryptfs_auth_tok_list_item_cache, | ||
| 566 | .name = "ecryptfs_auth_tok_list_item", | ||
| 567 | .size = sizeof(struct ecryptfs_auth_tok_list_item), | ||
| 568 | }, | ||
| 569 | { | ||
| 570 | .cache = &ecryptfs_file_info_cache, | ||
| 571 | .name = "ecryptfs_file_cache", | ||
| 572 | .size = sizeof(struct ecryptfs_file_info), | ||
| 573 | }, | ||
| 574 | { | ||
| 575 | .cache = &ecryptfs_dentry_info_cache, | ||
| 576 | .name = "ecryptfs_dentry_info_cache", | ||
| 577 | .size = sizeof(struct ecryptfs_dentry_info), | ||
| 578 | }, | ||
| 579 | { | ||
| 580 | .cache = &ecryptfs_inode_info_cache, | ||
| 581 | .name = "ecryptfs_inode_cache", | ||
| 582 | .size = sizeof(struct ecryptfs_inode_info), | ||
| 583 | .ctor = inode_info_init_once, | ||
| 584 | }, | ||
| 585 | { | ||
| 586 | .cache = &ecryptfs_sb_info_cache, | ||
| 587 | .name = "ecryptfs_sb_cache", | ||
| 588 | .size = sizeof(struct ecryptfs_sb_info), | ||
| 589 | }, | ||
| 590 | { | ||
| 591 | .cache = &ecryptfs_header_cache_0, | ||
| 592 | .name = "ecryptfs_headers_0", | ||
| 593 | .size = PAGE_CACHE_SIZE, | ||
| 594 | }, | ||
| 595 | { | ||
| 596 | .cache = &ecryptfs_header_cache_1, | ||
| 597 | .name = "ecryptfs_headers_1", | ||
| 598 | .size = PAGE_CACHE_SIZE, | ||
| 599 | }, | ||
| 600 | { | ||
| 601 | .cache = &ecryptfs_header_cache_2, | ||
| 602 | .name = "ecryptfs_headers_2", | ||
| 603 | .size = PAGE_CACHE_SIZE, | ||
| 604 | }, | ||
| 605 | { | ||
| 606 | .cache = &ecryptfs_lower_page_cache, | ||
| 607 | .name = "ecryptfs_lower_page_cache", | ||
| 608 | .size = PAGE_CACHE_SIZE, | ||
| 609 | }, | ||
| 610 | }; | ||
| 611 | |||
| 612 | static void ecryptfs_free_kmem_caches(void) | ||
| 613 | { | ||
| 614 | int i; | ||
| 615 | |||
| 616 | for (i = 0; i < ARRAY_SIZE(ecryptfs_cache_infos); i++) { | ||
| 617 | struct ecryptfs_cache_info *info; | ||
| 618 | |||
| 619 | info = &ecryptfs_cache_infos[i]; | ||
| 620 | if (*(info->cache)) | ||
| 621 | kmem_cache_destroy(*(info->cache)); | ||
| 622 | } | ||
| 623 | } | ||
| 624 | |||
| 625 | /** | ||
| 626 | * ecryptfs_init_kmem_caches | ||
| 627 | * | ||
| 628 | * Returns zero on success; non-zero otherwise | ||
| 629 | */ | ||
| 630 | static int ecryptfs_init_kmem_caches(void) | ||
| 631 | { | ||
| 632 | int i; | ||
| 633 | |||
| 634 | for (i = 0; i < ARRAY_SIZE(ecryptfs_cache_infos); i++) { | ||
| 635 | struct ecryptfs_cache_info *info; | ||
| 636 | |||
| 637 | info = &ecryptfs_cache_infos[i]; | ||
| 638 | *(info->cache) = kmem_cache_create(info->name, info->size, | ||
| 639 | 0, SLAB_HWCACHE_ALIGN, info->ctor, NULL); | ||
| 640 | if (!*(info->cache)) { | ||
| 641 | ecryptfs_free_kmem_caches(); | ||
| 642 | ecryptfs_printk(KERN_WARNING, "%s: " | ||
| 643 | "kmem_cache_create failed\n", | ||
| 644 | info->name); | ||
| 645 | return -ENOMEM; | ||
| 646 | } | ||
| 647 | } | ||
| 648 | return 0; | ||
| 649 | } | ||
| 650 | |||
| 651 | struct ecryptfs_obj { | ||
| 652 | char *name; | ||
| 653 | struct list_head slot_list; | ||
| 654 | struct kobject kobj; | ||
| 655 | }; | ||
| 656 | |||
| 657 | struct ecryptfs_attribute { | ||
| 658 | struct attribute attr; | ||
| 659 | ssize_t(*show) (struct ecryptfs_obj *, char *); | ||
| 660 | ssize_t(*store) (struct ecryptfs_obj *, const char *, size_t); | ||
| 661 | }; | ||
| 662 | |||
| 663 | static ssize_t | ||
| 664 | ecryptfs_attr_store(struct kobject *kobj, | ||
| 665 | struct attribute *attr, const char *buf, size_t len) | ||
| 666 | { | ||
| 667 | struct ecryptfs_obj *obj = container_of(kobj, struct ecryptfs_obj, | ||
| 668 | kobj); | ||
| 669 | struct ecryptfs_attribute *attribute = | ||
| 670 | container_of(attr, struct ecryptfs_attribute, attr); | ||
| 671 | |||
| 672 | return (attribute->store ? attribute->store(obj, buf, len) : 0); | ||
| 673 | } | ||
| 674 | |||
| 675 | static ssize_t | ||
| 676 | ecryptfs_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) | ||
| 677 | { | ||
| 678 | struct ecryptfs_obj *obj = container_of(kobj, struct ecryptfs_obj, | ||
| 679 | kobj); | ||
| 680 | struct ecryptfs_attribute *attribute = | ||
| 681 | container_of(attr, struct ecryptfs_attribute, attr); | ||
| 682 | |||
| 683 | return (attribute->show ? attribute->show(obj, buf) : 0); | ||
| 684 | } | ||
| 685 | |||
| 686 | static struct sysfs_ops ecryptfs_sysfs_ops = { | ||
| 687 | .show = ecryptfs_attr_show, | ||
| 688 | .store = ecryptfs_attr_store | ||
| 689 | }; | ||
| 690 | |||
| 691 | static struct kobj_type ecryptfs_ktype = { | ||
| 692 | .sysfs_ops = &ecryptfs_sysfs_ops | ||
| 693 | }; | ||
| 694 | |||
| 695 | static decl_subsys(ecryptfs, &ecryptfs_ktype, NULL); | ||
| 696 | |||
| 697 | static ssize_t version_show(struct ecryptfs_obj *obj, char *buff) | ||
| 698 | { | ||
| 699 | return snprintf(buff, PAGE_SIZE, "%d\n", ECRYPTFS_VERSIONING_MASK); | ||
| 700 | } | ||
| 701 | |||
| 702 | static struct ecryptfs_attribute sysfs_attr_version = __ATTR_RO(version); | ||
| 703 | |||
| 704 | struct ecryptfs_version_str_map_elem { | ||
| 705 | u32 flag; | ||
| 706 | char *str; | ||
| 707 | } ecryptfs_version_str_map[] = { | ||
| 708 | {ECRYPTFS_VERSIONING_PASSPHRASE, "passphrase"}, | ||
| 709 | {ECRYPTFS_VERSIONING_PUBKEY, "pubkey"}, | ||
| 710 | {ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH, "plaintext passthrough"}, | ||
| 711 | {ECRYPTFS_VERSIONING_POLICY, "policy"} | ||
| 712 | }; | ||
| 713 | |||
| 714 | static ssize_t version_str_show(struct ecryptfs_obj *obj, char *buff) | ||
| 715 | { | ||
| 716 | int i; | ||
| 717 | int remaining = PAGE_SIZE; | ||
| 718 | int total_written = 0; | ||
| 719 | |||
| 720 | buff[0] = '\0'; | ||
| 721 | for (i = 0; i < ARRAY_SIZE(ecryptfs_version_str_map); i++) { | ||
| 722 | int entry_size; | ||
| 723 | |||
| 724 | if (!(ECRYPTFS_VERSIONING_MASK | ||
| 725 | & ecryptfs_version_str_map[i].flag)) | ||
| 726 | continue; | ||
| 727 | entry_size = strlen(ecryptfs_version_str_map[i].str); | ||
| 728 | if ((entry_size + 2) > remaining) | ||
| 729 | goto out; | ||
| 730 | memcpy(buff, ecryptfs_version_str_map[i].str, entry_size); | ||
| 731 | buff[entry_size++] = '\n'; | ||
| 732 | buff[entry_size] = '\0'; | ||
| 733 | buff += entry_size; | ||
| 734 | total_written += entry_size; | ||
| 735 | remaining -= entry_size; | ||
| 736 | } | ||
| 737 | out: | ||
| 738 | return total_written; | ||
| 739 | } | ||
| 740 | |||
| 741 | static struct ecryptfs_attribute sysfs_attr_version_str = __ATTR_RO(version_str); | ||
| 742 | |||
| 743 | static int do_sysfs_registration(void) | ||
| 744 | { | ||
| 745 | int rc; | ||
| 746 | |||
| 747 | if ((rc = subsystem_register(&ecryptfs_subsys))) { | ||
| 748 | printk(KERN_ERR | ||
| 749 | "Unable to register ecryptfs sysfs subsystem\n"); | ||
| 750 | goto out; | ||
| 751 | } | ||
| 752 | rc = sysfs_create_file(&ecryptfs_subsys.kset.kobj, | ||
| 753 | &sysfs_attr_version.attr); | ||
| 754 | if (rc) { | ||
| 755 | printk(KERN_ERR | ||
| 756 | "Unable to create ecryptfs version attribute\n"); | ||
| 757 | subsystem_unregister(&ecryptfs_subsys); | ||
| 758 | goto out; | ||
| 759 | } | ||
| 760 | rc = sysfs_create_file(&ecryptfs_subsys.kset.kobj, | ||
| 761 | &sysfs_attr_version_str.attr); | ||
| 762 | if (rc) { | ||
| 763 | printk(KERN_ERR | ||
| 764 | "Unable to create ecryptfs version_str attribute\n"); | ||
| 765 | sysfs_remove_file(&ecryptfs_subsys.kset.kobj, | ||
| 766 | &sysfs_attr_version.attr); | ||
| 767 | subsystem_unregister(&ecryptfs_subsys); | ||
| 768 | goto out; | ||
| 769 | } | ||
| 770 | out: | ||
| 771 | return rc; | ||
| 772 | } | ||
| 773 | |||
| 774 | static int __init ecryptfs_init(void) | ||
| 775 | { | ||
| 776 | int rc; | ||
| 777 | |||
| 778 | if (ECRYPTFS_DEFAULT_EXTENT_SIZE > PAGE_CACHE_SIZE) { | ||
| 779 | rc = -EINVAL; | ||
| 780 | ecryptfs_printk(KERN_ERR, "The eCryptfs extent size is " | ||
| 781 | "larger than the host's page size, and so " | ||
| 782 | "eCryptfs cannot run on this system. The " | ||
| 783 | "default eCryptfs extent size is [%d] bytes; " | ||
| 784 | "the page size is [%d] bytes.\n", | ||
| 785 | ECRYPTFS_DEFAULT_EXTENT_SIZE, PAGE_CACHE_SIZE); | ||
| 786 | goto out; | ||
| 787 | } | ||
| 788 | rc = ecryptfs_init_kmem_caches(); | ||
| 789 | if (rc) { | ||
| 790 | printk(KERN_ERR | ||
| 791 | "Failed to allocate one or more kmem_cache objects\n"); | ||
| 792 | goto out; | ||
| 793 | } | ||
| 794 | rc = register_filesystem(&ecryptfs_fs_type); | ||
| 795 | if (rc) { | ||
| 796 | printk(KERN_ERR "Failed to register filesystem\n"); | ||
| 797 | ecryptfs_free_kmem_caches(); | ||
| 798 | goto out; | ||
| 799 | } | ||
| 800 | kset_set_kset_s(&ecryptfs_subsys, fs_subsys); | ||
| 801 | sysfs_attr_version.attr.owner = THIS_MODULE; | ||
| 802 | sysfs_attr_version_str.attr.owner = THIS_MODULE; | ||
| 803 | rc = do_sysfs_registration(); | ||
| 804 | if (rc) { | ||
| 805 | printk(KERN_ERR "sysfs registration failed\n"); | ||
| 806 | unregister_filesystem(&ecryptfs_fs_type); | ||
| 807 | ecryptfs_free_kmem_caches(); | ||
| 808 | goto out; | ||
| 809 | } | ||
| 810 | out: | ||
| 811 | return rc; | ||
| 812 | } | ||
| 813 | |||
| 814 | static void __exit ecryptfs_exit(void) | ||
| 815 | { | ||
| 816 | sysfs_remove_file(&ecryptfs_subsys.kset.kobj, | ||
| 817 | &sysfs_attr_version.attr); | ||
| 818 | sysfs_remove_file(&ecryptfs_subsys.kset.kobj, | ||
| 819 | &sysfs_attr_version_str.attr); | ||
| 820 | subsystem_unregister(&ecryptfs_subsys); | ||
| 821 | unregister_filesystem(&ecryptfs_fs_type); | ||
| 822 | ecryptfs_free_kmem_caches(); | ||
| 823 | } | ||
| 824 | |||
| 825 | MODULE_AUTHOR("Michael A. Halcrow <mhalcrow@us.ibm.com>"); | ||
| 826 | MODULE_DESCRIPTION("eCryptfs"); | ||
| 827 | |||
| 828 | MODULE_LICENSE("GPL"); | ||
| 829 | |||
| 830 | module_init(ecryptfs_init) | ||
| 831 | module_exit(ecryptfs_exit) | ||
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c new file mode 100644 index 000000000000..924dd90a4cf5 --- /dev/null +++ b/fs/ecryptfs/mmap.c | |||
| @@ -0,0 +1,788 @@ | |||
| 1 | /** | ||
| 2 | * eCryptfs: Linux filesystem encryption layer | ||
| 3 | * This is where eCryptfs coordinates the symmetric encryption and | ||
| 4 | * decryption of the file data as it passes between the lower | ||
| 5 | * encrypted file and the upper decrypted file. | ||
| 6 | * | ||
| 7 | * Copyright (C) 1997-2003 Erez Zadok | ||
| 8 | * Copyright (C) 2001-2003 Stony Brook University | ||
| 9 | * Copyright (C) 2004-2006 International Business Machines Corp. | ||
| 10 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or | ||
| 13 | * modify it under the terms of the GNU General Public License as | ||
| 14 | * published by the Free Software Foundation; either version 2 of the | ||
| 15 | * License, or (at your option) any later version. | ||
| 16 | * | ||
| 17 | * This program is distributed in the hope that it will be useful, but | ||
| 18 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 20 | * General Public License for more details. | ||
| 21 | * | ||
| 22 | * You should have received a copy of the GNU General Public License | ||
| 23 | * along with this program; if not, write to the Free Software | ||
| 24 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
| 25 | * 02111-1307, USA. | ||
| 26 | */ | ||
| 27 | |||
| 28 | #include <linux/pagemap.h> | ||
| 29 | #include <linux/writeback.h> | ||
| 30 | #include <linux/page-flags.h> | ||
| 31 | #include <linux/mount.h> | ||
| 32 | #include <linux/file.h> | ||
| 33 | #include <linux/crypto.h> | ||
| 34 | #include <linux/scatterlist.h> | ||
| 35 | #include "ecryptfs_kernel.h" | ||
| 36 | |||
| 37 | struct kmem_cache *ecryptfs_lower_page_cache; | ||
| 38 | |||
| 39 | /** | ||
| 40 | * ecryptfs_get1page | ||
| 41 | * | ||
| 42 | * Get one page from cache or lower f/s, return error otherwise. | ||
| 43 | * | ||
| 44 | * Returns unlocked and up-to-date page (if ok), with increased | ||
| 45 | * refcnt. | ||
| 46 | */ | ||
| 47 | static struct page *ecryptfs_get1page(struct file *file, int index) | ||
| 48 | { | ||
| 49 | struct page *page; | ||
| 50 | struct dentry *dentry; | ||
| 51 | struct inode *inode; | ||
| 52 | struct address_space *mapping; | ||
| 53 | |||
| 54 | dentry = file->f_dentry; | ||
| 55 | inode = dentry->d_inode; | ||
| 56 | mapping = inode->i_mapping; | ||
| 57 | page = read_cache_page(mapping, index, | ||
| 58 | (filler_t *)mapping->a_ops->readpage, | ||
| 59 | (void *)file); | ||
| 60 | if (IS_ERR(page)) | ||
| 61 | goto out; | ||
| 62 | wait_on_page_locked(page); | ||
| 63 | out: | ||
| 64 | return page; | ||
| 65 | } | ||
| 66 | |||
| 67 | static | ||
| 68 | int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros); | ||
| 69 | |||
| 70 | /** | ||
| 71 | * ecryptfs_fill_zeros | ||
| 72 | * @file: The ecryptfs file | ||
| 73 | * @new_length: The new length of the data in the underlying file; | ||
| 74 | * everything between the prior end of the file and the | ||
| 75 | * new end of the file will be filled with zero's. | ||
| 76 | * new_length must be greater than current length | ||
| 77 | * | ||
| 78 | * Function for handling lseek-ing past the end of the file. | ||
| 79 | * | ||
| 80 | * This function does not support shrinking, only growing a file. | ||
| 81 | * | ||
| 82 | * Returns zero on success; non-zero otherwise. | ||
| 83 | */ | ||
| 84 | int ecryptfs_fill_zeros(struct file *file, loff_t new_length) | ||
| 85 | { | ||
| 86 | int rc = 0; | ||
| 87 | struct dentry *dentry = file->f_dentry; | ||
| 88 | struct inode *inode = dentry->d_inode; | ||
| 89 | pgoff_t old_end_page_index = 0; | ||
| 90 | pgoff_t index = old_end_page_index; | ||
| 91 | int old_end_pos_in_page = -1; | ||
| 92 | pgoff_t new_end_page_index; | ||
| 93 | int new_end_pos_in_page; | ||
| 94 | loff_t cur_length = i_size_read(inode); | ||
| 95 | |||
| 96 | if (cur_length != 0) { | ||
| 97 | index = old_end_page_index = | ||
| 98 | ((cur_length - 1) >> PAGE_CACHE_SHIFT); | ||
| 99 | old_end_pos_in_page = ((cur_length - 1) & ~PAGE_CACHE_MASK); | ||
| 100 | } | ||
| 101 | new_end_page_index = ((new_length - 1) >> PAGE_CACHE_SHIFT); | ||
| 102 | new_end_pos_in_page = ((new_length - 1) & ~PAGE_CACHE_MASK); | ||
| 103 | ecryptfs_printk(KERN_DEBUG, "old_end_page_index = [0x%.16x]; " | ||
| 104 | "old_end_pos_in_page = [%d]; " | ||
| 105 | "new_end_page_index = [0x%.16x]; " | ||
| 106 | "new_end_pos_in_page = [%d]\n", | ||
| 107 | old_end_page_index, old_end_pos_in_page, | ||
| 108 | new_end_page_index, new_end_pos_in_page); | ||
| 109 | if (old_end_page_index == new_end_page_index) { | ||
| 110 | /* Start and end are in the same page; we just need to | ||
| 111 | * set a portion of the existing page to zero's */ | ||
| 112 | rc = write_zeros(file, index, (old_end_pos_in_page + 1), | ||
| 113 | (new_end_pos_in_page - old_end_pos_in_page)); | ||
| 114 | if (rc) | ||
| 115 | ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], " | ||
| 116 | "index=[0x%.16x], " | ||
| 117 | "old_end_pos_in_page=[d], " | ||
| 118 | "(PAGE_CACHE_SIZE - new_end_pos_in_page" | ||
| 119 | "=[%d]" | ||
| 120 | ")=[d]) returned [%d]\n", file, index, | ||
| 121 | old_end_pos_in_page, | ||
| 122 | new_end_pos_in_page, | ||
| 123 | (PAGE_CACHE_SIZE - new_end_pos_in_page), | ||
| 124 | rc); | ||
| 125 | goto out; | ||
| 126 | } | ||
| 127 | /* Fill the remainder of the previous last page with zeros */ | ||
| 128 | rc = write_zeros(file, index, (old_end_pos_in_page + 1), | ||
| 129 | ((PAGE_CACHE_SIZE - 1) - old_end_pos_in_page)); | ||
| 130 | if (rc) { | ||
| 131 | ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], " | ||
| 132 | "index=[0x%.16x], old_end_pos_in_page=[d], " | ||
| 133 | "(PAGE_CACHE_SIZE - old_end_pos_in_page)=[d]) " | ||
| 134 | "returned [%d]\n", file, index, | ||
| 135 | old_end_pos_in_page, | ||
| 136 | (PAGE_CACHE_SIZE - old_end_pos_in_page), rc); | ||
| 137 | goto out; | ||
| 138 | } | ||
| 139 | index++; | ||
| 140 | while (index < new_end_page_index) { | ||
| 141 | /* Fill all intermediate pages with zeros */ | ||
| 142 | rc = write_zeros(file, index, 0, PAGE_CACHE_SIZE); | ||
| 143 | if (rc) { | ||
| 144 | ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], " | ||
| 145 | "index=[0x%.16x], " | ||
| 146 | "old_end_pos_in_page=[d], " | ||
| 147 | "(PAGE_CACHE_SIZE - new_end_pos_in_page" | ||
| 148 | "=[%d]" | ||
| 149 | ")=[d]) returned [%d]\n", file, index, | ||
| 150 | old_end_pos_in_page, | ||
| 151 | new_end_pos_in_page, | ||
| 152 | (PAGE_CACHE_SIZE - new_end_pos_in_page), | ||
| 153 | rc); | ||
| 154 | goto out; | ||
| 155 | } | ||
| 156 | index++; | ||
| 157 | } | ||
| 158 | /* Fill the portion at the beginning of the last new page with | ||
| 159 | * zero's */ | ||
| 160 | rc = write_zeros(file, index, 0, (new_end_pos_in_page + 1)); | ||
| 161 | if (rc) { | ||
| 162 | ecryptfs_printk(KERN_ERR, "write_zeros(file=" | ||
| 163 | "[%p], index=[0x%.16x], 0, " | ||
| 164 | "new_end_pos_in_page=[%d]" | ||
| 165 | "returned [%d]\n", file, index, | ||
| 166 | new_end_pos_in_page, rc); | ||
| 167 | goto out; | ||
| 168 | } | ||
| 169 | out: | ||
| 170 | return rc; | ||
| 171 | } | ||
| 172 | |||
| 173 | /** | ||
| 174 | * ecryptfs_writepage | ||
| 175 | * @page: Page that is locked before this call is made | ||
| 176 | * | ||
| 177 | * Returns zero on success; non-zero otherwise | ||
| 178 | */ | ||
| 179 | static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc) | ||
| 180 | { | ||
| 181 | struct ecryptfs_page_crypt_context ctx; | ||
| 182 | int rc; | ||
| 183 | |||
| 184 | ctx.page = page; | ||
| 185 | ctx.mode = ECRYPTFS_WRITEPAGE_MODE; | ||
| 186 | ctx.param.wbc = wbc; | ||
| 187 | rc = ecryptfs_encrypt_page(&ctx); | ||
| 188 | if (rc) { | ||
| 189 | ecryptfs_printk(KERN_WARNING, "Error encrypting " | ||
| 190 | "page (upper index [0x%.16x])\n", page->index); | ||
| 191 | ClearPageUptodate(page); | ||
| 192 | goto out; | ||
| 193 | } | ||
| 194 | SetPageUptodate(page); | ||
| 195 | unlock_page(page); | ||
| 196 | out: | ||
| 197 | return rc; | ||
| 198 | } | ||
| 199 | |||
| 200 | /** | ||
| 201 | * Reads the data from the lower file file at index lower_page_index | ||
| 202 | * and copies that data into page. | ||
| 203 | * | ||
| 204 | * @param page Page to fill | ||
| 205 | * @param lower_page_index Index of the page in the lower file to get | ||
| 206 | */ | ||
| 207 | int ecryptfs_do_readpage(struct file *file, struct page *page, | ||
| 208 | pgoff_t lower_page_index) | ||
| 209 | { | ||
| 210 | int rc; | ||
| 211 | struct dentry *dentry; | ||
| 212 | struct file *lower_file; | ||
| 213 | struct dentry *lower_dentry; | ||
| 214 | struct inode *inode; | ||
| 215 | struct inode *lower_inode; | ||
| 216 | char *page_data; | ||
| 217 | struct page *lower_page = NULL; | ||
| 218 | char *lower_page_data; | ||
| 219 | const struct address_space_operations *lower_a_ops; | ||
| 220 | |||
| 221 | dentry = file->f_dentry; | ||
| 222 | lower_file = ecryptfs_file_to_lower(file); | ||
| 223 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 224 | inode = dentry->d_inode; | ||
| 225 | lower_inode = ecryptfs_inode_to_lower(inode); | ||
| 226 | lower_a_ops = lower_inode->i_mapping->a_ops; | ||
| 227 | lower_page = read_cache_page(lower_inode->i_mapping, lower_page_index, | ||
| 228 | (filler_t *)lower_a_ops->readpage, | ||
| 229 | (void *)lower_file); | ||
| 230 | if (IS_ERR(lower_page)) { | ||
| 231 | rc = PTR_ERR(lower_page); | ||
| 232 | lower_page = NULL; | ||
| 233 | ecryptfs_printk(KERN_ERR, "Error reading from page cache\n"); | ||
| 234 | goto out; | ||
| 235 | } | ||
| 236 | wait_on_page_locked(lower_page); | ||
| 237 | page_data = (char *)kmap(page); | ||
| 238 | if (!page_data) { | ||
| 239 | rc = -ENOMEM; | ||
| 240 | ecryptfs_printk(KERN_ERR, "Error mapping page\n"); | ||
| 241 | goto out; | ||
| 242 | } | ||
| 243 | lower_page_data = (char *)kmap(lower_page); | ||
| 244 | if (!lower_page_data) { | ||
| 245 | rc = -ENOMEM; | ||
| 246 | ecryptfs_printk(KERN_ERR, "Error mapping page\n"); | ||
| 247 | kunmap(page); | ||
| 248 | goto out; | ||
| 249 | } | ||
| 250 | memcpy(page_data, lower_page_data, PAGE_CACHE_SIZE); | ||
| 251 | kunmap(lower_page); | ||
| 252 | kunmap(page); | ||
| 253 | rc = 0; | ||
| 254 | out: | ||
| 255 | if (likely(lower_page)) | ||
| 256 | page_cache_release(lower_page); | ||
| 257 | if (rc == 0) | ||
| 258 | SetPageUptodate(page); | ||
| 259 | else | ||
| 260 | ClearPageUptodate(page); | ||
| 261 | return rc; | ||
| 262 | } | ||
| 263 | |||
| 264 | /** | ||
| 265 | * ecryptfs_readpage | ||
| 266 | * @file: This is an ecryptfs file | ||
| 267 | * @page: ecryptfs associated page to stick the read data into | ||
| 268 | * | ||
| 269 | * Read in a page, decrypting if necessary. | ||
| 270 | * | ||
| 271 | * Returns zero on success; non-zero on error. | ||
| 272 | */ | ||
| 273 | static int ecryptfs_readpage(struct file *file, struct page *page) | ||
| 274 | { | ||
| 275 | int rc = 0; | ||
| 276 | struct ecryptfs_crypt_stat *crypt_stat; | ||
| 277 | |||
| 278 | BUG_ON(!(file && file->f_dentry && file->f_dentry->d_inode)); | ||
| 279 | crypt_stat = | ||
| 280 | &ecryptfs_inode_to_private(file->f_dentry->d_inode)->crypt_stat; | ||
| 281 | if (!crypt_stat | ||
| 282 | || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED) | ||
| 283 | || ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE)) { | ||
| 284 | ecryptfs_printk(KERN_DEBUG, | ||
| 285 | "Passing through unencrypted page\n"); | ||
| 286 | rc = ecryptfs_do_readpage(file, page, page->index); | ||
| 287 | if (rc) { | ||
| 288 | ecryptfs_printk(KERN_ERR, "Error reading page; rc = " | ||
| 289 | "[%d]\n", rc); | ||
| 290 | goto out; | ||
| 291 | } | ||
| 292 | } else { | ||
| 293 | rc = ecryptfs_decrypt_page(file, page); | ||
| 294 | if (rc) { | ||
| 295 | |||
| 296 | ecryptfs_printk(KERN_ERR, "Error decrypting page; " | ||
| 297 | "rc = [%d]\n", rc); | ||
| 298 | goto out; | ||
| 299 | } | ||
| 300 | } | ||
| 301 | SetPageUptodate(page); | ||
| 302 | out: | ||
| 303 | if (rc) | ||
| 304 | ClearPageUptodate(page); | ||
| 305 | ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n", | ||
| 306 | page->index); | ||
| 307 | unlock_page(page); | ||
| 308 | return rc; | ||
| 309 | } | ||
| 310 | |||
| 311 | static int fill_zeros_to_end_of_page(struct page *page, unsigned int to) | ||
| 312 | { | ||
| 313 | struct inode *inode = page->mapping->host; | ||
| 314 | int end_byte_in_page; | ||
| 315 | int rc = 0; | ||
| 316 | char *page_virt; | ||
| 317 | |||
| 318 | if ((i_size_read(inode) / PAGE_CACHE_SIZE) == page->index) { | ||
| 319 | end_byte_in_page = i_size_read(inode) % PAGE_CACHE_SIZE; | ||
| 320 | if (to > end_byte_in_page) | ||
| 321 | end_byte_in_page = to; | ||
| 322 | page_virt = kmap(page); | ||
| 323 | if (!page_virt) { | ||
| 324 | rc = -ENOMEM; | ||
| 325 | ecryptfs_printk(KERN_WARNING, | ||
| 326 | "Could not map page\n"); | ||
| 327 | goto out; | ||
| 328 | } | ||
| 329 | memset((page_virt + end_byte_in_page), 0, | ||
| 330 | (PAGE_CACHE_SIZE - end_byte_in_page)); | ||
| 331 | kunmap(page); | ||
| 332 | } | ||
| 333 | out: | ||
| 334 | return rc; | ||
| 335 | } | ||
| 336 | |||
| 337 | static int ecryptfs_prepare_write(struct file *file, struct page *page, | ||
| 338 | unsigned from, unsigned to) | ||
| 339 | { | ||
| 340 | int rc = 0; | ||
| 341 | |||
| 342 | kmap(page); | ||
| 343 | if (from == 0 && to == PAGE_CACHE_SIZE) | ||
| 344 | goto out; /* If we are writing a full page, it will be | ||
| 345 | up to date. */ | ||
| 346 | if (!PageUptodate(page)) | ||
| 347 | rc = ecryptfs_do_readpage(file, page, page->index); | ||
| 348 | out: | ||
| 349 | return rc; | ||
| 350 | } | ||
| 351 | |||
| 352 | int ecryptfs_grab_and_map_lower_page(struct page **lower_page, | ||
| 353 | char **lower_virt, | ||
| 354 | struct inode *lower_inode, | ||
| 355 | unsigned long lower_page_index) | ||
| 356 | { | ||
| 357 | int rc = 0; | ||
| 358 | |||
| 359 | (*lower_page) = grab_cache_page(lower_inode->i_mapping, | ||
| 360 | lower_page_index); | ||
| 361 | if (!(*lower_page)) { | ||
| 362 | ecryptfs_printk(KERN_ERR, "grab_cache_page for " | ||
| 363 | "lower_page_index = [0x%.16x] failed\n", | ||
| 364 | lower_page_index); | ||
| 365 | rc = -EINVAL; | ||
| 366 | goto out; | ||
| 367 | } | ||
| 368 | if (lower_virt) | ||
| 369 | (*lower_virt) = kmap((*lower_page)); | ||
| 370 | else | ||
| 371 | kmap((*lower_page)); | ||
| 372 | out: | ||
| 373 | return rc; | ||
| 374 | } | ||
| 375 | |||
| 376 | int ecryptfs_writepage_and_release_lower_page(struct page *lower_page, | ||
| 377 | struct inode *lower_inode, | ||
| 378 | struct writeback_control *wbc) | ||
| 379 | { | ||
| 380 | int rc = 0; | ||
| 381 | |||
| 382 | rc = lower_inode->i_mapping->a_ops->writepage(lower_page, wbc); | ||
| 383 | if (rc) { | ||
| 384 | ecryptfs_printk(KERN_ERR, "Error calling lower writepage(); " | ||
| 385 | "rc = [%d]\n", rc); | ||
| 386 | goto out; | ||
| 387 | } | ||
| 388 | lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME; | ||
| 389 | page_cache_release(lower_page); | ||
| 390 | out: | ||
| 391 | return rc; | ||
| 392 | } | ||
| 393 | |||
| 394 | static void ecryptfs_unmap_and_release_lower_page(struct page *lower_page) | ||
| 395 | { | ||
| 396 | kunmap(lower_page); | ||
| 397 | ecryptfs_printk(KERN_DEBUG, "Unlocking lower page with index = " | ||
| 398 | "[0x%.16x]\n", lower_page->index); | ||
| 399 | unlock_page(lower_page); | ||
| 400 | page_cache_release(lower_page); | ||
| 401 | } | ||
| 402 | |||
| 403 | /** | ||
| 404 | * ecryptfs_write_inode_size_to_header | ||
| 405 | * | ||
| 406 | * Writes the lower file size to the first 8 bytes of the header. | ||
| 407 | * | ||
| 408 | * Returns zero on success; non-zero on error. | ||
| 409 | */ | ||
| 410 | int | ||
| 411 | ecryptfs_write_inode_size_to_header(struct file *lower_file, | ||
| 412 | struct inode *lower_inode, | ||
| 413 | struct inode *inode) | ||
| 414 | { | ||
| 415 | int rc = 0; | ||
| 416 | struct page *header_page; | ||
| 417 | char *header_virt; | ||
| 418 | const struct address_space_operations *lower_a_ops; | ||
| 419 | u64 file_size; | ||
| 420 | |||
| 421 | rc = ecryptfs_grab_and_map_lower_page(&header_page, &header_virt, | ||
| 422 | lower_inode, 0); | ||
| 423 | if (rc) { | ||
| 424 | ecryptfs_printk(KERN_ERR, "grab_cache_page for header page " | ||
| 425 | "failed\n"); | ||
| 426 | goto out; | ||
| 427 | } | ||
| 428 | lower_a_ops = lower_inode->i_mapping->a_ops; | ||
| 429 | rc = lower_a_ops->prepare_write(lower_file, header_page, 0, 8); | ||
| 430 | file_size = (u64)i_size_read(inode); | ||
| 431 | ecryptfs_printk(KERN_DEBUG, "Writing size: [0x%.16x]\n", file_size); | ||
| 432 | file_size = cpu_to_be64(file_size); | ||
| 433 | memcpy(header_virt, &file_size, sizeof(u64)); | ||
| 434 | rc = lower_a_ops->commit_write(lower_file, header_page, 0, 8); | ||
| 435 | if (rc < 0) | ||
| 436 | ecryptfs_printk(KERN_ERR, "Error commiting header page " | ||
| 437 | "write\n"); | ||
| 438 | ecryptfs_unmap_and_release_lower_page(header_page); | ||
| 439 | lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME; | ||
| 440 | mark_inode_dirty_sync(inode); | ||
| 441 | out: | ||
| 442 | return rc; | ||
| 443 | } | ||
| 444 | |||
| 445 | int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode, | ||
| 446 | struct file *lower_file, | ||
| 447 | unsigned long lower_page_index, int byte_offset, | ||
| 448 | int region_bytes) | ||
| 449 | { | ||
| 450 | int rc = 0; | ||
| 451 | |||
| 452 | rc = ecryptfs_grab_and_map_lower_page(lower_page, NULL, lower_inode, | ||
| 453 | lower_page_index); | ||
| 454 | if (rc) { | ||
| 455 | ecryptfs_printk(KERN_ERR, "Error attempting to grab and map " | ||
| 456 | "lower page with index [0x%.16x]\n", | ||
| 457 | lower_page_index); | ||
| 458 | goto out; | ||
| 459 | } | ||
| 460 | rc = lower_inode->i_mapping->a_ops->prepare_write(lower_file, | ||
| 461 | (*lower_page), | ||
| 462 | byte_offset, | ||
| 463 | region_bytes); | ||
| 464 | if (rc) { | ||
| 465 | ecryptfs_printk(KERN_ERR, "prepare_write for " | ||
| 466 | "lower_page_index = [0x%.16x] failed; rc = " | ||
| 467 | "[%d]\n", lower_page_index, rc); | ||
| 468 | } | ||
| 469 | out: | ||
| 470 | if (rc && (*lower_page)) { | ||
| 471 | ecryptfs_unmap_and_release_lower_page(*lower_page); | ||
| 472 | (*lower_page) = NULL; | ||
| 473 | } | ||
| 474 | return rc; | ||
| 475 | } | ||
| 476 | |||
| 477 | /** | ||
| 478 | * ecryptfs_commit_lower_page | ||
| 479 | * | ||
| 480 | * Returns zero on success; non-zero on error | ||
| 481 | */ | ||
| 482 | int | ||
| 483 | ecryptfs_commit_lower_page(struct page *lower_page, struct inode *lower_inode, | ||
| 484 | struct file *lower_file, int byte_offset, | ||
| 485 | int region_size) | ||
| 486 | { | ||
| 487 | int rc = 0; | ||
| 488 | |||
| 489 | rc = lower_inode->i_mapping->a_ops->commit_write( | ||
| 490 | lower_file, lower_page, byte_offset, region_size); | ||
| 491 | if (rc < 0) { | ||
| 492 | ecryptfs_printk(KERN_ERR, | ||
| 493 | "Error committing write; rc = [%d]\n", rc); | ||
| 494 | } else | ||
| 495 | rc = 0; | ||
| 496 | ecryptfs_unmap_and_release_lower_page(lower_page); | ||
| 497 | return rc; | ||
| 498 | } | ||
| 499 | |||
| 500 | /** | ||
| 501 | * ecryptfs_copy_page_to_lower | ||
| 502 | * | ||
| 503 | * Used for plaintext pass-through; no page index interpolation | ||
| 504 | * required. | ||
| 505 | */ | ||
| 506 | int ecryptfs_copy_page_to_lower(struct page *page, struct inode *lower_inode, | ||
| 507 | struct file *lower_file) | ||
| 508 | { | ||
| 509 | int rc = 0; | ||
| 510 | struct page *lower_page; | ||
| 511 | |||
| 512 | rc = ecryptfs_get_lower_page(&lower_page, lower_inode, lower_file, | ||
| 513 | page->index, 0, PAGE_CACHE_SIZE); | ||
| 514 | if (rc) { | ||
| 515 | ecryptfs_printk(KERN_ERR, "Error attempting to get page " | ||
| 516 | "at index [0x%.16x]\n", page->index); | ||
| 517 | goto out; | ||
| 518 | } | ||
| 519 | /* TODO: aops */ | ||
| 520 | memcpy((char *)page_address(lower_page), page_address(page), | ||
| 521 | PAGE_CACHE_SIZE); | ||
| 522 | rc = ecryptfs_commit_lower_page(lower_page, lower_inode, lower_file, | ||
| 523 | 0, PAGE_CACHE_SIZE); | ||
| 524 | if (rc) | ||
| 525 | ecryptfs_printk(KERN_ERR, "Error attempting to commit page " | ||
| 526 | "at index [0x%.16x]\n", page->index); | ||
| 527 | out: | ||
| 528 | return rc; | ||
| 529 | } | ||
| 530 | |||
| 531 | static int | ||
| 532 | process_new_file(struct ecryptfs_crypt_stat *crypt_stat, | ||
| 533 | struct file *file, struct inode *inode) | ||
| 534 | { | ||
| 535 | struct page *header_page; | ||
| 536 | const struct address_space_operations *lower_a_ops; | ||
| 537 | struct inode *lower_inode; | ||
| 538 | struct file *lower_file; | ||
| 539 | char *header_virt; | ||
| 540 | int rc = 0; | ||
| 541 | int current_header_page = 0; | ||
| 542 | int header_pages; | ||
| 543 | int more_header_data_to_be_written = 1; | ||
| 544 | |||
| 545 | lower_inode = ecryptfs_inode_to_lower(inode); | ||
| 546 | lower_file = ecryptfs_file_to_lower(file); | ||
| 547 | lower_a_ops = lower_inode->i_mapping->a_ops; | ||
| 548 | header_pages = ((crypt_stat->header_extent_size | ||
| 549 | * crypt_stat->num_header_extents_at_front) | ||
| 550 | / PAGE_CACHE_SIZE); | ||
| 551 | BUG_ON(header_pages < 1); | ||
| 552 | while (current_header_page < header_pages) { | ||
| 553 | rc = ecryptfs_grab_and_map_lower_page(&header_page, | ||
| 554 | &header_virt, | ||
| 555 | lower_inode, | ||
| 556 | current_header_page); | ||
| 557 | if (rc) { | ||
| 558 | ecryptfs_printk(KERN_ERR, "grab_cache_page for " | ||
| 559 | "header page [%d] failed; rc = [%d]\n", | ||
| 560 | current_header_page, rc); | ||
| 561 | goto out; | ||
| 562 | } | ||
| 563 | rc = lower_a_ops->prepare_write(lower_file, header_page, 0, | ||
| 564 | PAGE_CACHE_SIZE); | ||
| 565 | if (rc) { | ||
| 566 | ecryptfs_printk(KERN_ERR, "Error preparing to write " | ||
| 567 | "header page out; rc = [%d]\n", rc); | ||
| 568 | goto out; | ||
| 569 | } | ||
| 570 | memset(header_virt, 0, PAGE_CACHE_SIZE); | ||
| 571 | if (more_header_data_to_be_written) { | ||
| 572 | rc = ecryptfs_write_headers_virt(header_virt, | ||
| 573 | crypt_stat, | ||
| 574 | file->f_dentry); | ||
| 575 | if (rc) { | ||
| 576 | ecryptfs_printk(KERN_WARNING, "Error " | ||
| 577 | "generating header; rc = " | ||
| 578 | "[%d]\n", rc); | ||
| 579 | rc = -EIO; | ||
| 580 | memset(header_virt, 0, PAGE_CACHE_SIZE); | ||
| 581 | ecryptfs_unmap_and_release_lower_page( | ||
| 582 | header_page); | ||
| 583 | goto out; | ||
| 584 | } | ||
| 585 | if (current_header_page == 0) | ||
| 586 | memset(header_virt, 0, 8); | ||
| 587 | more_header_data_to_be_written = 0; | ||
| 588 | } | ||
| 589 | rc = lower_a_ops->commit_write(lower_file, header_page, 0, | ||
| 590 | PAGE_CACHE_SIZE); | ||
| 591 | ecryptfs_unmap_and_release_lower_page(header_page); | ||
| 592 | if (rc < 0) { | ||
| 593 | ecryptfs_printk(KERN_ERR, | ||
| 594 | "Error commiting header page write; " | ||
| 595 | "rc = [%d]\n", rc); | ||
| 596 | break; | ||
| 597 | } | ||
| 598 | current_header_page++; | ||
| 599 | } | ||
| 600 | if (rc >= 0) { | ||
| 601 | rc = 0; | ||
| 602 | ecryptfs_printk(KERN_DEBUG, "lower_inode->i_blocks = " | ||
| 603 | "[0x%.16x]\n", lower_inode->i_blocks); | ||
| 604 | i_size_write(inode, 0); | ||
| 605 | lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME; | ||
| 606 | mark_inode_dirty_sync(inode); | ||
| 607 | } | ||
| 608 | ecryptfs_printk(KERN_DEBUG, "Clearing ECRYPTFS_NEW_FILE flag in " | ||
| 609 | "crypt_stat at memory location [%p]\n", crypt_stat); | ||
| 610 | ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE); | ||
| 611 | out: | ||
| 612 | return rc; | ||
| 613 | } | ||
| 614 | |||
| 615 | /** | ||
| 616 | * ecryptfs_commit_write | ||
| 617 | * @file: The eCryptfs file object | ||
| 618 | * @page: The eCryptfs page | ||
| 619 | * @from: Ignored (we rotate the page IV on each write) | ||
| 620 | * @to: Ignored | ||
| 621 | * | ||
| 622 | * This is where we encrypt the data and pass the encrypted data to | ||
| 623 | * the lower filesystem. In OpenPGP-compatible mode, we operate on | ||
| 624 | * entire underlying packets. | ||
| 625 | */ | ||
| 626 | static int ecryptfs_commit_write(struct file *file, struct page *page, | ||
| 627 | unsigned from, unsigned to) | ||
| 628 | { | ||
| 629 | struct ecryptfs_page_crypt_context ctx; | ||
| 630 | loff_t pos; | ||
| 631 | struct inode *inode; | ||
| 632 | struct inode *lower_inode; | ||
| 633 | struct file *lower_file; | ||
| 634 | struct ecryptfs_crypt_stat *crypt_stat; | ||
| 635 | int rc; | ||
| 636 | |||
| 637 | inode = page->mapping->host; | ||
| 638 | lower_inode = ecryptfs_inode_to_lower(inode); | ||
| 639 | lower_file = ecryptfs_file_to_lower(file); | ||
| 640 | mutex_lock(&lower_inode->i_mutex); | ||
| 641 | crypt_stat = | ||
| 642 | &ecryptfs_inode_to_private(file->f_dentry->d_inode)->crypt_stat; | ||
| 643 | if (ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_NEW_FILE)) { | ||
| 644 | ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in " | ||
| 645 | "crypt_stat at memory location [%p]\n", crypt_stat); | ||
| 646 | rc = process_new_file(crypt_stat, file, inode); | ||
| 647 | if (rc) { | ||
| 648 | ecryptfs_printk(KERN_ERR, "Error processing new " | ||
| 649 | "file; rc = [%d]\n", rc); | ||
| 650 | goto out; | ||
| 651 | } | ||
| 652 | } else | ||
| 653 | ecryptfs_printk(KERN_DEBUG, "Not a new file\n"); | ||
| 654 | ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" | ||
| 655 | "(page w/ index = [0x%.16x], to = [%d])\n", page->index, | ||
| 656 | to); | ||
| 657 | rc = fill_zeros_to_end_of_page(page, to); | ||
| 658 | if (rc) { | ||
| 659 | ecryptfs_printk(KERN_WARNING, "Error attempting to fill " | ||
| 660 | "zeros in page with index = [0x%.16x]\n", | ||
| 661 | page->index); | ||
| 662 | goto out; | ||
| 663 | } | ||
| 664 | ctx.page = page; | ||
| 665 | ctx.mode = ECRYPTFS_PREPARE_COMMIT_MODE; | ||
| 666 | ctx.param.lower_file = lower_file; | ||
| 667 | rc = ecryptfs_encrypt_page(&ctx); | ||
| 668 | if (rc) { | ||
| 669 | ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper " | ||
| 670 | "index [0x%.16x])\n", page->index); | ||
| 671 | goto out; | ||
| 672 | } | ||
| 673 | rc = 0; | ||
| 674 | inode->i_blocks = lower_inode->i_blocks; | ||
| 675 | pos = (page->index << PAGE_CACHE_SHIFT) + to; | ||
| 676 | if (pos > i_size_read(inode)) { | ||
| 677 | i_size_write(inode, pos); | ||
| 678 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " | ||
| 679 | "[0x%.16x]\n", i_size_read(inode)); | ||
| 680 | } | ||
| 681 | ecryptfs_write_inode_size_to_header(lower_file, lower_inode, inode); | ||
| 682 | lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME; | ||
| 683 | mark_inode_dirty_sync(inode); | ||
| 684 | out: | ||
| 685 | kunmap(page); /* mapped in prior call (prepare_write) */ | ||
| 686 | if (rc < 0) | ||
| 687 | ClearPageUptodate(page); | ||
| 688 | else | ||
| 689 | SetPageUptodate(page); | ||
| 690 | mutex_unlock(&lower_inode->i_mutex); | ||
| 691 | return rc; | ||
| 692 | } | ||
| 693 | |||
| 694 | /** | ||
| 695 | * write_zeros | ||
| 696 | * @file: The ecryptfs file | ||
| 697 | * @index: The index in which we are writing | ||
| 698 | * @start: The position after the last block of data | ||
| 699 | * @num_zeros: The number of zeros to write | ||
| 700 | * | ||
| 701 | * Write a specified number of zero's to a page. | ||
| 702 | * | ||
| 703 | * (start + num_zeros) must be less than or equal to PAGE_CACHE_SIZE | ||
| 704 | */ | ||
| 705 | static | ||
| 706 | int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros) | ||
| 707 | { | ||
| 708 | int rc = 0; | ||
| 709 | struct page *tmp_page; | ||
| 710 | |||
| 711 | tmp_page = ecryptfs_get1page(file, index); | ||
| 712 | if (IS_ERR(tmp_page)) { | ||
| 713 | ecryptfs_printk(KERN_ERR, "Error getting page at index " | ||
| 714 | "[0x%.16x]\n", index); | ||
| 715 | rc = PTR_ERR(tmp_page); | ||
| 716 | goto out; | ||
| 717 | } | ||
| 718 | kmap(tmp_page); | ||
| 719 | rc = ecryptfs_prepare_write(file, tmp_page, start, start + num_zeros); | ||
| 720 | if (rc) { | ||
| 721 | ecryptfs_printk(KERN_ERR, "Error preparing to write zero's " | ||
| 722 | "to remainder of page at index [0x%.16x]\n", | ||
| 723 | index); | ||
| 724 | kunmap(tmp_page); | ||
| 725 | page_cache_release(tmp_page); | ||
| 726 | goto out; | ||
| 727 | } | ||
| 728 | memset(((char *)page_address(tmp_page) + start), 0, num_zeros); | ||
| 729 | rc = ecryptfs_commit_write(file, tmp_page, start, start + num_zeros); | ||
| 730 | if (rc < 0) { | ||
| 731 | ecryptfs_printk(KERN_ERR, "Error attempting to write zero's " | ||
| 732 | "to remainder of page at index [0x%.16x]\n", | ||
| 733 | index); | ||
| 734 | kunmap(tmp_page); | ||
| 735 | page_cache_release(tmp_page); | ||
| 736 | goto out; | ||
| 737 | } | ||
| 738 | rc = 0; | ||
| 739 | kunmap(tmp_page); | ||
| 740 | page_cache_release(tmp_page); | ||
| 741 | out: | ||
| 742 | return rc; | ||
| 743 | } | ||
| 744 | |||
| 745 | static sector_t ecryptfs_bmap(struct address_space *mapping, sector_t block) | ||
| 746 | { | ||
| 747 | int rc = 0; | ||
| 748 | struct inode *inode; | ||
| 749 | struct inode *lower_inode; | ||
| 750 | |||
| 751 | inode = (struct inode *)mapping->host; | ||
| 752 | lower_inode = ecryptfs_inode_to_lower(inode); | ||
| 753 | if (lower_inode->i_mapping->a_ops->bmap) | ||
| 754 | rc = lower_inode->i_mapping->a_ops->bmap(lower_inode->i_mapping, | ||
| 755 | block); | ||
| 756 | return rc; | ||
| 757 | } | ||
| 758 | |||
| 759 | static void ecryptfs_sync_page(struct page *page) | ||
| 760 | { | ||
| 761 | struct inode *inode; | ||
| 762 | struct inode *lower_inode; | ||
| 763 | struct page *lower_page; | ||
| 764 | |||
| 765 | inode = page->mapping->host; | ||
| 766 | lower_inode = ecryptfs_inode_to_lower(inode); | ||
| 767 | /* NOTE: Recently swapped with grab_cache_page(), since | ||
| 768 | * sync_page() just makes sure that pending I/O gets done. */ | ||
| 769 | lower_page = find_lock_page(lower_inode->i_mapping, page->index); | ||
| 770 | if (!lower_page) { | ||
| 771 | ecryptfs_printk(KERN_DEBUG, "find_lock_page failed\n"); | ||
| 772 | return; | ||
| 773 | } | ||
| 774 | lower_page->mapping->a_ops->sync_page(lower_page); | ||
| 775 | ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n", | ||
| 776 | lower_page->index); | ||
| 777 | unlock_page(lower_page); | ||
| 778 | page_cache_release(lower_page); | ||
| 779 | } | ||
| 780 | |||
| 781 | struct address_space_operations ecryptfs_aops = { | ||
| 782 | .writepage = ecryptfs_writepage, | ||
| 783 | .readpage = ecryptfs_readpage, | ||
| 784 | .prepare_write = ecryptfs_prepare_write, | ||
| 785 | .commit_write = ecryptfs_commit_write, | ||
| 786 | .bmap = ecryptfs_bmap, | ||
| 787 | .sync_page = ecryptfs_sync_page, | ||
| 788 | }; | ||
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c new file mode 100644 index 000000000000..c337c0410fb1 --- /dev/null +++ b/fs/ecryptfs/super.c | |||
| @@ -0,0 +1,198 @@ | |||
| 1 | /** | ||
| 2 | * eCryptfs: Linux filesystem encryption layer | ||
| 3 | * | ||
| 4 | * Copyright (C) 1997-2003 Erez Zadok | ||
| 5 | * Copyright (C) 2001-2003 Stony Brook University | ||
| 6 | * Copyright (C) 2004-2006 International Business Machines Corp. | ||
| 7 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> | ||
| 8 | * Michael C. Thompson <mcthomps@us.ibm.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or | ||
| 11 | * modify it under the terms of the GNU General Public License as | ||
| 12 | * published by the Free Software Foundation; either version 2 of the | ||
| 13 | * License, or (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, but | ||
| 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 18 | * General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
| 23 | * 02111-1307, USA. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <linux/fs.h> | ||
| 27 | #include <linux/mount.h> | ||
| 28 | #include <linux/key.h> | ||
| 29 | #include <linux/seq_file.h> | ||
| 30 | #include <linux/crypto.h> | ||
| 31 | #include "ecryptfs_kernel.h" | ||
| 32 | |||
| 33 | struct kmem_cache *ecryptfs_inode_info_cache; | ||
| 34 | |||
| 35 | /** | ||
| 36 | * ecryptfs_alloc_inode - allocate an ecryptfs inode | ||
| 37 | * @sb: Pointer to the ecryptfs super block | ||
| 38 | * | ||
| 39 | * Called to bring an inode into existence. | ||
| 40 | * | ||
| 41 | * Only handle allocation, setting up structures should be done in | ||
| 42 | * ecryptfs_read_inode. This is because the kernel, between now and | ||
| 43 | * then, will 0 out the private data pointer. | ||
| 44 | * | ||
| 45 | * Returns a pointer to a newly allocated inode, NULL otherwise | ||
| 46 | */ | ||
| 47 | static struct inode *ecryptfs_alloc_inode(struct super_block *sb) | ||
| 48 | { | ||
| 49 | struct ecryptfs_inode_info *ecryptfs_inode; | ||
| 50 | struct inode *inode = NULL; | ||
| 51 | |||
| 52 | ecryptfs_inode = kmem_cache_alloc(ecryptfs_inode_info_cache, | ||
| 53 | SLAB_KERNEL); | ||
| 54 | if (unlikely(!ecryptfs_inode)) | ||
| 55 | goto out; | ||
| 56 | ecryptfs_init_crypt_stat(&ecryptfs_inode->crypt_stat); | ||
| 57 | inode = &ecryptfs_inode->vfs_inode; | ||
| 58 | out: | ||
| 59 | return inode; | ||
| 60 | } | ||
| 61 | |||
| 62 | /** | ||
| 63 | * ecryptfs_destroy_inode | ||
| 64 | * @inode: The ecryptfs inode | ||
| 65 | * | ||
| 66 | * This is used during the final destruction of the inode. | ||
| 67 | * All allocation of memory related to the inode, including allocated | ||
| 68 | * memory in the crypt_stat struct, will be released here. | ||
| 69 | * There should be no chance that this deallocation will be missed. | ||
| 70 | */ | ||
| 71 | static void ecryptfs_destroy_inode(struct inode *inode) | ||
| 72 | { | ||
| 73 | struct ecryptfs_inode_info *inode_info; | ||
| 74 | |||
| 75 | inode_info = ecryptfs_inode_to_private(inode); | ||
| 76 | ecryptfs_destruct_crypt_stat(&inode_info->crypt_stat); | ||
| 77 | kmem_cache_free(ecryptfs_inode_info_cache, inode_info); | ||
| 78 | } | ||
| 79 | |||
| 80 | /** | ||
| 81 | * ecryptfs_init_inode | ||
| 82 | * @inode: The ecryptfs inode | ||
| 83 | * | ||
| 84 | * Set up the ecryptfs inode. | ||
| 85 | */ | ||
| 86 | void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode) | ||
| 87 | { | ||
| 88 | ecryptfs_set_inode_lower(inode, lower_inode); | ||
| 89 | inode->i_ino = lower_inode->i_ino; | ||
| 90 | inode->i_version++; | ||
| 91 | inode->i_op = &ecryptfs_main_iops; | ||
| 92 | inode->i_fop = &ecryptfs_main_fops; | ||
| 93 | inode->i_mapping->a_ops = &ecryptfs_aops; | ||
| 94 | } | ||
| 95 | |||
| 96 | /** | ||
| 97 | * ecryptfs_put_super | ||
| 98 | * @sb: Pointer to the ecryptfs super block | ||
| 99 | * | ||
| 100 | * Final actions when unmounting a file system. | ||
| 101 | * This will handle deallocation and release of our private data. | ||
| 102 | */ | ||
| 103 | static void ecryptfs_put_super(struct super_block *sb) | ||
| 104 | { | ||
| 105 | struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb); | ||
| 106 | |||
| 107 | ecryptfs_destruct_mount_crypt_stat(&sb_info->mount_crypt_stat); | ||
| 108 | kmem_cache_free(ecryptfs_sb_info_cache, sb_info); | ||
| 109 | ecryptfs_set_superblock_private(sb, NULL); | ||
| 110 | } | ||
| 111 | |||
| 112 | /** | ||
| 113 | * ecryptfs_statfs | ||
| 114 | * @sb: The ecryptfs super block | ||
| 115 | * @buf: The struct kstatfs to fill in with stats | ||
| 116 | * | ||
| 117 | * Get the filesystem statistics. Currently, we let this pass right through | ||
| 118 | * to the lower filesystem and take no action ourselves. | ||
| 119 | */ | ||
| 120 | static int ecryptfs_statfs(struct dentry *dentry, struct kstatfs *buf) | ||
| 121 | { | ||
| 122 | return vfs_statfs(ecryptfs_dentry_to_lower(dentry), buf); | ||
| 123 | } | ||
| 124 | |||
| 125 | /** | ||
| 126 | * ecryptfs_clear_inode | ||
| 127 | * @inode - The ecryptfs inode | ||
| 128 | * | ||
| 129 | * Called by iput() when the inode reference count reached zero | ||
| 130 | * and the inode is not hashed anywhere. Used to clear anything | ||
| 131 | * that needs to be, before the inode is completely destroyed and put | ||
| 132 | * on the inode free list. We use this to drop out reference to the | ||
| 133 | * lower inode. | ||
| 134 | */ | ||
| 135 | static void ecryptfs_clear_inode(struct inode *inode) | ||
| 136 | { | ||
| 137 | iput(ecryptfs_inode_to_lower(inode)); | ||
| 138 | } | ||
| 139 | |||
| 140 | /** | ||
| 141 | * ecryptfs_umount_begin | ||
| 142 | * | ||
| 143 | * Called in do_umount(). | ||
| 144 | */ | ||
| 145 | static void ecryptfs_umount_begin(struct vfsmount *vfsmnt, int flags) | ||
| 146 | { | ||
| 147 | struct vfsmount *lower_mnt = | ||
| 148 | ecryptfs_dentry_to_lower_mnt(vfsmnt->mnt_sb->s_root); | ||
| 149 | struct super_block *lower_sb; | ||
| 150 | |||
| 151 | mntput(lower_mnt); | ||
| 152 | lower_sb = lower_mnt->mnt_sb; | ||
| 153 | if (lower_sb->s_op->umount_begin) | ||
| 154 | lower_sb->s_op->umount_begin(lower_mnt, flags); | ||
| 155 | } | ||
| 156 | |||
| 157 | /** | ||
| 158 | * ecryptfs_show_options | ||
| 159 | * | ||
| 160 | * Prints the directory we are currently mounted over. | ||
| 161 | * Returns zero on success; non-zero otherwise | ||
| 162 | */ | ||
| 163 | static int ecryptfs_show_options(struct seq_file *m, struct vfsmount *mnt) | ||
| 164 | { | ||
| 165 | struct super_block *sb = mnt->mnt_sb; | ||
| 166 | struct dentry *lower_root_dentry = ecryptfs_dentry_to_lower(sb->s_root); | ||
| 167 | struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(sb->s_root); | ||
| 168 | char *tmp_page; | ||
| 169 | char *path; | ||
| 170 | int rc = 0; | ||
| 171 | |||
| 172 | tmp_page = (char *)__get_free_page(GFP_KERNEL); | ||
| 173 | if (!tmp_page) { | ||
| 174 | rc = -ENOMEM; | ||
| 175 | goto out; | ||
| 176 | } | ||
| 177 | path = d_path(lower_root_dentry, lower_mnt, tmp_page, PAGE_SIZE); | ||
| 178 | if (IS_ERR(path)) { | ||
| 179 | rc = PTR_ERR(path); | ||
| 180 | goto out; | ||
| 181 | } | ||
| 182 | seq_printf(m, ",dir=%s", path); | ||
| 183 | free_page((unsigned long)tmp_page); | ||
| 184 | out: | ||
| 185 | return rc; | ||
| 186 | } | ||
| 187 | |||
| 188 | struct super_operations ecryptfs_sops = { | ||
| 189 | .alloc_inode = ecryptfs_alloc_inode, | ||
| 190 | .destroy_inode = ecryptfs_destroy_inode, | ||
| 191 | .drop_inode = generic_delete_inode, | ||
| 192 | .put_super = ecryptfs_put_super, | ||
| 193 | .statfs = ecryptfs_statfs, | ||
| 194 | .remount_fs = NULL, | ||
| 195 | .clear_inode = ecryptfs_clear_inode, | ||
| 196 | .umount_begin = ecryptfs_umount_begin, | ||
| 197 | .show_options = ecryptfs_show_options | ||
| 198 | }; | ||
