aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@us.ibm.com>2007-02-12 03:53:46 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-12 12:48:36 -0500
commitdd2a3b7ad98f8482cae481cad89dfed5eee48365 (patch)
tree986c09754176ea4c6e8308c6e2cdbf3fc0658a0b /fs
parent17398957aa0a05ef62535060b41d103590dcc533 (diff)
[PATCH] eCryptfs: Generalize metadata read/write
Generalize the metadata reading and writing mechanisms, with two targets for now: metadata in file header and metadata in the user.ecryptfs xattr of the lower file. [akpm@osdl.org: printk warning fix] [bunk@stusta.de: make some needlessly global code static] Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/ecryptfs/crypto.c234
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h51
-rw-r--r--fs/ecryptfs/file.c27
-rw-r--r--fs/ecryptfs/inode.c61
-rw-r--r--fs/ecryptfs/main.c7
-rw-r--r--fs/ecryptfs/messaging.c18
-rw-r--r--fs/ecryptfs/mmap.c96
7 files changed, 348 insertions, 146 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 6d85aabb0179..96fa40a48b4f 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 1997-2004 Erez Zadok 4 * Copyright (C) 1997-2004 Erez Zadok
5 * Copyright (C) 2001-2004 Stony Brook University 5 * Copyright (C) 2001-2004 Stony Brook University
6 * Copyright (C) 2004-2006 International Business Machines Corp. 6 * Copyright (C) 2004-2007 International Business Machines Corp.
7 * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> 7 * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
8 * Michael C. Thompson <mcthomps@us.ibm.com> 8 * Michael C. Thompson <mcthomps@us.ibm.com>
9 * 9 *
@@ -863,7 +863,10 @@ void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat)
863 ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; 863 ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
864 } else 864 } else
865 crypt_stat->header_extent_size = PAGE_CACHE_SIZE; 865 crypt_stat->header_extent_size = PAGE_CACHE_SIZE;
866 crypt_stat->num_header_extents_at_front = 1; 866 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
867 crypt_stat->num_header_extents_at_front = 0;
868 else
869 crypt_stat->num_header_extents_at_front = 1;
867} 870}
868 871
869/** 872/**
@@ -1021,7 +1024,7 @@ int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry)
1021 * 1024 *
1022 * Returns one if marker found; zero if not found 1025 * Returns one if marker found; zero if not found
1023 */ 1026 */
1024int contains_ecryptfs_marker(char *data) 1027static int contains_ecryptfs_marker(char *data)
1025{ 1028{
1026 u32 m_1, m_2; 1029 u32 m_1, m_2;
1027 1030
@@ -1047,7 +1050,8 @@ struct ecryptfs_flag_map_elem {
1047/* Add support for additional flags by adding elements here. */ 1050/* Add support for additional flags by adding elements here. */
1048static struct ecryptfs_flag_map_elem ecryptfs_flag_map[] = { 1051static struct ecryptfs_flag_map_elem ecryptfs_flag_map[] = {
1049 {0x00000001, ECRYPTFS_ENABLE_HMAC}, 1052 {0x00000001, ECRYPTFS_ENABLE_HMAC},
1050 {0x00000002, ECRYPTFS_ENCRYPTED} 1053 {0x00000002, ECRYPTFS_ENCRYPTED},
1054 {0x00000004, ECRYPTFS_METADATA_IN_XATTR}
1051}; 1055};
1052 1056
1053/** 1057/**
@@ -1207,8 +1211,8 @@ int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code)
1207 * 1211 *
1208 * Returns zero on success; non-zero otherwise 1212 * Returns zero on success; non-zero otherwise
1209 */ 1213 */
1210int ecryptfs_read_header_region(char *data, struct dentry *dentry, 1214static int ecryptfs_read_header_region(char *data, struct dentry *dentry,
1211 struct vfsmount *mnt) 1215 struct vfsmount *mnt)
1212{ 1216{
1213 struct file *lower_file; 1217 struct file *lower_file;
1214 mm_segment_t oldfs; 1218 mm_segment_t oldfs;
@@ -1237,6 +1241,21 @@ out:
1237 return rc; 1241 return rc;
1238} 1242}
1239 1243
1244int ecryptfs_read_and_validate_header_region(char *data, struct dentry *dentry,
1245 struct vfsmount *mnt)
1246{
1247 int rc;
1248
1249 rc = ecryptfs_read_header_region(data, dentry, mnt);
1250 if (rc)
1251 goto out;
1252 if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES))
1253 rc = -EINVAL;
1254out:
1255 return rc;
1256}
1257
1258
1240static void 1259static void
1241write_header_metadata(char *virt, struct ecryptfs_crypt_stat *crypt_stat, 1260write_header_metadata(char *virt, struct ecryptfs_crypt_stat *crypt_stat,
1242 size_t *written) 1261 size_t *written)
@@ -1288,9 +1307,9 @@ struct kmem_cache *ecryptfs_header_cache_2;
1288 * 1307 *
1289 * Returns zero on success 1308 * Returns zero on success
1290 */ 1309 */
1291int ecryptfs_write_headers_virt(char *page_virt, 1310static int ecryptfs_write_headers_virt(char *page_virt, size_t *size,
1292 struct ecryptfs_crypt_stat *crypt_stat, 1311 struct ecryptfs_crypt_stat *crypt_stat,
1293 struct dentry *ecryptfs_dentry) 1312 struct dentry *ecryptfs_dentry)
1294{ 1313{
1295 int rc; 1314 int rc;
1296 size_t written; 1315 size_t written;
@@ -1309,11 +1328,53 @@ int ecryptfs_write_headers_virt(char *page_virt,
1309 if (rc) 1328 if (rc)
1310 ecryptfs_printk(KERN_WARNING, "Error generating key packet " 1329 ecryptfs_printk(KERN_WARNING, "Error generating key packet "
1311 "set; rc = [%d]\n", rc); 1330 "set; rc = [%d]\n", rc);
1331 if (size) {
1332 offset += written;
1333 *size = offset;
1334 }
1335 return rc;
1336}
1337
1338static int ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat,
1339 struct file *lower_file,
1340 char *page_virt)
1341{
1342 mm_segment_t oldfs;
1343 int current_header_page;
1344 int header_pages;
1345
1346 lower_file->f_pos = 0;
1347 oldfs = get_fs();
1348 set_fs(get_ds());
1349 lower_file->f_op->write(lower_file, (char __user *)page_virt,
1350 PAGE_CACHE_SIZE, &lower_file->f_pos);
1351 header_pages = ((crypt_stat->header_extent_size
1352 * crypt_stat->num_header_extents_at_front)
1353 / PAGE_CACHE_SIZE);
1354 memset(page_virt, 0, PAGE_CACHE_SIZE);
1355 current_header_page = 1;
1356 while (current_header_page < header_pages) {
1357 lower_file->f_op->write(lower_file, (char __user *)page_virt,
1358 PAGE_CACHE_SIZE, &lower_file->f_pos);
1359 current_header_page++;
1360 }
1361 set_fs(oldfs);
1362 return 0;
1363}
1364
1365static int ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry,
1366 struct ecryptfs_crypt_stat *crypt_stat,
1367 char *page_virt, size_t size)
1368{
1369 int rc;
1370
1371 rc = ecryptfs_setxattr(ecryptfs_dentry, ECRYPTFS_XATTR_NAME, page_virt,
1372 size, 0);
1312 return rc; 1373 return rc;
1313} 1374}
1314 1375
1315/** 1376/**
1316 * ecryptfs_write_headers 1377 * ecryptfs_write_metadata
1317 * @lower_file: The lower file struct, which was returned from dentry_open 1378 * @lower_file: The lower file struct, which was returned from dentry_open
1318 * 1379 *
1319 * Write the file headers out. This will likely involve a userspace 1380 * Write the file headers out. This will likely involve a userspace
@@ -1324,14 +1385,12 @@ int ecryptfs_write_headers_virt(char *page_virt,
1324 * 1385 *
1325 * Returns zero on success; non-zero on error 1386 * Returns zero on success; non-zero on error
1326 */ 1387 */
1327int ecryptfs_write_headers(struct dentry *ecryptfs_dentry, 1388int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry,
1328 struct file *lower_file) 1389 struct file *lower_file)
1329{ 1390{
1330 mm_segment_t oldfs;
1331 struct ecryptfs_crypt_stat *crypt_stat; 1391 struct ecryptfs_crypt_stat *crypt_stat;
1332 char *page_virt; 1392 char *page_virt;
1333 int current_header_page; 1393 size_t size;
1334 int header_pages;
1335 int rc = 0; 1394 int rc = 0;
1336 1395
1337 crypt_stat = &ecryptfs_inode_to_private( 1396 crypt_stat = &ecryptfs_inode_to_private(
@@ -1358,48 +1417,36 @@ int ecryptfs_write_headers(struct dentry *ecryptfs_dentry,
1358 rc = -ENOMEM; 1417 rc = -ENOMEM;
1359 goto out; 1418 goto out;
1360 } 1419 }
1361 1420 rc = ecryptfs_write_headers_virt(page_virt, &size, crypt_stat,
1362 rc = ecryptfs_write_headers_virt(page_virt, crypt_stat, 1421 ecryptfs_dentry);
1363 ecryptfs_dentry);
1364 if (unlikely(rc)) { 1422 if (unlikely(rc)) {
1365 ecryptfs_printk(KERN_ERR, "Error whilst writing headers\n"); 1423 ecryptfs_printk(KERN_ERR, "Error whilst writing headers\n");
1366 memset(page_virt, 0, PAGE_CACHE_SIZE); 1424 memset(page_virt, 0, PAGE_CACHE_SIZE);
1367 goto out_free; 1425 goto out_free;
1368 } 1426 }
1369 ecryptfs_printk(KERN_DEBUG, 1427 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
1370 "Writing key packet set to underlying file\n"); 1428 rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry,
1371 lower_file->f_pos = 0; 1429 crypt_stat, page_virt,
1372 oldfs = get_fs(); 1430 size);
1373 set_fs(get_ds()); 1431 else
1374 ecryptfs_printk(KERN_DEBUG, "Calling lower_file->f_op->" 1432 rc = ecryptfs_write_metadata_to_contents(crypt_stat, lower_file,
1375 "write() w/ header page; lower_file->f_pos = " 1433 page_virt);
1376 "[0x%.16x]\n", lower_file->f_pos); 1434 if (rc) {
1377 lower_file->f_op->write(lower_file, (char __user *)page_virt, 1435 printk(KERN_ERR "Error writing metadata out to lower file; "
1378 PAGE_CACHE_SIZE, &lower_file->f_pos); 1436 "rc = [%d]\n", rc);
1379 header_pages = ((crypt_stat->header_extent_size 1437 goto out_free;
1380 * crypt_stat->num_header_extents_at_front)
1381 / PAGE_CACHE_SIZE);
1382 memset(page_virt, 0, PAGE_CACHE_SIZE);
1383 current_header_page = 1;
1384 while (current_header_page < header_pages) {
1385 ecryptfs_printk(KERN_DEBUG, "Calling lower_file->f_op->"
1386 "write() w/ zero'd page; lower_file->f_pos = "
1387 "[0x%.16x]\n", lower_file->f_pos);
1388 lower_file->f_op->write(lower_file, (char __user *)page_virt,
1389 PAGE_CACHE_SIZE, &lower_file->f_pos);
1390 current_header_page++;
1391 } 1438 }
1392 set_fs(oldfs);
1393 ecryptfs_printk(KERN_DEBUG,
1394 "Done writing key packet set to underlying file.\n");
1395out_free: 1439out_free:
1396 kmem_cache_free(ecryptfs_header_cache_0, page_virt); 1440 kmem_cache_free(ecryptfs_header_cache_0, page_virt);
1397out: 1441out:
1398 return rc; 1442 return rc;
1399} 1443}
1400 1444
1445#define ECRYPTFS_DONT_VALIDATE_HEADER_SIZE 0
1446#define ECRYPTFS_VALIDATE_HEADER_SIZE 1
1401static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat, 1447static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
1402 char *virt, int *bytes_read) 1448 char *virt, int *bytes_read,
1449 int validate_header_size)
1403{ 1450{
1404 int rc = 0; 1451 int rc = 0;
1405 u32 header_extent_size; 1452 u32 header_extent_size;
@@ -1414,9 +1461,10 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
1414 crypt_stat->num_header_extents_at_front = 1461 crypt_stat->num_header_extents_at_front =
1415 (int)num_header_extents_at_front; 1462 (int)num_header_extents_at_front;
1416 (*bytes_read) = 6; 1463 (*bytes_read) = 6;
1417 if ((crypt_stat->header_extent_size 1464 if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE)
1418 * crypt_stat->num_header_extents_at_front) 1465 && ((crypt_stat->header_extent_size
1419 < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) { 1466 * crypt_stat->num_header_extents_at_front)
1467 < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) {
1420 rc = -EINVAL; 1468 rc = -EINVAL;
1421 ecryptfs_printk(KERN_WARNING, "Invalid header extent size: " 1469 ecryptfs_printk(KERN_WARNING, "Invalid header extent size: "
1422 "[%d]\n", crypt_stat->header_extent_size); 1470 "[%d]\n", crypt_stat->header_extent_size);
@@ -1447,7 +1495,8 @@ static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat)
1447 */ 1495 */
1448static int ecryptfs_read_headers_virt(char *page_virt, 1496static int ecryptfs_read_headers_virt(char *page_virt,
1449 struct ecryptfs_crypt_stat *crypt_stat, 1497 struct ecryptfs_crypt_stat *crypt_stat,
1450 struct dentry *ecryptfs_dentry) 1498 struct dentry *ecryptfs_dentry,
1499 int validate_header_size)
1451{ 1500{
1452 int rc = 0; 1501 int rc = 0;
1453 int offset; 1502 int offset;
@@ -1481,7 +1530,7 @@ static int ecryptfs_read_headers_virt(char *page_virt,
1481 offset += bytes_read; 1530 offset += bytes_read;
1482 if (crypt_stat->file_version >= 1) { 1531 if (crypt_stat->file_version >= 1) {
1483 rc = parse_header_metadata(crypt_stat, (page_virt + offset), 1532 rc = parse_header_metadata(crypt_stat, (page_virt + offset),
1484 &bytes_read); 1533 &bytes_read, validate_header_size);
1485 if (rc) { 1534 if (rc) {
1486 ecryptfs_printk(KERN_WARNING, "Error reading header " 1535 ecryptfs_printk(KERN_WARNING, "Error reading header "
1487 "metadata; rc = [%d]\n", rc); 1536 "metadata; rc = [%d]\n", rc);
@@ -1496,12 +1545,60 @@ out:
1496} 1545}
1497 1546
1498/** 1547/**
1499 * ecryptfs_read_headers 1548 * ecryptfs_read_xattr_region
1549 *
1550 * Attempts to read the crypto metadata from the extended attribute
1551 * region of the lower file.
1552 */
1553int ecryptfs_read_xattr_region(char *page_virt, struct dentry *ecryptfs_dentry)
1554{
1555 ssize_t size;
1556 int rc = 0;
1557
1558 size = ecryptfs_getxattr(ecryptfs_dentry, ECRYPTFS_XATTR_NAME,
1559 page_virt, ECRYPTFS_DEFAULT_EXTENT_SIZE);
1560 if (size < 0) {
1561 printk(KERN_DEBUG "Error attempting to read the [%s] "
1562 "xattr from the lower file; return value = [%zd]\n",
1563 ECRYPTFS_XATTR_NAME, size);
1564 rc = -EINVAL;
1565 goto out;
1566 }
1567out:
1568 return rc;
1569}
1570
1571int ecryptfs_read_and_validate_xattr_region(char *page_virt,
1572 struct dentry *ecryptfs_dentry)
1573{
1574 int rc;
1575
1576 rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_dentry);
1577 if (rc)
1578 goto out;
1579 if (!contains_ecryptfs_marker(page_virt + ECRYPTFS_FILE_SIZE_BYTES)) {
1580 printk(KERN_WARNING "Valid data found in [%s] xattr, but "
1581 "the marker is invalid\n", ECRYPTFS_XATTR_NAME);
1582 rc = -EINVAL;
1583 }
1584out:
1585 return rc;
1586}
1587
1588/**
1589 * ecryptfs_read_metadata
1590 *
1591 * Common entry point for reading file metadata. From here, we could
1592 * retrieve the header information from the header region of the file,
1593 * the xattr region of the file, or some other repostory that is
1594 * stored separately from the file itself. The current implementation
1595 * supports retrieving the metadata information from the file contents
1596 * and from the xattr region.
1500 * 1597 *
1501 * Returns zero if valid headers found and parsed; non-zero otherwise 1598 * Returns zero if valid headers found and parsed; non-zero otherwise
1502 */ 1599 */
1503int ecryptfs_read_headers(struct dentry *ecryptfs_dentry, 1600int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry,
1504 struct file *lower_file) 1601 struct file *lower_file)
1505{ 1602{
1506 int rc = 0; 1603 int rc = 0;
1507 char *page_virt = NULL; 1604 char *page_virt = NULL;
@@ -1530,11 +1627,36 @@ int ecryptfs_read_headers(struct dentry *ecryptfs_dentry,
1530 goto out; 1627 goto out;
1531 } 1628 }
1532 rc = ecryptfs_read_headers_virt(page_virt, crypt_stat, 1629 rc = ecryptfs_read_headers_virt(page_virt, crypt_stat,
1533 ecryptfs_dentry); 1630 ecryptfs_dentry,
1631 ECRYPTFS_VALIDATE_HEADER_SIZE);
1534 if (rc) { 1632 if (rc) {
1535 ecryptfs_printk(KERN_DEBUG, "Valid eCryptfs headers not " 1633 rc = ecryptfs_read_xattr_region(page_virt,
1536 "found\n"); 1634 ecryptfs_dentry);
1537 rc = -EINVAL; 1635 if (rc) {
1636 printk(KERN_DEBUG "Valid eCryptfs headers not found in "
1637 "file header region or xattr region\n");
1638 rc = -EINVAL;
1639 goto out;
1640 }
1641 rc = ecryptfs_read_headers_virt(page_virt, crypt_stat,
1642 ecryptfs_dentry,
1643 ECRYPTFS_DONT_VALIDATE_HEADER_SIZE);
1644 if (rc) {
1645 printk(KERN_DEBUG "Valid eCryptfs headers not found in "
1646 "file xattr region either\n");
1647 rc = -EINVAL;
1648 }
1649 if (crypt_stat->mount_crypt_stat->flags
1650 & ECRYPTFS_XATTR_METADATA_ENABLED) {
1651 crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR;
1652 } else {
1653 printk(KERN_WARNING "Attempt to access file with "
1654 "crypto metadata only in the extended attribute "
1655 "region, but eCryptfs was mounted without "
1656 "xattr support enabled. eCryptfs will not treat "
1657 "this like an encrypted file.\n");
1658 rc = -EINVAL;
1659 }
1538 } 1660 }
1539out: 1661out:
1540 if (page_virt) { 1662 if (page_virt) {
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 7bbd6e6e2743..020abcd16f0e 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -4,7 +4,7 @@
4 * 4 *
5 * Copyright (C) 1997-2003 Erez Zadok 5 * Copyright (C) 1997-2003 Erez Zadok
6 * Copyright (C) 2001-2003 Stony Brook University 6 * Copyright (C) 2001-2003 Stony Brook University
7 * Copyright (C) 2004-2006 International Business Machines Corp. 7 * Copyright (C) 2004-2007 International Business Machines Corp.
8 * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> 8 * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
9 * Trevor S. Highland <trevor.highland@gmail.com> 9 * Trevor S. Highland <trevor.highland@gmail.com>
10 * Tyler Hicks <tyhicks@ou.edu> 10 * Tyler Hicks <tyhicks@ou.edu>
@@ -50,8 +50,8 @@
50#define ECRYPTFS_VERSIONING_XATTR 0x00000010 50#define ECRYPTFS_VERSIONING_XATTR 0x00000010
51#define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \ 51#define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \
52 | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \ 52 | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \
53 | ECRYPTFS_VERSIONING_PUBKEY) 53 | ECRYPTFS_VERSIONING_PUBKEY \
54 54 | ECRYPTFS_VERSIONING_XATTR)
55#define ECRYPTFS_MAX_PASSWORD_LENGTH 64 55#define ECRYPTFS_MAX_PASSWORD_LENGTH 64
56#define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH 56#define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH
57#define ECRYPTFS_SALT_SIZE 8 57#define ECRYPTFS_SALT_SIZE 8
@@ -83,6 +83,7 @@
83#define ECRYPTFS_TRANSPORT_CONNECTOR 1 83#define ECRYPTFS_TRANSPORT_CONNECTOR 1
84#define ECRYPTFS_TRANSPORT_RELAYFS 2 84#define ECRYPTFS_TRANSPORT_RELAYFS 2
85#define ECRYPTFS_DEFAULT_TRANSPORT ECRYPTFS_TRANSPORT_NETLINK 85#define ECRYPTFS_DEFAULT_TRANSPORT ECRYPTFS_TRANSPORT_NETLINK
86#define ECRYPTFS_XATTR_NAME "user.ecryptfs"
86 87
87#define RFC2440_CIPHER_DES3_EDE 0x02 88#define RFC2440_CIPHER_DES3_EDE 0x02
88#define RFC2440_CIPHER_CAST_5 0x03 89#define RFC2440_CIPHER_CAST_5 0x03
@@ -327,18 +328,6 @@ struct ecryptfs_msg_ctx {
327 struct mutex mux; 328 struct mutex mux;
328}; 329};
329 330
330extern struct list_head ecryptfs_msg_ctx_free_list;
331extern struct list_head ecryptfs_msg_ctx_alloc_list;
332extern struct mutex ecryptfs_msg_ctx_lists_mux;
333
334#define ecryptfs_uid_hash(uid) \
335 hash_long((unsigned long)uid, ecryptfs_hash_buckets)
336extern struct hlist_head *ecryptfs_daemon_id_hash;
337extern struct mutex ecryptfs_daemon_id_hash_mux;
338extern int ecryptfs_hash_buckets;
339
340extern unsigned int ecryptfs_msg_counter;
341extern struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr;
342extern unsigned int ecryptfs_transport; 331extern unsigned int ecryptfs_transport;
343 332
344struct ecryptfs_daemon_id { 333struct ecryptfs_daemon_id {
@@ -479,6 +468,7 @@ extern struct kmem_cache *ecryptfs_sb_info_cache;
479extern struct kmem_cache *ecryptfs_header_cache_0; 468extern struct kmem_cache *ecryptfs_header_cache_0;
480extern struct kmem_cache *ecryptfs_header_cache_1; 469extern struct kmem_cache *ecryptfs_header_cache_1;
481extern struct kmem_cache *ecryptfs_header_cache_2; 470extern struct kmem_cache *ecryptfs_header_cache_2;
471extern struct kmem_cache *ecryptfs_xattr_cache;
482extern struct kmem_cache *ecryptfs_lower_page_cache; 472extern struct kmem_cache *ecryptfs_lower_page_cache;
483 473
484int ecryptfs_interpose(struct dentry *hidden_dentry, 474int ecryptfs_interpose(struct dentry *hidden_dentry,
@@ -505,9 +495,13 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat);
505int ecryptfs_crypto_api_algify_cipher_name(char **algified_name, 495int ecryptfs_crypto_api_algify_cipher_name(char **algified_name,
506 char *cipher_name, 496 char *cipher_name,
507 char *chaining_modifier); 497 char *chaining_modifier);
508int ecryptfs_write_inode_size_to_header(struct file *lower_file, 498#define ECRYPTFS_LOWER_I_MUTEX_NOT_HELD 0
509 struct inode *lower_inode, 499#define ECRYPTFS_LOWER_I_MUTEX_HELD 1
510 struct inode *inode); 500int ecryptfs_write_inode_size_to_metadata(struct file *lower_file,
501 struct inode *lower_inode,
502 struct inode *inode,
503 struct dentry *ecryptfs_dentry,
504 int lower_i_mutex_held);
511int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode, 505int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode,
512 struct file *lower_file, 506 struct file *lower_file,
513 unsigned long lower_page_index, int byte_offset, 507 unsigned long lower_page_index, int byte_offset,
@@ -529,17 +523,15 @@ int ecryptfs_writepage_and_release_lower_page(struct page *lower_page,
529 struct writeback_control *wbc); 523 struct writeback_control *wbc);
530int ecryptfs_encrypt_page(struct ecryptfs_page_crypt_context *ctx); 524int ecryptfs_encrypt_page(struct ecryptfs_page_crypt_context *ctx);
531int ecryptfs_decrypt_page(struct file *file, struct page *page); 525int ecryptfs_decrypt_page(struct file *file, struct page *page);
532int ecryptfs_write_headers(struct dentry *ecryptfs_dentry, 526int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry,
527 struct file *lower_file);
528int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry,
533 struct file *lower_file); 529 struct file *lower_file);
534int ecryptfs_write_headers_virt(char *page_virt,
535 struct ecryptfs_crypt_stat *crypt_stat,
536 struct dentry *ecryptfs_dentry);
537int ecryptfs_read_headers(struct dentry *ecryptfs_dentry,
538 struct file *lower_file);
539int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry); 530int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry);
540int contains_ecryptfs_marker(char *data); 531int ecryptfs_read_and_validate_header_region(char *data, struct dentry *dentry,
541int ecryptfs_read_header_region(char *data, struct dentry *dentry, 532 struct vfsmount *mnt);
542 struct vfsmount *mnt); 533int ecryptfs_read_and_validate_xattr_region(char *page_virt,
534 struct dentry *ecryptfs_dentry);
543u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat); 535u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat);
544int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code); 536int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code);
545void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat); 537void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat);
@@ -562,6 +554,11 @@ int ecryptfs_open_lower_file(struct file **lower_file,
562 struct dentry *lower_dentry, 554 struct dentry *lower_dentry,
563 struct vfsmount *lower_mnt, int flags); 555 struct vfsmount *lower_mnt, int flags);
564int ecryptfs_close_lower_file(struct file *lower_file); 556int ecryptfs_close_lower_file(struct file *lower_file);
557ssize_t ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value,
558 size_t size);
559int
560ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
561 size_t size, int flags);
565 562
566int 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);
567int ecryptfs_process_quit(uid_t uid, pid_t pid); 564int ecryptfs_process_quit(uid_t uid, pid_t pid);
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 779c3477d93c..f22c3a73485c 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 1997-2004 Erez Zadok 4 * Copyright (C) 1997-2004 Erez Zadok
5 * Copyright (C) 2001-2004 Stony Brook University 5 * Copyright (C) 2001-2004 Stony Brook University
6 * Copyright (C) 2004-2006 International Business Machines Corp. 6 * Copyright (C) 2004-2007 International Business Machines Corp.
7 * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> 7 * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com>
8 * Michael C. Thompson <mcthomps@us.ibm.com> 8 * Michael C. Thompson <mcthomps@us.ibm.com>
9 * 9 *
@@ -293,26 +293,11 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
293 goto out; 293 goto out;
294 } 294 }
295 mutex_lock(&crypt_stat->cs_mutex); 295 mutex_lock(&crypt_stat->cs_mutex);
296 if (i_size_read(lower_inode) < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) { 296 if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
297 if (!(mount_crypt_stat->flags 297 ECRYPTFS_POLICY_APPLIED)
298 & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { 298 || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
299 rc = -EIO; 299 ECRYPTFS_KEY_VALID)) {
300 printk(KERN_WARNING "Attempt to read file that is " 300 rc = ecryptfs_read_metadata(ecryptfs_dentry, lower_file);
301 "not in a valid eCryptfs format, and plaintext "
302 "passthrough mode is not enabled; returning "
303 "-EIO\n");
304 mutex_unlock(&crypt_stat->cs_mutex);
305 goto out_puts;
306 }
307 crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
308 rc = 0;
309 mutex_unlock(&crypt_stat->cs_mutex);
310 goto out;
311 } else if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
312 ECRYPTFS_POLICY_APPLIED)
313 || !ECRYPTFS_CHECK_FLAG(crypt_stat->flags,
314 ECRYPTFS_KEY_VALID)) {
315 rc = ecryptfs_read_headers(ecryptfs_dentry, lower_file);
316 if (rc) { 301 if (rc) {
317 ecryptfs_printk(KERN_DEBUG, 302 ecryptfs_printk(KERN_DEBUG,
318 "Valid headers not found\n"); 303 "Valid headers not found\n");
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index d4f02f3e18d7..6b45b2908f17 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 1997-2004 Erez Zadok 4 * Copyright (C) 1997-2004 Erez Zadok
5 * Copyright (C) 2001-2004 Stony Brook University 5 * Copyright (C) 2001-2004 Stony Brook University
6 * Copyright (C) 2004-2006 International Business Machines Corp. 6 * Copyright (C) 2004-2007 International Business Machines Corp.
7 * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> 7 * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
8 * Michael C. Thompsion <mcthomps@us.ibm.com> 8 * Michael C. Thompsion <mcthomps@us.ibm.com>
9 * 9 *
@@ -169,7 +169,9 @@ static int grow_file(struct dentry *ecryptfs_dentry, struct file *lower_file,
169 goto out; 169 goto out;
170 } 170 }
171 i_size_write(inode, 0); 171 i_size_write(inode, 0);
172 ecryptfs_write_inode_size_to_header(lower_file, lower_inode, inode); 172 ecryptfs_write_inode_size_to_metadata(lower_file, lower_inode, inode,
173 ecryptfs_dentry,
174 ECRYPTFS_LOWER_I_MUTEX_NOT_HELD);
173 ECRYPTFS_SET_FLAG(ecryptfs_inode_to_private(inode)->crypt_stat.flags, 175 ECRYPTFS_SET_FLAG(ecryptfs_inode_to_private(inode)->crypt_stat.flags,
174 ECRYPTFS_NEW_FILE); 176 ECRYPTFS_NEW_FILE);
175out: 177out:
@@ -225,7 +227,7 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
225 "context\n"); 227 "context\n");
226 goto out_fput; 228 goto out_fput;
227 } 229 }
228 rc = ecryptfs_write_headers(ecryptfs_dentry, lower_file); 230 rc = ecryptfs_write_metadata(ecryptfs_dentry, lower_file);
229 if (rc) { 231 if (rc) {
230 ecryptfs_printk(KERN_DEBUG, "Error writing headers\n"); 232 ecryptfs_printk(KERN_DEBUG, "Error writing headers\n");
231 goto out_fput; 233 goto out_fput;
@@ -362,32 +364,33 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
362 } 364 }
363 /* Released in this function */ 365 /* Released in this function */
364 page_virt = kmem_cache_zalloc(ecryptfs_header_cache_2, 366 page_virt = kmem_cache_zalloc(ecryptfs_header_cache_2,
365 GFP_USER); 367 GFP_USER);
366 if (!page_virt) { 368 if (!page_virt) {
367 rc = -ENOMEM; 369 rc = -ENOMEM;
368 ecryptfs_printk(KERN_ERR, 370 ecryptfs_printk(KERN_ERR,
369 "Cannot ecryptfs_kmalloc a page\n"); 371 "Cannot ecryptfs_kmalloc a page\n");
370 goto out_dput; 372 goto out_dput;
371 } 373 }
372
373 rc = ecryptfs_read_header_region(page_virt, lower_dentry, nd->mnt);
374 crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; 374 crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
375 if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) 375 if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED))
376 ecryptfs_set_default_sizes(crypt_stat); 376 ecryptfs_set_default_sizes(crypt_stat);
377 rc = ecryptfs_read_and_validate_header_region(page_virt, lower_dentry,
378 nd->mnt);
377 if (rc) { 379 if (rc) {
378 rc = 0; 380 rc = ecryptfs_read_and_validate_xattr_region(page_virt, dentry);
379 ecryptfs_printk(KERN_WARNING, "Error reading header region;" 381 if (rc) {
380 " assuming unencrypted\n"); 382 printk(KERN_DEBUG "Valid metadata not found in header "
381 } else { 383 "region or xattr region; treating file as "
382 if (!contains_ecryptfs_marker(page_virt 384 "unencrypted\n");
383 + ECRYPTFS_FILE_SIZE_BYTES)) { 385 rc = 0;
384 kmem_cache_free(ecryptfs_header_cache_2, page_virt); 386 kmem_cache_free(ecryptfs_header_cache_2, page_virt);
385 goto out; 387 goto out;
386 } 388 }
387 memcpy(&file_size, page_virt, sizeof(file_size)); 389 crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR;
388 file_size = be64_to_cpu(file_size);
389 i_size_write(dentry->d_inode, (loff_t)file_size);
390 } 390 }
391 memcpy(&file_size, page_virt, sizeof(file_size));
392 file_size = be64_to_cpu(file_size);
393 i_size_write(dentry->d_inode, (loff_t)file_size);
391 kmem_cache_free(ecryptfs_header_cache_2, page_virt); 394 kmem_cache_free(ecryptfs_header_cache_2, page_virt);
392 goto out; 395 goto out;
393 396
@@ -781,20 +784,26 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
781 goto out_fput; 784 goto out_fput;
782 } 785 }
783 i_size_write(inode, new_length); 786 i_size_write(inode, new_length);
784 rc = ecryptfs_write_inode_size_to_header(lower_file, 787 rc = ecryptfs_write_inode_size_to_metadata(
785 lower_dentry->d_inode, 788 lower_file, lower_dentry->d_inode, inode, dentry,
786 inode); 789 ECRYPTFS_LOWER_I_MUTEX_NOT_HELD);
787 if (rc) { 790 if (rc) {
788 ecryptfs_printk(KERN_ERR, 791 printk(KERN_ERR "Problem with "
789 "Problem with ecryptfs_write" 792 "ecryptfs_write_inode_size_to_metadata; "
790 "_inode_size\n"); 793 "rc = [%d]\n", rc);
791 goto out_fput; 794 goto out_fput;
792 } 795 }
793 } else { /* new_length < i_size_read(inode) */ 796 } else { /* new_length < i_size_read(inode) */
794 vmtruncate(inode, new_length); 797 vmtruncate(inode, new_length);
795 ecryptfs_write_inode_size_to_header(lower_file, 798 rc = ecryptfs_write_inode_size_to_metadata(
796 lower_dentry->d_inode, 799 lower_file, lower_dentry->d_inode, inode, dentry,
797 inode); 800 ECRYPTFS_LOWER_I_MUTEX_NOT_HELD);
801 if (rc) {
802 printk(KERN_ERR "Problem with "
803 "ecryptfs_write_inode_size_to_metadata; "
804 "rc = [%d]\n", rc);
805 goto out_fput;
806 }
798 /* We are reducing the size of the ecryptfs file, and need to 807 /* We are reducing the size of the ecryptfs file, and need to
799 * know if we need to reduce the size of the lower file. */ 808 * know if we need to reduce the size of the lower file. */
800 lower_size_before_truncate = 809 lower_size_before_truncate =
@@ -881,7 +890,7 @@ out:
881 return rc; 890 return rc;
882} 891}
883 892
884static int 893int
885ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, 894ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
886 size_t size, int flags) 895 size_t size, int flags)
887{ 896{
@@ -901,7 +910,7 @@ out:
901 return rc; 910 return rc;
902} 911}
903 912
904static ssize_t 913ssize_t
905ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value, 914ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value,
906 size_t size) 915 size_t size)
907{ 916{
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index a3efdccbbcc8..26fe405a5763 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 1997-2003 Erez Zadok 4 * Copyright (C) 1997-2003 Erez Zadok
5 * Copyright (C) 2001-2003 Stony Brook University 5 * Copyright (C) 2001-2003 Stony Brook University
6 * Copyright (C) 2004-2006 International Business Machines Corp. 6 * Copyright (C) 2004-2007 International Business Machines Corp.
7 * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> 7 * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
8 * Michael C. Thompson <mcthomps@us.ibm.com> 8 * Michael C. Thompson <mcthomps@us.ibm.com>
9 * Tyler Hicks <tyhicks@ou.edu> 9 * Tyler Hicks <tyhicks@ou.edu>
@@ -642,6 +642,11 @@ static struct ecryptfs_cache_info {
642 .size = PAGE_CACHE_SIZE, 642 .size = PAGE_CACHE_SIZE,
643 }, 643 },
644 { 644 {
645 .cache = &ecryptfs_xattr_cache,
646 .name = "ecryptfs_xattr_cache",
647 .size = PAGE_CACHE_SIZE,
648 },
649 {
645 .cache = &ecryptfs_lower_page_cache, 650 .cache = &ecryptfs_lower_page_cache,
646 .name = "ecryptfs_lower_page_cache", 651 .name = "ecryptfs_lower_page_cache",
647 .size = PAGE_CACHE_SIZE, 652 .size = PAGE_CACHE_SIZE,
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c
index e8ba6278ad2c..47d7e7b611f7 100644
--- a/fs/ecryptfs/messaging.c
+++ b/fs/ecryptfs/messaging.c
@@ -22,16 +22,18 @@
22 22
23#include "ecryptfs_kernel.h" 23#include "ecryptfs_kernel.h"
24 24
25LIST_HEAD(ecryptfs_msg_ctx_free_list); 25static LIST_HEAD(ecryptfs_msg_ctx_free_list);
26LIST_HEAD(ecryptfs_msg_ctx_alloc_list); 26static LIST_HEAD(ecryptfs_msg_ctx_alloc_list);
27struct mutex ecryptfs_msg_ctx_lists_mux; 27static struct mutex ecryptfs_msg_ctx_lists_mux;
28 28
29struct hlist_head *ecryptfs_daemon_id_hash; 29static struct hlist_head *ecryptfs_daemon_id_hash;
30struct mutex ecryptfs_daemon_id_hash_mux; 30static struct mutex ecryptfs_daemon_id_hash_mux;
31int ecryptfs_hash_buckets; 31static int ecryptfs_hash_buckets;
32#define ecryptfs_uid_hash(uid) \
33 hash_long((unsigned long)uid, ecryptfs_hash_buckets)
32 34
33unsigned int ecryptfs_msg_counter; 35static unsigned int ecryptfs_msg_counter;
34struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr; 36static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr;
35 37
36/** 38/**
37 * ecryptfs_acquire_free_msg_ctx 39 * ecryptfs_acquire_free_msg_ctx
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index 0af3aa3b4b3e..ba3650d03c48 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -6,7 +6,7 @@
6 * 6 *
7 * Copyright (C) 1997-2003 Erez Zadok 7 * Copyright (C) 1997-2003 Erez Zadok
8 * Copyright (C) 2001-2003 Stony Brook University 8 * Copyright (C) 2001-2003 Stony Brook University
9 * Copyright (C) 2004-2006 International Business Machines Corp. 9 * Copyright (C) 2004-2007 International Business Machines Corp.
10 * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> 10 * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
11 * 11 *
12 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
@@ -308,6 +308,9 @@ out:
308 return rc; 308 return rc;
309} 309}
310 310
311/**
312 * Called with lower inode mutex held.
313 */
311static int fill_zeros_to_end_of_page(struct page *page, unsigned int to) 314static int fill_zeros_to_end_of_page(struct page *page, unsigned int to)
312{ 315{
313 struct inode *inode = page->mapping->host; 316 struct inode *inode = page->mapping->host;
@@ -407,10 +410,9 @@ static void ecryptfs_unmap_and_release_lower_page(struct page *lower_page)
407 * 410 *
408 * Returns zero on success; non-zero on error. 411 * Returns zero on success; non-zero on error.
409 */ 412 */
410int 413static int ecryptfs_write_inode_size_to_header(struct file *lower_file,
411ecryptfs_write_inode_size_to_header(struct file *lower_file, 414 struct inode *lower_inode,
412 struct inode *lower_inode, 415 struct inode *inode)
413 struct inode *inode)
414{ 416{
415 int rc = 0; 417 int rc = 0;
416 struct page *header_page; 418 struct page *header_page;
@@ -442,6 +444,80 @@ out:
442 return rc; 444 return rc;
443} 445}
444 446
447static int ecryptfs_write_inode_size_to_xattr(struct inode *lower_inode,
448 struct inode *inode,
449 struct dentry *ecryptfs_dentry,
450 int lower_i_mutex_held)
451{
452 ssize_t size;
453 void *xattr_virt;
454 struct dentry *lower_dentry;
455 u64 file_size;
456 int rc;
457
458 xattr_virt = kmem_cache_alloc(ecryptfs_xattr_cache, GFP_KERNEL);
459 if (!xattr_virt) {
460 printk(KERN_ERR "Out of memory whilst attempting to write "
461 "inode size to xattr\n");
462 rc = -ENOMEM;
463 goto out;
464 }
465 lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
466 if (!lower_dentry->d_inode->i_op->getxattr) {
467 printk(KERN_WARNING
468 "No support for setting xattr in lower filesystem\n");
469 rc = -ENOSYS;
470 kmem_cache_free(ecryptfs_xattr_cache, xattr_virt);
471 goto out;
472 }
473 if (!lower_i_mutex_held)
474 mutex_lock(&lower_dentry->d_inode->i_mutex);
475 size = lower_dentry->d_inode->i_op->getxattr(lower_dentry,
476 ECRYPTFS_XATTR_NAME,
477 xattr_virt,
478 PAGE_CACHE_SIZE);
479 if (!lower_i_mutex_held)
480 mutex_unlock(&lower_dentry->d_inode->i_mutex);
481 if (size < 0)
482 size = 8;
483 file_size = (u64)i_size_read(inode);
484 file_size = cpu_to_be64(file_size);
485 memcpy(xattr_virt, &file_size, sizeof(u64));
486 if (!lower_i_mutex_held)
487 mutex_lock(&lower_dentry->d_inode->i_mutex);
488 rc = lower_dentry->d_inode->i_op->setxattr(lower_dentry,
489 ECRYPTFS_XATTR_NAME,
490 xattr_virt, size, 0);
491 if (!lower_i_mutex_held)
492 mutex_unlock(&lower_dentry->d_inode->i_mutex);
493 if (rc)
494 printk(KERN_ERR "Error whilst attempting to write inode size "
495 "to lower file xattr; rc = [%d]\n", rc);
496 kmem_cache_free(ecryptfs_xattr_cache, xattr_virt);
497out:
498 return rc;
499}
500
501int
502ecryptfs_write_inode_size_to_metadata(struct file *lower_file,
503 struct inode *lower_inode,
504 struct inode *inode,
505 struct dentry *ecryptfs_dentry,
506 int lower_i_mutex_held)
507{
508 struct ecryptfs_crypt_stat *crypt_stat;
509
510 crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
511 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
512 return ecryptfs_write_inode_size_to_xattr(lower_inode, inode,
513 ecryptfs_dentry,
514 lower_i_mutex_held);
515 else
516 return ecryptfs_write_inode_size_to_header(lower_file,
517 lower_inode,
518 inode);
519}
520
445int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode, 521int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode,
446 struct file *lower_file, 522 struct file *lower_file,
447 unsigned long lower_page_index, int byte_offset, 523 unsigned long lower_page_index, int byte_offset,
@@ -528,6 +604,8 @@ out:
528 return rc; 604 return rc;
529} 605}
530 606
607struct kmem_cache *ecryptfs_xattr_cache;
608
531/** 609/**
532 * ecryptfs_commit_write 610 * ecryptfs_commit_write
533 * @file: The eCryptfs file object 611 * @file: The eCryptfs file object
@@ -581,7 +659,6 @@ static int ecryptfs_commit_write(struct file *file, struct page *page,
581 "index [0x%.16x])\n", page->index); 659 "index [0x%.16x])\n", page->index);
582 goto out; 660 goto out;
583 } 661 }
584 rc = 0;
585 inode->i_blocks = lower_inode->i_blocks; 662 inode->i_blocks = lower_inode->i_blocks;
586 pos = (page->index << PAGE_CACHE_SHIFT) + to; 663 pos = (page->index << PAGE_CACHE_SHIFT) + to;
587 if (pos > i_size_read(inode)) { 664 if (pos > i_size_read(inode)) {
@@ -589,7 +666,12 @@ static int ecryptfs_commit_write(struct file *file, struct page *page,
589 ecryptfs_printk(KERN_DEBUG, "Expanded file size to " 666 ecryptfs_printk(KERN_DEBUG, "Expanded file size to "
590 "[0x%.16x]\n", i_size_read(inode)); 667 "[0x%.16x]\n", i_size_read(inode));
591 } 668 }
592 ecryptfs_write_inode_size_to_header(lower_file, lower_inode, inode); 669 rc = ecryptfs_write_inode_size_to_metadata(lower_file, lower_inode,
670 inode, file->f_dentry,
671 ECRYPTFS_LOWER_I_MUTEX_HELD);
672 if (rc)
673 printk(KERN_ERR "Error writing inode size to metadata; "
674 "rc = [%d]\n", rc);
593 lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME; 675 lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
594 mark_inode_dirty_sync(inode); 676 mark_inode_dirty_sync(inode);
595out: 677out: