diff options
author | Michael Halcrow <mhalcrow@us.ibm.com> | 2008-02-06 04:38:32 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-06 13:41:12 -0500 |
commit | cc11beffdf80ca31dff21422fa2a5e54d25f1494 (patch) | |
tree | 3b0e28d18f493a7c59b089c4c6fc59c79945937e /fs/ecryptfs/crypto.c | |
parent | 7896b631823c6e8f1a520d89390624a51445840e (diff) |
eCryptfs: track header bytes rather than extents
Remove internal references to header extents; just keep track of header bytes
instead. Headers can easily span multiple pages with the recent persistent
file changes.
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/ecryptfs/crypto.c')
-rw-r--r-- | fs/ecryptfs/crypto.c | 98 |
1 files changed, 35 insertions, 63 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 5e7d018a348..4d1b2b4eb79 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -379,8 +379,7 @@ out: | |||
379 | static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num, | 379 | static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num, |
380 | struct ecryptfs_crypt_stat *crypt_stat) | 380 | struct ecryptfs_crypt_stat *crypt_stat) |
381 | { | 381 | { |
382 | (*offset) = ((crypt_stat->extent_size | 382 | (*offset) = (crypt_stat->num_header_bytes_at_front |
383 | * crypt_stat->num_header_extents_at_front) | ||
384 | + (crypt_stat->extent_size * extent_num)); | 383 | + (crypt_stat->extent_size * extent_num)); |
385 | } | 384 | } |
386 | 385 | ||
@@ -842,15 +841,13 @@ void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat) | |||
842 | set_extent_mask_and_shift(crypt_stat); | 841 | set_extent_mask_and_shift(crypt_stat); |
843 | crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES; | 842 | crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES; |
844 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | 843 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) |
845 | crypt_stat->num_header_extents_at_front = 0; | 844 | crypt_stat->num_header_bytes_at_front = 0; |
846 | else { | 845 | else { |
847 | if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) | 846 | if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) |
848 | crypt_stat->num_header_extents_at_front = | 847 | crypt_stat->num_header_bytes_at_front = |
849 | (ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE | 848 | ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; |
850 | / crypt_stat->extent_size); | ||
851 | else | 849 | else |
852 | crypt_stat->num_header_extents_at_front = | 850 | crypt_stat->num_header_bytes_at_front = PAGE_CACHE_SIZE; |
853 | (PAGE_CACHE_SIZE / crypt_stat->extent_size); | ||
854 | } | 851 | } |
855 | } | 852 | } |
856 | 853 | ||
@@ -1236,7 +1233,8 @@ ecryptfs_write_header_metadata(char *virt, | |||
1236 | 1233 | ||
1237 | header_extent_size = (u32)crypt_stat->extent_size; | 1234 | header_extent_size = (u32)crypt_stat->extent_size; |
1238 | num_header_extents_at_front = | 1235 | num_header_extents_at_front = |
1239 | (u16)crypt_stat->num_header_extents_at_front; | 1236 | (u16)(crypt_stat->num_header_bytes_at_front |
1237 | / crypt_stat->extent_size); | ||
1240 | header_extent_size = cpu_to_be32(header_extent_size); | 1238 | header_extent_size = cpu_to_be32(header_extent_size); |
1241 | memcpy(virt, &header_extent_size, 4); | 1239 | memcpy(virt, &header_extent_size, 4); |
1242 | virt += 4; | 1240 | virt += 4; |
@@ -1311,40 +1309,16 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t *size, | |||
1311 | static int | 1309 | static int |
1312 | ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat, | 1310 | ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat, |
1313 | struct dentry *ecryptfs_dentry, | 1311 | struct dentry *ecryptfs_dentry, |
1314 | char *page_virt) | 1312 | char *virt) |
1315 | { | 1313 | { |
1316 | int current_header_page; | ||
1317 | int header_pages; | ||
1318 | int rc; | 1314 | int rc; |
1319 | 1315 | ||
1320 | rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, page_virt, | 1316 | rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, virt, |
1321 | 0, PAGE_CACHE_SIZE); | 1317 | 0, crypt_stat->num_header_bytes_at_front); |
1322 | if (rc) { | 1318 | if (rc) |
1323 | printk(KERN_ERR "%s: Error attempting to write header " | 1319 | printk(KERN_ERR "%s: Error attempting to write header " |
1324 | "information to lower file; rc = [%d]\n", __FUNCTION__, | 1320 | "information to lower file; rc = [%d]\n", __FUNCTION__, |
1325 | rc); | 1321 | rc); |
1326 | goto out; | ||
1327 | } | ||
1328 | header_pages = ((crypt_stat->extent_size | ||
1329 | * crypt_stat->num_header_extents_at_front) | ||
1330 | / PAGE_CACHE_SIZE); | ||
1331 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
1332 | current_header_page = 1; | ||
1333 | while (current_header_page < header_pages) { | ||
1334 | loff_t offset; | ||
1335 | |||
1336 | offset = (((loff_t)current_header_page) << PAGE_CACHE_SHIFT); | ||
1337 | if ((rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, | ||
1338 | page_virt, offset, | ||
1339 | PAGE_CACHE_SIZE))) { | ||
1340 | printk(KERN_ERR "%s: Error attempting to write header " | ||
1341 | "information to lower file; rc = [%d]\n", | ||
1342 | __FUNCTION__, rc); | ||
1343 | goto out; | ||
1344 | } | ||
1345 | current_header_page++; | ||
1346 | } | ||
1347 | out: | ||
1348 | return rc; | 1322 | return rc; |
1349 | } | 1323 | } |
1350 | 1324 | ||
@@ -1370,15 +1344,13 @@ ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, | |||
1370 | * retrieved via a prompt. Exactly what happens at this point should | 1344 | * retrieved via a prompt. Exactly what happens at this point should |
1371 | * be policy-dependent. | 1345 | * be policy-dependent. |
1372 | * | 1346 | * |
1373 | * TODO: Support header information spanning multiple pages | ||
1374 | * | ||
1375 | * Returns zero on success; non-zero on error | 1347 | * Returns zero on success; non-zero on error |
1376 | */ | 1348 | */ |
1377 | int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) | 1349 | int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) |
1378 | { | 1350 | { |
1379 | struct ecryptfs_crypt_stat *crypt_stat = | 1351 | struct ecryptfs_crypt_stat *crypt_stat = |
1380 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; | 1352 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; |
1381 | char *page_virt; | 1353 | char *virt; |
1382 | size_t size = 0; | 1354 | size_t size = 0; |
1383 | int rc = 0; | 1355 | int rc = 0; |
1384 | 1356 | ||
@@ -1389,40 +1361,39 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) | |||
1389 | goto out; | 1361 | goto out; |
1390 | } | 1362 | } |
1391 | } else { | 1363 | } else { |
1364 | printk(KERN_WARNING "%s: Encrypted flag not set\n", | ||
1365 | __FUNCTION__); | ||
1392 | rc = -EINVAL; | 1366 | rc = -EINVAL; |
1393 | ecryptfs_printk(KERN_WARNING, | ||
1394 | "Called with crypt_stat->encrypted == 0\n"); | ||
1395 | goto out; | 1367 | goto out; |
1396 | } | 1368 | } |
1397 | /* Released in this function */ | 1369 | /* Released in this function */ |
1398 | page_virt = kmem_cache_zalloc(ecryptfs_header_cache_0, GFP_USER); | 1370 | virt = kzalloc(crypt_stat->num_header_bytes_at_front, GFP_KERNEL); |
1399 | if (!page_virt) { | 1371 | if (!virt) { |
1400 | ecryptfs_printk(KERN_ERR, "Out of memory\n"); | 1372 | printk(KERN_ERR "%s: Out of memory\n", __FUNCTION__); |
1401 | rc = -ENOMEM; | 1373 | rc = -ENOMEM; |
1402 | goto out; | 1374 | goto out; |
1403 | } | 1375 | } |
1404 | rc = ecryptfs_write_headers_virt(page_virt, &size, crypt_stat, | 1376 | rc = ecryptfs_write_headers_virt(virt, &size, crypt_stat, |
1405 | ecryptfs_dentry); | 1377 | ecryptfs_dentry); |
1406 | if (unlikely(rc)) { | 1378 | if (unlikely(rc)) { |
1407 | ecryptfs_printk(KERN_ERR, "Error whilst writing headers\n"); | 1379 | printk(KERN_ERR "%s: Error whilst writing headers; rc = [%d]\n", |
1408 | memset(page_virt, 0, PAGE_CACHE_SIZE); | 1380 | __FUNCTION__, rc); |
1409 | goto out_free; | 1381 | goto out_free; |
1410 | } | 1382 | } |
1411 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | 1383 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) |
1412 | rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, | 1384 | rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, |
1413 | crypt_stat, page_virt, | 1385 | crypt_stat, virt, size); |
1414 | size); | ||
1415 | else | 1386 | else |
1416 | rc = ecryptfs_write_metadata_to_contents(crypt_stat, | 1387 | rc = ecryptfs_write_metadata_to_contents(crypt_stat, |
1417 | ecryptfs_dentry, | 1388 | ecryptfs_dentry, virt); |
1418 | page_virt); | ||
1419 | if (rc) { | 1389 | if (rc) { |
1420 | printk(KERN_ERR "Error writing metadata out to lower file; " | 1390 | printk(KERN_ERR "%s: Error writing metadata out to lower file; " |
1421 | "rc = [%d]\n", rc); | 1391 | "rc = [%d]\n", __FUNCTION__, rc); |
1422 | goto out_free; | 1392 | goto out_free; |
1423 | } | 1393 | } |
1424 | out_free: | 1394 | out_free: |
1425 | kmem_cache_free(ecryptfs_header_cache_0, page_virt); | 1395 | memset(virt, 0, crypt_stat->num_header_bytes_at_front); |
1396 | kfree(virt); | ||
1426 | out: | 1397 | out: |
1427 | return rc; | 1398 | return rc; |
1428 | } | 1399 | } |
@@ -1442,16 +1413,16 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat, | |||
1442 | virt += sizeof(u32); | 1413 | virt += sizeof(u32); |
1443 | memcpy(&num_header_extents_at_front, virt, sizeof(u16)); | 1414 | memcpy(&num_header_extents_at_front, virt, sizeof(u16)); |
1444 | num_header_extents_at_front = be16_to_cpu(num_header_extents_at_front); | 1415 | num_header_extents_at_front = be16_to_cpu(num_header_extents_at_front); |
1445 | crypt_stat->num_header_extents_at_front = | 1416 | crypt_stat->num_header_bytes_at_front = |
1446 | (int)num_header_extents_at_front; | 1417 | (((size_t)num_header_extents_at_front |
1418 | * (size_t)header_extent_size)); | ||
1447 | (*bytes_read) = (sizeof(u32) + sizeof(u16)); | 1419 | (*bytes_read) = (sizeof(u32) + sizeof(u16)); |
1448 | if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE) | 1420 | if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE) |
1449 | && ((crypt_stat->extent_size | 1421 | && (crypt_stat->num_header_bytes_at_front |
1450 | * crypt_stat->num_header_extents_at_front) | ||
1451 | < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) { | 1422 | < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) { |
1452 | rc = -EINVAL; | 1423 | rc = -EINVAL; |
1453 | printk(KERN_WARNING "Invalid number of header extents: [%zd]\n", | 1424 | printk(KERN_WARNING "Invalid header size: [%zd]\n", |
1454 | crypt_stat->num_header_extents_at_front); | 1425 | crypt_stat->num_header_bytes_at_front); |
1455 | } | 1426 | } |
1456 | return rc; | 1427 | return rc; |
1457 | } | 1428 | } |
@@ -1466,7 +1437,8 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat, | |||
1466 | */ | 1437 | */ |
1467 | static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat) | 1438 | static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat) |
1468 | { | 1439 | { |
1469 | crypt_stat->num_header_extents_at_front = 2; | 1440 | crypt_stat->num_header_bytes_at_front = |
1441 | ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; | ||
1470 | } | 1442 | } |
1471 | 1443 | ||
1472 | /** | 1444 | /** |