Pull ntfs3 updates from Konstantin Komarov:
 "Added:
   - support for FS_IOC_{GET,SET}FSLABEL ioctl
   - reject index allocation if $BITMAP is empty but blocks exist

  Fixed:
   - integer overflow in run_unpack()
   - resource leak bug in wnd_extend()

  Changed:
   - pretend $Extend records as regular files
   - stop using write_cache_pages"

* tag 'ntfs3_for_6.18' of https://github.com/Paragon-Software-Group/linux-ntfs3:
  ntfs3: stop using write_cache_pages
  fs/ntfs3: reject index allocation if $BITMAP is empty but blocks exist
  fs/ntfs3: Fix a resource leak bug in wnd_extend()
  fs: ntfs3: Fix integer overflow in run_unpack()
  ntfs3: pretend $Extend records as regular files
  ntfs3: add FS_IOC_SETFSLABEL ioctl
  ntfs3: add FS_IOC_GETFSLABEL ioctl
  ntfs3: transition magic number to shared constant
This commit is contained in:
Linus Torvalds
2025-10-03 13:57:33 -07:00
6 changed files with 50 additions and 4 deletions
+1
View File
@@ -1371,6 +1371,7 @@ int wnd_extend(struct wnd_bitmap *wnd, size_t new_bits)
mark_buffer_dirty(bh);
unlock_buffer(bh);
/* err = sync_dirty_buffer(bh); */
put_bh(bh);
b0 = 0;
bits -= op;
+28
View File
@@ -49,6 +49,30 @@ static int ntfs_ioctl_fitrim(struct ntfs_sb_info *sbi, unsigned long arg)
return 0;
}
static int ntfs_ioctl_get_volume_label(struct ntfs_sb_info *sbi, u8 __user *buf)
{
if (copy_to_user(buf, sbi->volume.label, FSLABEL_MAX))
return -EFAULT;
return 0;
}
static int ntfs_ioctl_set_volume_label(struct ntfs_sb_info *sbi, u8 __user *buf)
{
u8 user[FSLABEL_MAX] = {0};
int len;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (copy_from_user(user, buf, FSLABEL_MAX))
return -EFAULT;
len = strnlen(user, FSLABEL_MAX);
return ntfs_set_label(sbi, user, len);
}
/*
* ntfs_ioctl - file_operations::unlocked_ioctl
*/
@@ -64,6 +88,10 @@ long ntfs_ioctl(struct file *filp, u32 cmd, unsigned long arg)
switch (cmd) {
case FITRIM:
return ntfs_ioctl_fitrim(sbi, arg);
case FS_IOC_GETFSLABEL:
return ntfs_ioctl_get_volume_label(sbi, (u8 __user *)arg);
case FS_IOC_SETFSLABEL:
return ntfs_ioctl_set_volume_label(sbi, (u8 __user *)arg);
}
return -ENOTTY; /* Inappropriate ioctl for device. */
}
+10
View File
@@ -1508,6 +1508,16 @@ static int indx_add_allocate(struct ntfs_index *indx, struct ntfs_inode *ni,
bmp_size = bmp_size_v = le32_to_cpu(bmp->res.data_size);
}
/*
* Index blocks exist, but $BITMAP has zero valid bits.
* This implies an on-disk corruption and must be rejected.
*/
if (in->name == I30_NAME &&
unlikely(bmp_size_v == 0 && indx->alloc_run.count)) {
err = -EINVAL;
goto out1;
}
bit = bmp_size << 3;
}
+1
View File
@@ -471,6 +471,7 @@ end_enum:
fname->home.seq == cpu_to_le16(MFT_REC_EXTEND)) {
/* Records in $Extend are not a files or general directories. */
inode->i_op = &ntfs_file_inode_operations;
mode = S_IFREG;
} else {
err = -EINVAL;
goto out;
+1 -1
View File
@@ -280,7 +280,7 @@ struct ntfs_sb_info {
__le16 flags; // Cached current VOLUME_INFO::flags, VOLUME_FLAG_DIRTY.
u8 major_ver;
u8 minor_ver;
char label[256];
char label[FSLABEL_MAX];
bool real_dirty; // Real fs state.
} volume;
+9 -3
View File
@@ -9,6 +9,7 @@
#include <linux/blkdev.h>
#include <linux/fs.h>
#include <linux/log2.h>
#include <linux/overflow.h>
#include "debug.h"
#include "ntfs.h"
@@ -982,14 +983,18 @@ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
if (!dlcn)
return -EINVAL;
lcn = prev_lcn + dlcn;
if (check_add_overflow(prev_lcn, dlcn, &lcn))
return -EINVAL;
prev_lcn = lcn;
} else {
/* The size of 'dlcn' can't be > 8. */
return -EINVAL;
}
next_vcn = vcn64 + len;
if (check_add_overflow(vcn64, len, &next_vcn))
return -EINVAL;
/* Check boundary. */
if (next_vcn > evcn + 1)
return -EINVAL;
@@ -1153,7 +1158,8 @@ int run_get_highest_vcn(CLST vcn, const u8 *run_buf, u64 *highest_vcn)
return -EINVAL;
run_buf += size_size + offset_size;
vcn64 += len;
if (check_add_overflow(vcn64, len, &vcn64))
return -EINVAL;
#ifndef CONFIG_NTFS3_64BIT_CLUSTER
if (vcn64 > 0x100000000ull)