mirror of
https://github.com/linux-apfs/linux-apfs-rw.git
synced 2026-08-18 02:19:59 -07:00
Allow internal reads of huge xattrs
The Linux xattr syscalls don't support values of more than 64k, but the
module still needs to use bigger xattrs internally to support compressed
files. When I refactored the xattr code in commit 9b71ea9b0f ("Use the
common dstream code to read dstream xattrs"), it seems that I thought I
could simplify an overflow check on the xattr size by simply checking
against this upper limit, but that broke compressed reads.
Revert the bad change, and put the xattr size check directly inside the
apfs_xattr_get() handler, where it won't bother internal code.
Signed-off-by: Ernesto A. Fernández <ernesto@corellium.com>
This commit is contained in:
1 parent
9c117a8126
commit
362c4e32ab
2 files changed
+7
-8
No files matched your search
@@ -862,8 +862,6 @@ extern int ____apfs_xattr_get(struct inode *inode, const char *name, void *buffe
|
||||
size_t size, bool only_whole);
|
||||
extern int __apfs_xattr_get(struct inode *inode, const char *name, void *buffer,
|
||||
size_t size);
|
||||
extern int apfs_xattr_get(struct inode *inode, const char *name, void *buffer,
|
||||
size_t size);
|
||||
extern int apfs_delete_all_xattrs(struct inode *inode);
|
||||
extern int apfs_xattr_set(struct inode *inode, const char *name, const void *value,
|
||||
size_t size, int flags);
|
||||
|
||||
@@ -104,11 +104,11 @@ static int apfs_xattr_extents_read(struct inode *parent,
|
||||
return -ENOMEM;
|
||||
apfs_dstream_from_xattr(sb, xattr, dstream);
|
||||
|
||||
if (dstream->ds_size > XATTR_SIZE_MAX) {
|
||||
ret = -E2BIG;
|
||||
goto out;
|
||||
}
|
||||
length = dstream->ds_size;
|
||||
if (length < 0 || length < dstream->ds_size) {
|
||||
/* TODO: avoid overflow here for huge compressed files */
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
if (!buffer) {
|
||||
/* All we want is the length */
|
||||
@@ -269,8 +269,7 @@ done:
|
||||
* Returns the number of bytes used/required, or a negative error code in case
|
||||
* of failure.
|
||||
*/
|
||||
int apfs_xattr_get(struct inode *inode, const char *name, void *buffer,
|
||||
size_t size)
|
||||
static int apfs_xattr_get(struct inode *inode, const char *name, void *buffer, size_t size)
|
||||
{
|
||||
struct apfs_nxsb_info *nxi = APFS_NXI(inode->i_sb);
|
||||
int ret;
|
||||
@@ -278,6 +277,8 @@ int apfs_xattr_get(struct inode *inode, const char *name, void *buffer,
|
||||
down_read(&nxi->nx_big_sem);
|
||||
ret = __apfs_xattr_get(inode, name, buffer, size);
|
||||
up_read(&nxi->nx_big_sem);
|
||||
if (ret > XATTR_SIZE_MAX)
|
||||
return -E2BIG;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user