diff options
Diffstat (limited to 'fs/ecryptfs/mmap.c')
-rw-r--r-- | fs/ecryptfs/mmap.c | 74 |
1 files changed, 73 insertions, 1 deletions
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index ba3650d03c48..3386014becc6 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -260,6 +260,33 @@ out: | |||
260 | ClearPageUptodate(page); | 260 | ClearPageUptodate(page); |
261 | return rc; | 261 | return rc; |
262 | } | 262 | } |
263 | /** | ||
264 | * Header Extent: | ||
265 | * Octets 0-7: Unencrypted file size (big-endian) | ||
266 | * Octets 8-15: eCryptfs special marker | ||
267 | * Octets 16-19: Flags | ||
268 | * Octet 16: File format version number (between 0 and 255) | ||
269 | * Octets 17-18: Reserved | ||
270 | * Octet 19: Bit 1 (lsb): Reserved | ||
271 | * Bit 2: Encrypted? | ||
272 | * Bits 3-8: Reserved | ||
273 | * Octets 20-23: Header extent size (big-endian) | ||
274 | * Octets 24-25: Number of header extents at front of file | ||
275 | * (big-endian) | ||
276 | * Octet 26: Begin RFC 2440 authentication token packet set | ||
277 | */ | ||
278 | static void set_header_info(char *page_virt, | ||
279 | struct ecryptfs_crypt_stat *crypt_stat) | ||
280 | { | ||
281 | size_t written; | ||
282 | int save_num_header_extents_at_front = | ||
283 | crypt_stat->num_header_extents_at_front; | ||
284 | |||
285 | crypt_stat->num_header_extents_at_front = 1; | ||
286 | ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written); | ||
287 | crypt_stat->num_header_extents_at_front = | ||
288 | save_num_header_extents_at_front; | ||
289 | } | ||
263 | 290 | ||
264 | /** | 291 | /** |
265 | * ecryptfs_readpage | 292 | * ecryptfs_readpage |
@@ -289,10 +316,55 @@ static int ecryptfs_readpage(struct file *file, struct page *page) | |||
289 | "[%d]\n", rc); | 316 | "[%d]\n", rc); |
290 | goto out; | 317 | goto out; |
291 | } | 318 | } |
319 | } else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) { | ||
320 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) { | ||
321 | int num_pages_in_header_region = | ||
322 | (crypt_stat->header_extent_size | ||
323 | / PAGE_CACHE_SIZE); | ||
324 | |||
325 | if (page->index < num_pages_in_header_region) { | ||
326 | char *page_virt; | ||
327 | |||
328 | page_virt = (char *)kmap(page); | ||
329 | if (!page_virt) { | ||
330 | rc = -ENOMEM; | ||
331 | printk(KERN_ERR "Error mapping page\n"); | ||
332 | goto out; | ||
333 | } | ||
334 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
335 | if (page->index == 0) { | ||
336 | rc = ecryptfs_read_xattr_region( | ||
337 | page_virt, file->f_path.dentry); | ||
338 | set_header_info(page_virt, crypt_stat); | ||
339 | } | ||
340 | kunmap(page); | ||
341 | if (rc) { | ||
342 | printk(KERN_ERR "Error reading xattr " | ||
343 | "region\n"); | ||
344 | goto out; | ||
345 | } | ||
346 | } else { | ||
347 | rc = ecryptfs_do_readpage( | ||
348 | file, page, | ||
349 | (page->index | ||
350 | - num_pages_in_header_region)); | ||
351 | if (rc) { | ||
352 | printk(KERN_ERR "Error reading page; " | ||
353 | "rc = [%d]\n", rc); | ||
354 | goto out; | ||
355 | } | ||
356 | } | ||
357 | } else { | ||
358 | rc = ecryptfs_do_readpage(file, page, page->index); | ||
359 | if (rc) { | ||
360 | printk(KERN_ERR "Error reading page; rc = " | ||
361 | "[%d]\n", rc); | ||
362 | goto out; | ||
363 | } | ||
364 | } | ||
292 | } else { | 365 | } else { |
293 | rc = ecryptfs_decrypt_page(file, page); | 366 | rc = ecryptfs_decrypt_page(file, page); |
294 | if (rc) { | 367 | if (rc) { |
295 | |||
296 | ecryptfs_printk(KERN_ERR, "Error decrypting page; " | 368 | ecryptfs_printk(KERN_ERR, "Error decrypting page; " |
297 | "rc = [%d]\n", rc); | 369 | "rc = [%d]\n", rc); |
298 | goto out; | 370 | goto out; |