aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@google.com>2015-04-12 00:56:28 -0400
committerTheodore Ts'o <tytso@mit.edu>2015-04-12 00:56:28 -0400
commit4bdfc873ba34e425d6532581b4127b960274272a (patch)
treebb025d46b0de4bee9a650ef679b0729a82b2772c /fs/ext4
parent2f61830ae33e2944ad66bb8bb40916f534b2e494 (diff)
ext4 crypto: insert encrypted filenames into a leaf directory block
Signed-off-by: Uday Savagaonkar <savagaon@google.com> Signed-off-by: Ildar Muslukhov <ildarm@google.com> Signed-off-by: Michael Halcrow <mhalcrow@google.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/ext4.h4
-rw-r--r--fs/ext4/inline.c7
-rw-r--r--fs/ext4/namei.c81
3 files changed, 79 insertions, 13 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index ba75838f3588..5146e67e8d51 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2151,9 +2151,11 @@ extern int ext4_find_dest_de(struct inode *dir, struct inode *inode,
2151 void *buf, int buf_size, 2151 void *buf, int buf_size,
2152 const char *name, int namelen, 2152 const char *name, int namelen,
2153 struct ext4_dir_entry_2 **dest_de); 2153 struct ext4_dir_entry_2 **dest_de);
2154void ext4_insert_dentry(struct inode *inode, 2154int ext4_insert_dentry(struct inode *dir,
2155 struct inode *inode,
2155 struct ext4_dir_entry_2 *de, 2156 struct ext4_dir_entry_2 *de,
2156 int buf_size, 2157 int buf_size,
2158 const struct qstr *iname,
2157 const char *name, int namelen); 2159 const char *name, int namelen);
2158static inline void ext4_update_dx_flag(struct inode *inode) 2160static inline void ext4_update_dx_flag(struct inode *inode)
2159{ 2161{
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index 661f0b8dcfe0..feb2cafbeace 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -11,11 +11,13 @@
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 */ 13 */
14
15#include <linux/fiemap.h>
16
14#include "ext4_jbd2.h" 17#include "ext4_jbd2.h"
15#include "ext4.h" 18#include "ext4.h"
16#include "xattr.h" 19#include "xattr.h"
17#include "truncate.h" 20#include "truncate.h"
18#include <linux/fiemap.h>
19 21
20#define EXT4_XATTR_SYSTEM_DATA "data" 22#define EXT4_XATTR_SYSTEM_DATA "data"
21#define EXT4_MIN_INLINE_DATA_SIZE ((sizeof(__le32) * EXT4_N_BLOCKS)) 23#define EXT4_MIN_INLINE_DATA_SIZE ((sizeof(__le32) * EXT4_N_BLOCKS))
@@ -1014,7 +1016,8 @@ static int ext4_add_dirent_to_inline(handle_t *handle,
1014 err = ext4_journal_get_write_access(handle, iloc->bh); 1016 err = ext4_journal_get_write_access(handle, iloc->bh);
1015 if (err) 1017 if (err)
1016 return err; 1018 return err;
1017 ext4_insert_dentry(inode, de, inline_size, name, namelen); 1019 ext4_insert_dentry(dir, inode, de, inline_size, &dentry->d_name,
1020 name, namelen);
1018 1021
1019 ext4_show_inline_dir(dir, iloc->bh, inline_start, inline_size); 1022 ext4_show_inline_dir(dir, iloc->bh, inline_start, inline_size);
1020 1023
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 8cef115ee64a..eb11a1b8a3d5 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1665,19 +1665,49 @@ int ext4_find_dest_de(struct inode *dir, struct inode *inode,
1665 return 0; 1665 return 0;
1666} 1666}
1667 1667
1668void ext4_insert_dentry(struct inode *inode, 1668int ext4_insert_dentry(struct inode *dir,
1669 struct ext4_dir_entry_2 *de, 1669 struct inode *inode,
1670 int buf_size, 1670 struct ext4_dir_entry_2 *de,
1671 const char *name, int namelen) 1671 int buf_size,
1672 const struct qstr *iname,
1673 const char *name, int namelen)
1672{ 1674{
1673 1675
1674 int nlen, rlen; 1676 int nlen, rlen;
1677 struct ext4_fname_crypto_ctx *ctx = NULL;
1678 struct ext4_str fname_crypto_str = {.name = NULL, .len = 0};
1679 struct ext4_str tmp_str;
1680 int res;
1681
1682 ctx = ext4_get_fname_crypto_ctx(dir, EXT4_NAME_LEN);
1683 if (IS_ERR(ctx))
1684 return -EIO;
1685 /* By default, the input name would be written to the disk */
1686 tmp_str.name = (unsigned char *)name;
1687 tmp_str.len = namelen;
1688 if (ctx != NULL) {
1689 /* Directory is encrypted */
1690 res = ext4_fname_crypto_alloc_buffer(ctx, EXT4_NAME_LEN,
1691 &fname_crypto_str);
1692 if (res < 0) {
1693 ext4_put_fname_crypto_ctx(&ctx);
1694 return -ENOMEM;
1695 }
1696 res = ext4_fname_usr_to_disk(ctx, iname, &fname_crypto_str);
1697 if (res < 0) {
1698 ext4_put_fname_crypto_ctx(&ctx);
1699 ext4_fname_crypto_free_buffer(&fname_crypto_str);
1700 return res;
1701 }
1702 tmp_str.name = fname_crypto_str.name;
1703 tmp_str.len = fname_crypto_str.len;
1704 }
1675 1705
1676 nlen = EXT4_DIR_REC_LEN(de->name_len); 1706 nlen = EXT4_DIR_REC_LEN(de->name_len);
1677 rlen = ext4_rec_len_from_disk(de->rec_len, buf_size); 1707 rlen = ext4_rec_len_from_disk(de->rec_len, buf_size);
1678 if (de->inode) { 1708 if (de->inode) {
1679 struct ext4_dir_entry_2 *de1 = 1709 struct ext4_dir_entry_2 *de1 =
1680 (struct ext4_dir_entry_2 *)((char *)de + nlen); 1710 (struct ext4_dir_entry_2 *)((char *)de + nlen);
1681 de1->rec_len = ext4_rec_len_to_disk(rlen - nlen, buf_size); 1711 de1->rec_len = ext4_rec_len_to_disk(rlen - nlen, buf_size);
1682 de->rec_len = ext4_rec_len_to_disk(nlen, buf_size); 1712 de->rec_len = ext4_rec_len_to_disk(nlen, buf_size);
1683 de = de1; 1713 de = de1;
@@ -1685,9 +1715,14 @@ void ext4_insert_dentry(struct inode *inode,
1685 de->file_type = EXT4_FT_UNKNOWN; 1715 de->file_type = EXT4_FT_UNKNOWN;
1686 de->inode = cpu_to_le32(inode->i_ino); 1716 de->inode = cpu_to_le32(inode->i_ino);
1687 ext4_set_de_type(inode->i_sb, de, inode->i_mode); 1717 ext4_set_de_type(inode->i_sb, de, inode->i_mode);
1688 de->name_len = namelen; 1718 de->name_len = tmp_str.len;
1689 memcpy(de->name, name, namelen); 1719
1720 memcpy(de->name, tmp_str.name, tmp_str.len);
1721 ext4_put_fname_crypto_ctx(&ctx);
1722 ext4_fname_crypto_free_buffer(&fname_crypto_str);
1723 return 0;
1690} 1724}
1725
1691/* 1726/*
1692 * Add a new entry into a directory (leaf) block. If de is non-NULL, 1727 * Add a new entry into a directory (leaf) block. If de is non-NULL,
1693 * it points to a directory entry which is guaranteed to be large 1728 * it points to a directory entry which is guaranteed to be large
@@ -1724,8 +1759,12 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
1724 return err; 1759 return err;
1725 } 1760 }
1726 1761
1727 /* By now the buffer is marked for journaling */ 1762 /* By now the buffer is marked for journaling. Due to crypto operations,
1728 ext4_insert_dentry(inode, de, blocksize, name, namelen); 1763 * the following function call may fail */
1764 err = ext4_insert_dentry(dir, inode, de, blocksize, &dentry->d_name,
1765 name, namelen);
1766 if (err < 0)
1767 return err;
1729 1768
1730 /* 1769 /*
1731 * XXX shouldn't update any times until successful 1770 * XXX shouldn't update any times until successful
@@ -1757,8 +1796,13 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
1757 struct inode *inode, struct buffer_head *bh) 1796 struct inode *inode, struct buffer_head *bh)
1758{ 1797{
1759 struct inode *dir = dentry->d_parent->d_inode; 1798 struct inode *dir = dentry->d_parent->d_inode;
1799#ifdef CONFIG_EXT4_FS_ENCRYPTION
1800 struct ext4_fname_crypto_ctx *ctx = NULL;
1801 int res;
1802#else
1760 const char *name = dentry->d_name.name; 1803 const char *name = dentry->d_name.name;
1761 int namelen = dentry->d_name.len; 1804 int namelen = dentry->d_name.len;
1805#endif
1762 struct buffer_head *bh2; 1806 struct buffer_head *bh2;
1763 struct dx_root *root; 1807 struct dx_root *root;
1764 struct dx_frame frames[2], *frame; 1808 struct dx_frame frames[2], *frame;
@@ -1772,7 +1816,13 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
1772 struct dx_hash_info hinfo; 1816 struct dx_hash_info hinfo;
1773 ext4_lblk_t block; 1817 ext4_lblk_t block;
1774 struct fake_dirent *fde; 1818 struct fake_dirent *fde;
1775 int csum_size = 0; 1819 int csum_size = 0;
1820
1821#ifdef CONFIG_EXT4_FS_ENCRYPTION
1822 ctx = ext4_get_fname_crypto_ctx(dir, EXT4_NAME_LEN);
1823 if (IS_ERR(ctx))
1824 return PTR_ERR(ctx);
1825#endif
1776 1826
1777 if (ext4_has_metadata_csum(inode->i_sb)) 1827 if (ext4_has_metadata_csum(inode->i_sb))
1778 csum_size = sizeof(struct ext4_dir_entry_tail); 1828 csum_size = sizeof(struct ext4_dir_entry_tail);
@@ -1839,7 +1889,18 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
1839 if (hinfo.hash_version <= DX_HASH_TEA) 1889 if (hinfo.hash_version <= DX_HASH_TEA)
1840 hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned; 1890 hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
1841 hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed; 1891 hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
1892#ifdef CONFIG_EXT4_FS_ENCRYPTION
1893 res = ext4_fname_usr_to_hash(ctx, &dentry->d_name, &hinfo);
1894 if (res < 0) {
1895 ext4_put_fname_crypto_ctx(&ctx);
1896 ext4_mark_inode_dirty(handle, dir);
1897 brelse(bh);
1898 return res;
1899 }
1900 ext4_put_fname_crypto_ctx(&ctx);
1901#else
1842 ext4fs_dirhash(name, namelen, &hinfo); 1902 ext4fs_dirhash(name, namelen, &hinfo);
1903#endif
1843 memset(frames, 0, sizeof(frames)); 1904 memset(frames, 0, sizeof(frames));
1844 frame = frames; 1905 frame = frames;
1845 frame->entries = entries; 1906 frame->entries = entries;