Menu

#113 Overflow when reading quota values from kernel

None
closed-fixed
nobody
None
5
2014-05-01
2013-09-17
Anonymous
No

Kernel quotactl() interface uses u_uit64_t to transfer block usage etc. However quota tools use qsize_t which is a int64_t.

When I hit a bug in GFS2 kernel driver, I got a very high number of block usage from the kernel. But when storing the value into quota tools structures, the value overflows. The quotaio_xfs.c:xfs_kern2utildqblk() does arithmetic without checking ranges:

static inline void xfs_kern2utildqblk(struct util_dqblk *u, struct xfs_kern_dqblk * k)
{
u->dqb_ihardlimit = k->d_ino_hardlimit;
u->dqb_isoftlimit = k->d_ino_softlimit;
u->dqb_bhardlimit = k->d_blk_hardlimit >> 1;
u->dqb_bsoftlimit = k->d_blk_softlimit >> 1;
u->dqb_curinodes = k->d_icount;
u->dqb_curspace = ((qsize_t)k->d_bcount) << 9;
u->dqb_itime = k->d_itimer;
u->dqb_btime = k->d_btimer;
}

Before I will try to implement necessary checks, I have a question: Why qsize_t is signed? Is it safe to change the typedef to u_int64_t? Various printf's format the value using %llu.

Discussion

  • Jan Kara

    Jan Kara - 2013-09-19

    qsize_t is signed in kernel, because cluster filesystems (such as GFS2 or OCFS2) can temporarily show negative quota usage because quota usage accounting isn't completely synchronized between nodes (this happens for example when you allocate files on one node and delete them on another node).

    So I think it is better to keep qsize_t signed and a check to xfs_kern2utildqblk().

     
  • Jan Kara

    Jan Kara - 2014-05-01

    OK, I made quota tools treat return used space and inodes as signed values.

     
  • Jan Kara

    Jan Kara - 2014-05-01
    • status: open --> closed-fixed
    • Group: -->
     

Anonymous
Anonymous

Add attachments
Cancel