mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2026-01-27 12:47:24 +01:00
Squashfs: fix uninit-value in squashfs_get_parent
Syzkaller reports a "KMSAN: uninit-value in squashfs_get_parent" bug.
This is caused by open_by_handle_at() being called with a file handle
containing an invalid parent inode number. In particular the inode number
is that of a symbolic link, rather than a directory.
Squashfs_get_parent() gets called with that symbolic link inode, and
accesses the parent member field.
unsigned int parent_ino = squashfs_i(inode)->parent;
Because non-directory inodes in Squashfs do not have a parent value, this
is uninitialised, and this causes an uninitialised value access.
The fix is to initialise parent with the invalid inode 0, which will cause
an EINVAL error to be returned.
Regular inodes used to share the parent field with the block_list_start
field. This is removed in this commit to enable the parent field to
contain the invalid inode number 0.
Link: https://lkml.kernel.org/r/20250918233308.293861-1-phillip@squashfs.org.uk
Fixes: 122601408d ("Squashfs: export operations")
Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
Reported-by: syzbot+157bdef5cf596ad0da2c@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/68cc2431.050a0220.139b6.0001.GAE@google.com/
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
f322a97aeb
commit
74058c0a9f
|
|
@ -169,6 +169,7 @@ int squashfs_read_inode(struct inode *inode, long long ino)
|
|||
squashfs_i(inode)->start = le32_to_cpu(sqsh_ino->start_block);
|
||||
squashfs_i(inode)->block_list_start = block;
|
||||
squashfs_i(inode)->offset = offset;
|
||||
squashfs_i(inode)->parent = 0;
|
||||
inode->i_data.a_ops = &squashfs_aops;
|
||||
|
||||
TRACE("File inode %x:%x, start_block %llx, block_list_start "
|
||||
|
|
@ -216,6 +217,7 @@ int squashfs_read_inode(struct inode *inode, long long ino)
|
|||
squashfs_i(inode)->start = le64_to_cpu(sqsh_ino->start_block);
|
||||
squashfs_i(inode)->block_list_start = block;
|
||||
squashfs_i(inode)->offset = offset;
|
||||
squashfs_i(inode)->parent = 0;
|
||||
inode->i_data.a_ops = &squashfs_aops;
|
||||
|
||||
TRACE("File inode %x:%x, start_block %llx, block_list_start "
|
||||
|
|
@ -296,6 +298,7 @@ int squashfs_read_inode(struct inode *inode, long long ino)
|
|||
inode->i_mode |= S_IFLNK;
|
||||
squashfs_i(inode)->start = block;
|
||||
squashfs_i(inode)->offset = offset;
|
||||
squashfs_i(inode)->parent = 0;
|
||||
|
||||
if (type == SQUASHFS_LSYMLINK_TYPE) {
|
||||
__le32 xattr;
|
||||
|
|
@ -333,6 +336,7 @@ int squashfs_read_inode(struct inode *inode, long long ino)
|
|||
set_nlink(inode, le32_to_cpu(sqsh_ino->nlink));
|
||||
rdev = le32_to_cpu(sqsh_ino->rdev);
|
||||
init_special_inode(inode, inode->i_mode, new_decode_dev(rdev));
|
||||
squashfs_i(inode)->parent = 0;
|
||||
|
||||
TRACE("Device inode %x:%x, rdev %x\n",
|
||||
SQUASHFS_INODE_BLK(ino), offset, rdev);
|
||||
|
|
@ -357,6 +361,7 @@ int squashfs_read_inode(struct inode *inode, long long ino)
|
|||
set_nlink(inode, le32_to_cpu(sqsh_ino->nlink));
|
||||
rdev = le32_to_cpu(sqsh_ino->rdev);
|
||||
init_special_inode(inode, inode->i_mode, new_decode_dev(rdev));
|
||||
squashfs_i(inode)->parent = 0;
|
||||
|
||||
TRACE("Device inode %x:%x, rdev %x\n",
|
||||
SQUASHFS_INODE_BLK(ino), offset, rdev);
|
||||
|
|
@ -377,6 +382,7 @@ int squashfs_read_inode(struct inode *inode, long long ino)
|
|||
inode->i_mode |= S_IFSOCK;
|
||||
set_nlink(inode, le32_to_cpu(sqsh_ino->nlink));
|
||||
init_special_inode(inode, inode->i_mode, 0);
|
||||
squashfs_i(inode)->parent = 0;
|
||||
break;
|
||||
}
|
||||
case SQUASHFS_LFIFO_TYPE:
|
||||
|
|
@ -396,6 +402,7 @@ int squashfs_read_inode(struct inode *inode, long long ino)
|
|||
inode->i_op = &squashfs_inode_ops;
|
||||
set_nlink(inode, le32_to_cpu(sqsh_ino->nlink));
|
||||
init_special_inode(inode, inode->i_mode, 0);
|
||||
squashfs_i(inode)->parent = 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ struct squashfs_inode_info {
|
|||
u64 xattr;
|
||||
unsigned int xattr_size;
|
||||
int xattr_count;
|
||||
int parent;
|
||||
union {
|
||||
struct {
|
||||
u64 fragment_block;
|
||||
|
|
@ -27,7 +28,6 @@ struct squashfs_inode_info {
|
|||
u64 dir_idx_start;
|
||||
int dir_idx_offset;
|
||||
int dir_idx_cnt;
|
||||
int parent;
|
||||
};
|
||||
};
|
||||
struct inode vfs_inode;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user