mmap.c 13.4 KB
Newer Older
1 2 3 4 5 6 7 8
/**
 * eCryptfs: Linux filesystem encryption layer
 * This is where eCryptfs coordinates the symmetric encryption and
 * decryption of the file data as it passes between the lower
 * encrypted file and the upper decrypted file.
 *
 * Copyright (C) 1997-2003 Erez Zadok
 * Copyright (C) 2001-2003 Stony Brook University
9
 * Copyright (C) 2004-2007 International Business Machines Corp.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
 *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */

#include <linux/pagemap.h>
#include <linux/writeback.h>
#include <linux/page-flags.h>
#include <linux/mount.h>
#include <linux/file.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include "ecryptfs_kernel.h"

struct kmem_cache *ecryptfs_lower_page_cache;

/**
 * ecryptfs_get1page
 *
 * Get one page from cache or lower f/s, return error otherwise.
 *
 * Returns unlocked and up-to-date page (if ok), with increased
 * refcnt.
 */
M
Michael Halcrow 已提交
47
struct page *ecryptfs_get1page(struct file *file, loff_t index)
48 49 50 51 52
{
	struct dentry *dentry;
	struct inode *inode;
	struct address_space *mapping;

53
	dentry = file->f_path.dentry;
54 55
	inode = dentry->d_inode;
	mapping = inode->i_mapping;
56
	return read_mapping_page(mapping, index, (void *)file);
57 58 59 60 61 62 63 64 65 66 67 68
}

/**
 * ecryptfs_writepage
 * @page: Page that is locked before this call is made
 *
 * Returns zero on success; non-zero otherwise
 */
static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc)
{
	int rc;

69
	rc = ecryptfs_encrypt_page(page);
70 71 72 73 74 75 76 77 78 79 80 81
	if (rc) {
		ecryptfs_printk(KERN_WARNING, "Error encrypting "
				"page (upper index [0x%.16x])\n", page->index);
		ClearPageUptodate(page);
		goto out;
	}
	SetPageUptodate(page);
	unlock_page(page);
out:
	return rc;
}

82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
/**
 *   Header Extent:
 *     Octets 0-7:        Unencrypted file size (big-endian)
 *     Octets 8-15:       eCryptfs special marker
 *     Octets 16-19:      Flags
 *      Octet 16:         File format version number (between 0 and 255)
 *      Octets 17-18:     Reserved
 *      Octet 19:         Bit 1 (lsb): Reserved
 *                        Bit 2: Encrypted?
 *                        Bits 3-8: Reserved
 *     Octets 20-23:      Header extent size (big-endian)
 *     Octets 24-25:      Number of header extents at front of file
 *                        (big-endian)
 *     Octet  26:         Begin RFC 2440 authentication token packet set
 */
static void set_header_info(char *page_virt,
			    struct ecryptfs_crypt_stat *crypt_stat)
{
	size_t written;
	int save_num_header_extents_at_front =
		crypt_stat->num_header_extents_at_front;

	crypt_stat->num_header_extents_at_front = 1;
	ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written);
	crypt_stat->num_header_extents_at_front =
		save_num_header_extents_at_front;
}
109

110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
/**
 * ecryptfs_copy_up_encrypted_with_header
 * @page: Sort of a ``virtual'' representation of the encrypted lower
 *        file. The actual lower file does not have the metadata in
 *        the header. This is locked.
 * @crypt_stat: The eCryptfs inode's cryptographic context
 *
 * The ``view'' is the version of the file that userspace winds up
 * seeing, with the header information inserted.
 */
static int
ecryptfs_copy_up_encrypted_with_header(struct page *page,
				       struct ecryptfs_crypt_stat *crypt_stat)
{
	loff_t extent_num_in_page = 0;
	loff_t num_extents_per_page = (PAGE_CACHE_SIZE
				       / crypt_stat->extent_size);
	int rc = 0;

	while (extent_num_in_page < num_extents_per_page) {
M
Michael Halcrow 已提交
130 131
		loff_t view_extent_num = ((((loff_t)page->index)
					   * num_extents_per_page)
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
					  + extent_num_in_page);

		if (view_extent_num < crypt_stat->num_header_extents_at_front) {
			/* This is a header extent */
			char *page_virt;

			page_virt = kmap_atomic(page, KM_USER0);
			memset(page_virt, 0, PAGE_CACHE_SIZE);
			/* TODO: Support more than one header extent */
			if (view_extent_num == 0) {
				rc = ecryptfs_read_xattr_region(
					page_virt, page->mapping->host);
				set_header_info(page_virt, crypt_stat);
			}
			kunmap_atomic(page_virt, KM_USER0);
			flush_dcache_page(page);
			if (rc) {
				ClearPageUptodate(page);
				printk(KERN_ERR "%s: Error reading xattr "
				       "region; rc = [%d]\n", __FUNCTION__, rc);
				goto out;
			}
			SetPageUptodate(page);
		} else {
			/* This is an encrypted data extent */
			loff_t lower_offset =
				((view_extent_num -
				  crypt_stat->num_header_extents_at_front)
				 * crypt_stat->extent_size);

			rc = ecryptfs_read_lower_page_segment(
				page, (lower_offset >> PAGE_CACHE_SHIFT),
				(lower_offset & ~PAGE_CACHE_MASK),
				crypt_stat->extent_size, page->mapping->host);
			if (rc) {
				printk(KERN_ERR "%s: Error attempting to read "
				       "extent at offset [%lld] in the lower "
				       "file; rc = [%d]\n", __FUNCTION__,
				       lower_offset, rc);
				goto out;
			}
		}
		extent_num_in_page++;
	}
out:
	return rc;
}

180 181
/**
 * ecryptfs_readpage
182 183
 * @file: An eCryptfs file
 * @page: Page from eCryptfs inode mapping into which to stick the read data
184 185 186 187 188 189 190
 *
 * Read in a page, decrypting if necessary.
 *
 * Returns zero on success; non-zero on error.
 */
static int ecryptfs_readpage(struct file *file, struct page *page)
{
191 192
	struct ecryptfs_crypt_stat *crypt_stat =
		&ecryptfs_inode_to_private(file->f_path.dentry->d_inode)->crypt_stat;
193 194 195
	int rc = 0;

	if (!crypt_stat
196 197
	    || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED)
	    || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) {
198 199
		ecryptfs_printk(KERN_DEBUG,
				"Passing through unencrypted page\n");
200 201 202
		rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
						      PAGE_CACHE_SIZE,
						      page->mapping->host);
203 204
	} else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) {
		if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
205 206 207 208 209 210 211 212 213
			rc = ecryptfs_copy_up_encrypted_with_header(page,
								    crypt_stat);
			if (rc) {
				printk(KERN_ERR "%s: Error attempting to copy "
				       "the encrypted content from the lower "
				       "file whilst inserting the metadata "
				       "from the xattr into the header; rc = "
				       "[%d]\n", __FUNCTION__, rc);
				goto out;
214
			}
215

216
		} else {
217 218 219
			rc = ecryptfs_read_lower_page_segment(
				page, page->index, 0, PAGE_CACHE_SIZE,
				page->mapping->host);
220 221 222 223 224 225
			if (rc) {
				printk(KERN_ERR "Error reading page; rc = "
				       "[%d]\n", rc);
				goto out;
			}
		}
226
	} else {
227
		rc = ecryptfs_decrypt_page(page);
228 229 230 231 232 233 234 235 236 237 238 239 240
		if (rc) {
			ecryptfs_printk(KERN_ERR, "Error decrypting page; "
					"rc = [%d]\n", rc);
			goto out;
		}
	}
out:
	ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n",
			page->index);
	unlock_page(page);
	return rc;
}

241 242 243
/**
 * Called with lower inode mutex held.
 */
244 245 246 247 248
static int fill_zeros_to_end_of_page(struct page *page, unsigned int to)
{
	struct inode *inode = page->mapping->host;
	int end_byte_in_page;

249 250 251 252 253
	if ((i_size_read(inode) / PAGE_CACHE_SIZE) != page->index)
		goto out;
	end_byte_in_page = i_size_read(inode) % PAGE_CACHE_SIZE;
	if (to > end_byte_in_page)
		end_byte_in_page = to;
N
Nate Diller 已提交
254 255
	zero_user_page(page, end_byte_in_page,
		PAGE_CACHE_SIZE - end_byte_in_page, KM_USER0);
256
out:
257
	return 0;
258 259 260 261 262 263 264 265 266 267 268
}

static int ecryptfs_prepare_write(struct file *file, struct page *page,
				  unsigned from, unsigned to)
{
	int rc = 0;

	if (from == 0 && to == PAGE_CACHE_SIZE)
		goto out;	/* If we are writing a full page, it will be
				   up to date. */
	if (!PageUptodate(page))
269 270 271
		rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
						      PAGE_CACHE_SIZE,
						      page->mapping->host);
272
	if (page->index != 0) {
273 274
		loff_t end_of_prev_pg_pos =
			(((loff_t)page->index << PAGE_CACHE_SHIFT) - 1);
275 276 277 278 279 280 281 282 283 284

		if (end_of_prev_pg_pos > i_size_read(page->mapping->host)) {
			rc = ecryptfs_truncate(file->f_path.dentry,
					       end_of_prev_pg_pos);
			if (rc) {
				printk(KERN_ERR "Error on attempt to "
				       "truncate to (higher) offset [%lld];"
				       " rc = [%d]\n", end_of_prev_pg_pos, rc);
				goto out;
			}
285
		}
286 287
		if (end_of_prev_pg_pos + 1 > i_size_read(page->mapping->host))
			zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0);
288
	}
289 290 291 292 293 294 295 296 297 298 299
out:
	return rc;
}

/**
 * ecryptfs_write_inode_size_to_header
 *
 * Writes the lower file size to the first 8 bytes of the header.
 *
 * Returns zero on success; non-zero on error.
 */
300
static int ecryptfs_write_inode_size_to_header(struct inode *ecryptfs_inode)
301 302
{
	u64 file_size;
303 304
	char *file_size_virt;
	int rc;
305

306 307 308
	file_size_virt = kmalloc(sizeof(u64), GFP_KERNEL);
	if (!file_size_virt) {
		rc = -ENOMEM;
309 310
		goto out;
	}
311
	file_size = (u64)i_size_read(ecryptfs_inode);
312
	file_size = cpu_to_be64(file_size);
313 314 315 316 317 318 319
	memcpy(file_size_virt, &file_size, sizeof(u64));
	rc = ecryptfs_write_lower(ecryptfs_inode, file_size_virt, 0,
				  sizeof(u64));
	kfree(file_size_virt);
	if (rc)
		printk(KERN_ERR "%s: Error writing file size to header; "
		       "rc = [%d]\n", __FUNCTION__, rc);
320 321 322 323
out:
	return rc;
}

324 325 326
struct kmem_cache *ecryptfs_xattr_cache;

static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
327 328 329
{
	ssize_t size;
	void *xattr_virt;
330 331 332
	struct dentry *lower_dentry =
		ecryptfs_inode_to_private(ecryptfs_inode)->lower_file->f_dentry;
	struct inode *lower_inode = lower_dentry->d_inode;
333 334 335
	u64 file_size;
	int rc;

336 337 338 339 340 341
	if (!lower_inode->i_op->getxattr || !lower_inode->i_op->setxattr) {
		printk(KERN_WARNING
		       "No support for setting xattr in lower filesystem\n");
		rc = -ENOSYS;
		goto out;
	}
342 343 344 345 346 347 348
	xattr_virt = kmem_cache_alloc(ecryptfs_xattr_cache, GFP_KERNEL);
	if (!xattr_virt) {
		printk(KERN_ERR "Out of memory whilst attempting to write "
		       "inode size to xattr\n");
		rc = -ENOMEM;
		goto out;
	}
349 350 351
	mutex_lock(&lower_inode->i_mutex);
	size = lower_inode->i_op->getxattr(lower_dentry, ECRYPTFS_XATTR_NAME,
					   xattr_virt, PAGE_CACHE_SIZE);
352 353
	if (size < 0)
		size = 8;
354
	file_size = (u64)i_size_read(ecryptfs_inode);
355 356
	file_size = cpu_to_be64(file_size);
	memcpy(xattr_virt, &file_size, sizeof(u64));
357 358 359
	rc = lower_inode->i_op->setxattr(lower_dentry, ECRYPTFS_XATTR_NAME,
					 xattr_virt, size, 0);
	mutex_unlock(&lower_inode->i_mutex);
360 361 362 363 364 365 366 367
	if (rc)
		printk(KERN_ERR "Error whilst attempting to write inode size "
		       "to lower file xattr; rc = [%d]\n", rc);
	kmem_cache_free(ecryptfs_xattr_cache, xattr_virt);
out:
	return rc;
}

368
int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode)
369 370 371
{
	struct ecryptfs_crypt_stat *crypt_stat;

372
	crypt_stat = &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
373
	if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
374
		return ecryptfs_write_inode_size_to_xattr(ecryptfs_inode);
375
	else
376
		return ecryptfs_write_inode_size_to_header(ecryptfs_inode);
377 378
}

379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
/**
 * ecryptfs_commit_write
 * @file: The eCryptfs file object
 * @page: The eCryptfs page
 * @from: Ignored (we rotate the page IV on each write)
 * @to: Ignored
 *
 * This is where we encrypt the data and pass the encrypted data to
 * the lower filesystem.  In OpenPGP-compatible mode, we operate on
 * entire underlying packets.
 */
static int ecryptfs_commit_write(struct file *file, struct page *page,
				 unsigned from, unsigned to)
{
	loff_t pos;
394 395 396
	struct inode *ecryptfs_inode = page->mapping->host;
	struct ecryptfs_crypt_stat *crypt_stat =
		&ecryptfs_inode_to_private(file->f_path.dentry->d_inode)->crypt_stat;
397 398
	int rc;

399
	if (crypt_stat->flags & ECRYPTFS_NEW_FILE) {
400 401
		ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in "
			"crypt_stat at memory location [%p]\n", crypt_stat);
402
		crypt_stat->flags &= ~(ECRYPTFS_NEW_FILE);
403 404 405 406 407
	} else
		ecryptfs_printk(KERN_DEBUG, "Not a new file\n");
	ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page"
			"(page w/ index = [0x%.16x], to = [%d])\n", page->index,
			to);
408
	/* Fills in zeros if 'to' goes beyond inode size */
409 410 411 412 413 414 415
	rc = fill_zeros_to_end_of_page(page, to);
	if (rc) {
		ecryptfs_printk(KERN_WARNING, "Error attempting to fill "
				"zeros in page with index = [0x%.16x]\n",
				page->index);
		goto out;
	}
416
	rc = ecryptfs_encrypt_page(page);
417 418 419 420 421
	if (rc) {
		ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper "
				"index [0x%.16x])\n", page->index);
		goto out;
	}
M
Michael Halcrow 已提交
422
	pos = (((loff_t)page->index) << PAGE_CACHE_SHIFT) + to;
423 424
	if (pos > i_size_read(ecryptfs_inode)) {
		i_size_write(ecryptfs_inode, pos);
425
		ecryptfs_printk(KERN_DEBUG, "Expanded file size to "
426
				"[0x%.16x]\n", i_size_read(ecryptfs_inode));
427
	}
428
	rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
429 430 431
	if (rc)
		printk(KERN_ERR "Error writing inode size to metadata; "
		       "rc = [%d]\n", rc);
432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
out:
	return rc;
}

static sector_t ecryptfs_bmap(struct address_space *mapping, sector_t block)
{
	int rc = 0;
	struct inode *inode;
	struct inode *lower_inode;

	inode = (struct inode *)mapping->host;
	lower_inode = ecryptfs_inode_to_lower(inode);
	if (lower_inode->i_mapping->a_ops->bmap)
		rc = lower_inode->i_mapping->a_ops->bmap(lower_inode->i_mapping,
							 block);
	return rc;
}

struct address_space_operations ecryptfs_aops = {
	.writepage = ecryptfs_writepage,
	.readpage = ecryptfs_readpage,
	.prepare_write = ecryptfs_prepare_write,
	.commit_write = ecryptfs_commit_write,
	.bmap = ecryptfs_bmap,
};