Re: [PATCH 1/3] quota: Check next/prev free block number after reading from quota file

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

 



在 2022/9/21 21:37, Jan Kara 写道:
Hi Jan,
On Sat 20-08-22 19:05:12, Zhihao Cheng wrote:
Following process:
[...]

Link: https://bugzilla.kernel.org/show_bug.cgi?id=216372
Fixes: 1da177e4c3f4152 ("Linux-2.6.12-rc2")

It's better to just have:

CC: stable@xxxxxxxxxxxxxxx

here. Fixes tag pointing to kernel release is not very useful.
Will add in v2.

--- a/fs/quota/quota_tree.c
+++ b/fs/quota/quota_tree.c
@@ -71,6 +71,35 @@ static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf)
  	return ret;
  }
+static inline int do_check_range(struct super_block *sb, uint val, uint max_val)
+{
+	if (val >= max_val) {
+		quota_error(sb, "Getting block too big (%u >= %u)",
+			    val, max_val);
+		return -EUCLEAN;
+	}
+
+	return 0;
+}

I'd already provide min_val and the string for the message here as well (as
you do in patch 2). It is less churn in the next patch and free blocks
checking actually needs that as well. See below.

+
+static int check_free_block(struct qtree_mem_dqinfo *info,
+			    struct qt_disk_dqdbheader *dh)
+{
+	int err = 0;
+	uint nextblk, prevblk;
+
+	nextblk = le32_to_cpu(dh->dqdh_next_free);
+	err = do_check_range(info->dqi_sb, nextblk, info->dqi_blocks);
+	if (err)
+		return err;
+	prevblk = le32_to_cpu(dh->dqdh_prev_free);
+	err = do_check_range(info->dqi_sb, prevblk, info->dqi_blocks);
+	if (err)
+		return err;

The free block should actually be > QT_TREEOFF so I'd add the check to
do_check_range().

'dh->dqdh_next_free' may be updated when quota entry removed, 'dh->dqdh_next_free' can be used for next new quota entris. Before sending v2, I found 'dh->dqdh_next_free' and 'dh->dqdh_prev_free' can easily be zero in newly allocated blocks when continually creating files onwed by different users:
find_free_dqentry
  get_free_dqblk
    write_blk(info, info->dqi_blocks, buf)  // zero'd qt_disk_dqdbheader
    blk = info->dqi_blocks++   // allocate new one block
  info->dqi_free_entry = blk   // will be used for new quota entries

find_free_dqentry
  if (info->dqi_free_entry)
    blk = info->dqi_free_entry
read_blk(info, blk, buf) // dh->dqdh_next_free = dh->dqdh_prev_free = 0

I think it's normal when 'dh->dqdh_next_free' or 'dh->dqdh_prev_free' equals to 0.

Also rather than having check_free_block(), I'd provide a helper function
like check_dquot_block_header() which will check only free blocks pointers
now and in later patches you can add other checks there.
OK, will be updated in v2.

								Honza





[Index of Archives]     [Reiser Filesystem Development]     [Ceph FS]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite National Park]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Media]

  Powered by Linux