diff options
-rw-r--r-- | fs/ecryptfs/crypto.c | 15 | ||||
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 7 | ||||
-rw-r--r-- | fs/ecryptfs/file.c | 13 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 15 | ||||
-rw-r--r-- | fs/ecryptfs/mmap.c | 74 |
5 files changed, 113 insertions, 11 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 96fa40a48b4..44c2ec2e9e6 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -1256,9 +1256,10 @@ out: | |||
1256 | } | 1256 | } |
1257 | 1257 | ||
1258 | 1258 | ||
1259 | static void | 1259 | void |
1260 | write_header_metadata(char *virt, struct ecryptfs_crypt_stat *crypt_stat, | 1260 | ecryptfs_write_header_metadata(char *virt, |
1261 | size_t *written) | 1261 | struct ecryptfs_crypt_stat *crypt_stat, |
1262 | size_t *written) | ||
1262 | { | 1263 | { |
1263 | u32 header_extent_size; | 1264 | u32 header_extent_size; |
1264 | u16 num_header_extents_at_front; | 1265 | u16 num_header_extents_at_front; |
@@ -1320,7 +1321,8 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t *size, | |||
1320 | offset += written; | 1321 | offset += written; |
1321 | write_ecryptfs_flags((page_virt + offset), crypt_stat, &written); | 1322 | write_ecryptfs_flags((page_virt + offset), crypt_stat, &written); |
1322 | offset += written; | 1323 | offset += written; |
1323 | write_header_metadata((page_virt + offset), crypt_stat, &written); | 1324 | ecryptfs_write_header_metadata((page_virt + offset), crypt_stat, |
1325 | &written); | ||
1324 | offset += written; | 1326 | offset += written; |
1325 | rc = ecryptfs_generate_key_packet_set((page_virt + offset), crypt_stat, | 1327 | rc = ecryptfs_generate_key_packet_set((page_virt + offset), crypt_stat, |
1326 | ecryptfs_dentry, &written, | 1328 | ecryptfs_dentry, &written, |
@@ -1606,7 +1608,12 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry, | |||
1606 | ssize_t bytes_read; | 1608 | ssize_t bytes_read; |
1607 | struct ecryptfs_crypt_stat *crypt_stat = | 1609 | struct ecryptfs_crypt_stat *crypt_stat = |
1608 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; | 1610 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; |
1611 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | ||
1612 | &ecryptfs_superblock_to_private( | ||
1613 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | ||
1609 | 1614 | ||
1615 | ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat, | ||
1616 | mount_crypt_stat); | ||
1610 | /* Read the first page from the underlying file */ | 1617 | /* Read the first page from the underlying file */ |
1611 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, GFP_USER); | 1618 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, GFP_USER); |
1612 | if (!page_virt) { | 1619 | if (!page_virt) { |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 020abcd16f0..ec526df4235 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -559,7 +559,7 @@ ssize_t ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value, | |||
559 | int | 559 | int |
560 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 560 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
561 | size_t size, int flags); | 561 | size_t size, int flags); |
562 | 562 | int ecryptfs_read_xattr_region(char *page_virt, struct dentry *ecryptfs_dentry); | |
563 | int ecryptfs_process_helo(unsigned int transport, uid_t uid, pid_t pid); | 563 | int ecryptfs_process_helo(unsigned int transport, uid_t uid, pid_t pid); |
564 | int ecryptfs_process_quit(uid_t uid, pid_t pid); | 564 | int ecryptfs_process_quit(uid_t uid, pid_t pid); |
565 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t uid, | 565 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t uid, |
@@ -582,6 +582,9 @@ int ecryptfs_send_connector(char *data, int data_len, | |||
582 | u16 msg_flags, pid_t daemon_pid); | 582 | u16 msg_flags, pid_t daemon_pid); |
583 | int ecryptfs_init_connector(void); | 583 | int ecryptfs_init_connector(void); |
584 | void ecryptfs_release_connector(void); | 584 | void ecryptfs_release_connector(void); |
585 | 585 | void | |
586 | ecryptfs_write_header_metadata(char *virt, | ||
587 | struct ecryptfs_crypt_stat *crypt_stat, | ||
588 | size_t *written); | ||
586 | 589 | ||
587 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ | 590 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index f22c3a73485..652ed772a9b 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -250,6 +250,17 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
250 | struct ecryptfs_file_info *file_info; | 250 | struct ecryptfs_file_info *file_info; |
251 | int lower_flags; | 251 | int lower_flags; |
252 | 252 | ||
253 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
254 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | ||
255 | if ((mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) | ||
256 | && ((file->f_flags & O_WRONLY) || (file->f_flags & O_RDWR) | ||
257 | || (file->f_flags & O_CREAT) || (file->f_flags & O_TRUNC) | ||
258 | || (file->f_flags & O_APPEND))) { | ||
259 | printk(KERN_WARNING "Mount has encrypted view enabled; " | ||
260 | "files may only be read\n"); | ||
261 | rc = -EPERM; | ||
262 | goto out; | ||
263 | } | ||
253 | /* Released in ecryptfs_release or end of function if failure */ | 264 | /* Released in ecryptfs_release or end of function if failure */ |
254 | file_info = kmem_cache_zalloc(ecryptfs_file_info_cache, GFP_KERNEL); | 265 | file_info = kmem_cache_zalloc(ecryptfs_file_info_cache, GFP_KERNEL); |
255 | ecryptfs_set_file_private(file, file_info); | 266 | ecryptfs_set_file_private(file, file_info); |
@@ -261,8 +272,6 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
261 | } | 272 | } |
262 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | 273 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); |
263 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | 274 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; |
264 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
265 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | ||
266 | mutex_lock(&crypt_stat->cs_mutex); | 275 | mutex_lock(&crypt_stat->cs_mutex); |
267 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) { | 276 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) { |
268 | ecryptfs_printk(KERN_DEBUG, "Setting flags for stat...\n"); | 277 | ecryptfs_printk(KERN_DEBUG, "Setting flags for stat...\n"); |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 6b45b2908f1..bbc1b4f666f 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -289,6 +289,7 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
289 | char *encoded_name; | 289 | char *encoded_name; |
290 | unsigned int encoded_namelen; | 290 | unsigned int encoded_namelen; |
291 | struct ecryptfs_crypt_stat *crypt_stat = NULL; | 291 | struct ecryptfs_crypt_stat *crypt_stat = NULL; |
292 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | ||
292 | char *page_virt = NULL; | 293 | char *page_virt = NULL; |
293 | struct inode *lower_inode; | 294 | struct inode *lower_inode; |
294 | u64 file_size; | 295 | u64 file_size; |
@@ -388,8 +389,18 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
388 | } | 389 | } |
389 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; | 390 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; |
390 | } | 391 | } |
391 | memcpy(&file_size, page_virt, sizeof(file_size)); | 392 | mount_crypt_stat = &ecryptfs_superblock_to_private( |
392 | file_size = be64_to_cpu(file_size); | 393 | dentry->d_sb)->mount_crypt_stat; |
394 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { | ||
395 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | ||
396 | file_size = (crypt_stat->header_extent_size | ||
397 | + i_size_read(lower_dentry->d_inode)); | ||
398 | else | ||
399 | file_size = i_size_read(lower_dentry->d_inode); | ||
400 | } else { | ||
401 | memcpy(&file_size, page_virt, sizeof(file_size)); | ||
402 | file_size = be64_to_cpu(file_size); | ||
403 | } | ||
393 | i_size_write(dentry->d_inode, (loff_t)file_size); | 404 | i_size_write(dentry->d_inode, (loff_t)file_size); |
394 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); | 405 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); |
395 | goto out; | 406 | goto out; |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index ba3650d03c4..3386014becc 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; |