aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ecryptfs/crypto.c15
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h7
-rw-r--r--fs/ecryptfs/file.c13
-rw-r--r--fs/ecryptfs/inode.c15
-rw-r--r--fs/ecryptfs/mmap.c74
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
1259static void 1259void
1260write_header_metadata(char *virt, struct ecryptfs_crypt_stat *crypt_stat, 1260ecryptfs_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,
559int 559int
560ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, 560ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
561 size_t size, int flags); 561 size_t size, int flags);
562 562int ecryptfs_read_xattr_region(char *page_virt, struct dentry *ecryptfs_dentry);
563int ecryptfs_process_helo(unsigned int transport, uid_t uid, pid_t pid); 563int ecryptfs_process_helo(unsigned int transport, uid_t uid, pid_t pid);
564int ecryptfs_process_quit(uid_t uid, pid_t pid); 564int ecryptfs_process_quit(uid_t uid, pid_t pid);
565int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t uid, 565int 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);
583int ecryptfs_init_connector(void); 583int ecryptfs_init_connector(void);
584void ecryptfs_release_connector(void); 584void ecryptfs_release_connector(void);
585 585void
586ecryptfs_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 */
278static 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;