Re: [PATCH vfs.all 08/26] erofs: prevent direct access of bd_inode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Apr 06, 2024 at 05:09:12PM +0800, Yu Kuai wrote:
> From: Yu Kuai <yukuai3@xxxxxxxxxx>
> 
> Now that all filesystems stash the bdev file, it's ok to get inode
> for the file.

Looking at the only user of erofs_buf->inode (erofs_bread())...  We
use the inode for two things there - block size calculation (to get
from block number to position in bytes) and access to page cache.
We read in full pages anyway.  And frankly, looking at the callers,
we really would be better off if we passed position in bytes instead
of block number.  IOW, it smells like erofs_bread() having wrong type.

Look at the callers.  With 3 exceptions it's
fs/erofs/super.c:135:   ptr = erofs_bread(buf, erofs_blknr(sb, *offset), EROFS_KMAP);
fs/erofs/super.c:151:           ptr = erofs_bread(buf, erofs_blknr(sb, *offset), EROFS_KMAP);
fs/erofs/xattr.c:84:    it.kaddr = erofs_bread(&it.buf, erofs_blknr(sb, it.pos), EROFS_KMAP);
fs/erofs/xattr.c:105:           it.kaddr = erofs_bread(&it.buf, erofs_blknr(sb, it.pos),
fs/erofs/xattr.c:188:           it->kaddr = erofs_bread(&it->buf, erofs_blknr(sb, it->pos),
fs/erofs/xattr.c:294:           it->kaddr = erofs_bread(&it->buf, erofs_blknr(sb, it->pos),
fs/erofs/xattr.c:339:           it->kaddr = erofs_bread(&it->buf, erofs_blknr(it->sb, it->pos),
fs/erofs/xattr.c:378:           it->kaddr = erofs_bread(&it->buf, erofs_blknr(sb, it->pos),
fs/erofs/zdata.c:943:           src = erofs_bread(&buf, erofs_blknr(sb, pos), EROFS_KMAP);

and all of them actually want the return value + erofs_offset(...).  IOW,
we take a linear position (in bytes).  Divide it by block size (from sb).
Pass the factor to erofs_bread(), where we multiply that by block size
(from inode), see which page will that be in, get that page and return a
pointer *into* that page.  Then we again divide the same position
by block size (from sb) and add the remainder to the pointer returned
by erofs_bread().

IOW, it would be much easier to pass the position directly and to hell
with block size logics.  Three exceptions to that pattern:

fs/erofs/data.c:80:     return erofs_bread(buf, blkaddr, type);
fs/erofs/dir.c:66:              de = erofs_bread(&buf, i, EROFS_KMAP);
fs/erofs/namei.c:103:           de = erofs_bread(&buf, mid, EROFS_KMAP);

Those could bloody well multiply the argument by block size;
the first one (erofs_read_metabuf()) is also interesting - its
callers themselves follow the similar pattern.  So it might be
worth passing it a position in bytes as well...

In any case, all 3 have superblock reference, so they can convert
from blocks to bytes conveniently.  Which means that erofs_bread()
doesn't need to mess with block size considerations at all.

IOW, it might make sense to replace erofs_buf->inode with
pointer to address space.  And use file_mapping() instead of
file_inode() in that patch...




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux