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.