summaryrefslogtreecommitdiffstats
path: root/fs/ext4/inline.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2018-06-16 23:41:59 -0400
committerTheodore Ts'o <tytso@mit.edu>2018-06-16 23:41:59 -0400
commit8bc1379b82b8e809eef77a9fedbb75c6c297be19 (patch)
tree621b4e6f36dae1bf770c8bb9309028e80ece02c2 /fs/ext4/inline.c
parente09463f220ca9a1a1ecfda84fcda658f99a1f12a (diff)
ext4: avoid running out of journal credits when appending to an inline file
Use a separate journal transaction if it turns out that we need to convert an inline file to use an data block. Otherwise we could end up failing due to not having journal credits. This addresses CVE-2018-10883. https://bugzilla.kernel.org/show_bug.cgi?id=200071 Signed-off-by: Theodore Ts'o <tytso@mit.edu> Cc: stable@kernel.org
Diffstat (limited to 'fs/ext4/inline.c')
-rw-r--r--fs/ext4/inline.c38
1 files changed, 1 insertions, 37 deletions
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index d79115d8d716..851bc552d849 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -887,11 +887,11 @@ retry_journal:
887 flags |= AOP_FLAG_NOFS; 887 flags |= AOP_FLAG_NOFS;
888 888
889 if (ret == -ENOSPC) { 889 if (ret == -ENOSPC) {
890 ext4_journal_stop(handle);
890 ret = ext4_da_convert_inline_data_to_extent(mapping, 891 ret = ext4_da_convert_inline_data_to_extent(mapping,
891 inode, 892 inode,
892 flags, 893 flags,
893 fsdata); 894 fsdata);
894 ext4_journal_stop(handle);
895 if (ret == -ENOSPC && 895 if (ret == -ENOSPC &&
896 ext4_should_retry_alloc(inode->i_sb, &retries)) 896 ext4_should_retry_alloc(inode->i_sb, &retries))
897 goto retry_journal; 897 goto retry_journal;
@@ -1891,42 +1891,6 @@ out:
1891 return (error < 0 ? error : 0); 1891 return (error < 0 ? error : 0);
1892} 1892}
1893 1893
1894/*
1895 * Called during xattr set, and if we can sparse space 'needed',
1896 * just create the extent tree evict the data to the outer block.
1897 *
1898 * We use jbd2 instead of page cache to move data to the 1st block
1899 * so that the whole transaction can be committed as a whole and
1900 * the data isn't lost because of the delayed page cache write.
1901 */
1902int ext4_try_to_evict_inline_data(handle_t *handle,
1903 struct inode *inode,
1904 int needed)
1905{
1906 int error;
1907 struct ext4_xattr_entry *entry;
1908 struct ext4_inode *raw_inode;
1909 struct ext4_iloc iloc;
1910
1911 error = ext4_get_inode_loc(inode, &iloc);
1912 if (error)
1913 return error;
1914
1915 raw_inode = ext4_raw_inode(&iloc);
1916 entry = (struct ext4_xattr_entry *)((void *)raw_inode +
1917 EXT4_I(inode)->i_inline_off);
1918 if (EXT4_XATTR_LEN(entry->e_name_len) +
1919 EXT4_XATTR_SIZE(le32_to_cpu(entry->e_value_size)) < needed) {
1920 error = -ENOSPC;
1921 goto out;
1922 }
1923
1924 error = ext4_convert_inline_data_nolock(handle, inode, &iloc);
1925out:
1926 brelse(iloc.bh);
1927 return error;
1928}
1929
1930int ext4_inline_data_truncate(struct inode *inode, int *has_inline) 1894int ext4_inline_data_truncate(struct inode *inode, int *has_inline)
1931{ 1895{
1932 handle_t *handle; 1896 handle_t *handle;