mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-16 04:04:06 +00:00
\n
-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEq1nRK9aeMoq1VSgcnJ2qBz9kQNkFAmEBWkcACgkQnJ2qBz9k QNlc2Af/dJBIzZmwPiqW/3vg8/2NihuKnhlkR0ytF5pGswDiZ/3jpNoapz53UeMy is73PwCqrBYII923Q//+TsiRSGELbmo5nY+xRKlAmg4yovVti+/fgkg2sYdHLfz5 SwMpZjtpqnJ6sfKY6wnN4nXJ0JfGR6Q52wfMWmYQbpQaHLPy1XVUBmKKh+TKwuqy 5S7OhYQ/sml3pdlHhQ5AoG0glgM12DiC5DvqJjwThWmZbsGNfpOw578XC9suCdKJ 6/Wvxm2KiKcltoSb/5LzRTOSIJNtBX7XXwUQewRXnXclEbZYhb5cob/HBkoAU0Nw 4LxVXzxnF3SDwx1thtkgoJ6qUclDWg== =/q9+ -----END PGP SIGNATURE----- Merge tag 'fixes_for_v5.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs Pull ext2 and reiserfs fixes from Jan Kara: "A fix for the ext2 conversion to kmap_local() and two reiserfs hardening fixes" * tag 'fixes_for_v5.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: reiserfs: check directory items on read from disk fs/ext2: Avoid page_address on pages returned by ext2_get_page reiserfs: add check for root_inode in reiserfs_fill_super
This commit is contained in:
commit
4010a52821
5 changed files with 44 additions and 14 deletions
|
@ -106,12 +106,11 @@ static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
|
|||
return err;
|
||||
}
|
||||
|
||||
static bool ext2_check_page(struct page *page, int quiet)
|
||||
static bool ext2_check_page(struct page *page, int quiet, char *kaddr)
|
||||
{
|
||||
struct inode *dir = page->mapping->host;
|
||||
struct super_block *sb = dir->i_sb;
|
||||
unsigned chunk_size = ext2_chunk_size(dir);
|
||||
char *kaddr = page_address(page);
|
||||
u32 max_inumber = le32_to_cpu(EXT2_SB(sb)->s_es->s_inodes_count);
|
||||
unsigned offs, rec_len;
|
||||
unsigned limit = PAGE_SIZE;
|
||||
|
@ -205,7 +204,8 @@ static struct page * ext2_get_page(struct inode *dir, unsigned long n,
|
|||
if (!IS_ERR(page)) {
|
||||
*page_addr = kmap_local_page(page);
|
||||
if (unlikely(!PageChecked(page))) {
|
||||
if (PageError(page) || !ext2_check_page(page, quiet))
|
||||
if (PageError(page) || !ext2_check_page(page, quiet,
|
||||
*page_addr))
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
@ -584,10 +584,10 @@ out_unlock:
|
|||
* ext2_delete_entry deletes a directory entry by merging it with the
|
||||
* previous entry. Page is up-to-date.
|
||||
*/
|
||||
int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
|
||||
int ext2_delete_entry (struct ext2_dir_entry_2 *dir, struct page *page,
|
||||
char *kaddr)
|
||||
{
|
||||
struct inode *inode = page->mapping->host;
|
||||
char *kaddr = page_address(page);
|
||||
unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
|
||||
unsigned to = ((char *)dir - kaddr) +
|
||||
ext2_rec_len_from_disk(dir->rec_len);
|
||||
|
@ -607,7 +607,7 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
|
|||
de = ext2_next_entry(de);
|
||||
}
|
||||
if (pde)
|
||||
from = (char*)pde - (char*)page_address(page);
|
||||
from = (char *)pde - kaddr;
|
||||
pos = page_offset(page) + from;
|
||||
lock_page(page);
|
||||
err = ext2_prepare_chunk(page, pos, to - from);
|
||||
|
|
|
@ -740,7 +740,8 @@ extern int ext2_inode_by_name(struct inode *dir,
|
|||
extern int ext2_make_empty(struct inode *, struct inode *);
|
||||
extern struct ext2_dir_entry_2 *ext2_find_entry(struct inode *, const struct qstr *,
|
||||
struct page **, void **res_page_addr);
|
||||
extern int ext2_delete_entry (struct ext2_dir_entry_2 *, struct page *);
|
||||
extern int ext2_delete_entry(struct ext2_dir_entry_2 *dir, struct page *page,
|
||||
char *kaddr);
|
||||
extern int ext2_empty_dir (struct inode *);
|
||||
extern struct ext2_dir_entry_2 *ext2_dotdot(struct inode *dir, struct page **p, void **pa);
|
||||
extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, void *,
|
||||
|
|
|
@ -293,7 +293,7 @@ static int ext2_unlink(struct inode * dir, struct dentry *dentry)
|
|||
goto out;
|
||||
}
|
||||
|
||||
err = ext2_delete_entry (de, page);
|
||||
err = ext2_delete_entry (de, page, page_addr);
|
||||
ext2_put_page(page, page_addr);
|
||||
if (err)
|
||||
goto out;
|
||||
|
@ -397,7 +397,7 @@ static int ext2_rename (struct user_namespace * mnt_userns,
|
|||
old_inode->i_ctime = current_time(old_inode);
|
||||
mark_inode_dirty(old_inode);
|
||||
|
||||
ext2_delete_entry(old_de, old_page);
|
||||
ext2_delete_entry(old_de, old_page, old_page_addr);
|
||||
|
||||
if (dir_de) {
|
||||
if (old_dir != new_dir)
|
||||
|
|
|
@ -387,6 +387,24 @@ void pathrelse(struct treepath *search_path)
|
|||
search_path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET;
|
||||
}
|
||||
|
||||
static int has_valid_deh_location(struct buffer_head *bh, struct item_head *ih)
|
||||
{
|
||||
struct reiserfs_de_head *deh;
|
||||
int i;
|
||||
|
||||
deh = B_I_DEH(bh, ih);
|
||||
for (i = 0; i < ih_entry_count(ih); i++) {
|
||||
if (deh_location(&deh[i]) > ih_item_len(ih)) {
|
||||
reiserfs_warning(NULL, "reiserfs-5094",
|
||||
"directory entry location seems wrong %h",
|
||||
&deh[i]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int is_leaf(char *buf, int blocksize, struct buffer_head *bh)
|
||||
{
|
||||
struct block_head *blkh;
|
||||
|
@ -454,11 +472,14 @@ static int is_leaf(char *buf, int blocksize, struct buffer_head *bh)
|
|||
"(second one): %h", ih);
|
||||
return 0;
|
||||
}
|
||||
if (is_direntry_le_ih(ih) && (ih_item_len(ih) < (ih_entry_count(ih) * IH_SIZE))) {
|
||||
reiserfs_warning(NULL, "reiserfs-5093",
|
||||
"item entry count seems wrong %h",
|
||||
ih);
|
||||
return 0;
|
||||
if (is_direntry_le_ih(ih)) {
|
||||
if (ih_item_len(ih) < (ih_entry_count(ih) * IH_SIZE)) {
|
||||
reiserfs_warning(NULL, "reiserfs-5093",
|
||||
"item entry count seems wrong %h",
|
||||
ih);
|
||||
return 0;
|
||||
}
|
||||
return has_valid_deh_location(bh, ih);
|
||||
}
|
||||
prev_location = ih_location(ih);
|
||||
}
|
||||
|
|
|
@ -2082,6 +2082,14 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
|
|||
unlock_new_inode(root_inode);
|
||||
}
|
||||
|
||||
if (!S_ISDIR(root_inode->i_mode) || !inode_get_bytes(root_inode) ||
|
||||
!root_inode->i_size) {
|
||||
SWARN(silent, s, "", "corrupt root inode, run fsck");
|
||||
iput(root_inode);
|
||||
errval = -EUCLEAN;
|
||||
goto error;
|
||||
}
|
||||
|
||||
s->s_root = d_make_root(root_inode);
|
||||
if (!s->s_root)
|
||||
goto error;
|
||||
|
|
Loading…
Add table
Reference in a new issue