]> Git Repo - J-linux.git/commitdiff
Merge tag 'fs_for_v5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack...
authorLinus Torvalds <[email protected]>
Thu, 15 Oct 2020 21:56:15 +0000 (14:56 -0700)
committerLinus Torvalds <[email protected]>
Thu, 15 Oct 2020 21:56:15 +0000 (14:56 -0700)
Pull UDF, reiserfs, ext2, quota fixes from Jan Kara:

 - a couple of UDF fixes for issues found by syzbot fuzzing

 - a couple of reiserfs fixes for issues found by syzbot fuzzing

 - some minor ext2 cleanups

 - quota patches to support grace times beyond year 2038 for XFS quota
   APIs

* tag 'fs_for_v5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
  reiserfs: Fix oops during mount
  udf: Limit sparing table size
  udf: Remove pointless union in udf_inode_info
  udf: Avoid accessing uninitialized data on failed inode read
  quota: clear padding in v2r1_mem2diskdqb()
  reiserfs: Initialize inode keys properly
  udf: Fix memory leak when mounting
  udf: Remove redundant initialization of variable ret
  reiserfs: only call unlock_new_inode() if I_NEW
  ext2: Fix some kernel-doc warnings in balloc.c
  quota: Expand comment describing d_itimer
  quota: widen timestamps for the fs_disk_quota structure
  reiserfs: Fix memory leak in reiserfs_parse_options()
  udf: Use kvzalloc() in udf_sb_alloc_bitmap()
  ext2: remove duplicate include

1  2 
fs/quota/quota.c

diff --combined fs/quota/quota.c
index 6b37d58f1067d4f28da5a172610b3ffdb1c4e90f,52362eeaea94cac38877fda61f57f4c6f2dafdb4..9af95c7a0bbe3c26edfb710ecd6d1b74e3b5912d
@@@ -19,7 -19,6 +19,7 @@@
  #include <linux/types.h>
  #include <linux/writeback.h>
  #include <linux/nospec.h>
 +#include "compat.h"
  
  static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
                                     qid_t id)
@@@ -212,18 -211,8 +212,18 @@@ static int quota_getquota(struct super_
        if (ret)
                return ret;
        copy_to_if_dqblk(&idq, &fdq);
 -      if (copy_to_user(addr, &idq, sizeof(idq)))
 -              return -EFAULT;
 +
 +      if (compat_need_64bit_alignment_fixup()) {
 +              struct compat_if_dqblk __user *compat_dqblk = addr;
 +
 +              if (copy_to_user(compat_dqblk, &idq, sizeof(*compat_dqblk)))
 +                      return -EFAULT;
 +              if (put_user(idq.dqb_valid, &compat_dqblk->dqb_valid))
 +                      return -EFAULT;
 +      } else {
 +              if (copy_to_user(addr, &idq, sizeof(idq)))
 +                      return -EFAULT;
 +      }
        return 0;
  }
  
@@@ -288,16 -277,8 +288,16 @@@ static int quota_setquota(struct super_
        struct if_dqblk idq;
        struct kqid qid;
  
 -      if (copy_from_user(&idq, addr, sizeof(idq)))
 -              return -EFAULT;
 +      if (compat_need_64bit_alignment_fixup()) {
 +              struct compat_if_dqblk __user *compat_dqblk = addr;
 +
 +              if (copy_from_user(&idq, compat_dqblk, sizeof(*compat_dqblk)) ||
 +                  get_user(idq.dqb_valid, &compat_dqblk->dqb_valid))
 +                      return -EFAULT;
 +      } else {
 +              if (copy_from_user(&idq, addr, sizeof(idq)))
 +                      return -EFAULT;
 +      }
        if (!sb->s_qcop->set_dqblk)
                return -ENOSYS;
        qid = make_kqid(current_user_ns(), type, id);
@@@ -401,33 -382,6 +401,33 @@@ static int quota_getstate(struct super_
        return 0;
  }
  
 +static int compat_copy_fs_qfilestat(struct compat_fs_qfilestat __user *to,
 +              struct fs_qfilestat *from)
 +{
 +      if (copy_to_user(to, from, sizeof(*to)) ||
 +          put_user(from->qfs_nextents, &to->qfs_nextents))
 +              return -EFAULT;
 +      return 0;
 +}
 +
 +static int compat_copy_fs_quota_stat(struct compat_fs_quota_stat __user *to,
 +              struct fs_quota_stat *from)
 +{
 +      if (put_user(from->qs_version, &to->qs_version) ||
 +          put_user(from->qs_flags, &to->qs_flags) ||
 +          put_user(from->qs_pad, &to->qs_pad) ||
 +          compat_copy_fs_qfilestat(&to->qs_uquota, &from->qs_uquota) ||
 +          compat_copy_fs_qfilestat(&to->qs_gquota, &from->qs_gquota) ||
 +          put_user(from->qs_incoredqs, &to->qs_incoredqs) ||
 +          put_user(from->qs_btimelimit, &to->qs_btimelimit) ||
 +          put_user(from->qs_itimelimit, &to->qs_itimelimit) ||
 +          put_user(from->qs_rtbtimelimit, &to->qs_rtbtimelimit) ||
 +          put_user(from->qs_bwarnlimit, &to->qs_bwarnlimit) ||
 +          put_user(from->qs_iwarnlimit, &to->qs_iwarnlimit))
 +              return -EFAULT;
 +      return 0;
 +}
 +
  static int quota_getxstate(struct super_block *sb, int type, void __user *addr)
  {
        struct fs_quota_stat fqs;
        if (!sb->s_qcop->get_state)
                return -ENOSYS;
        ret = quota_getstate(sb, type, &fqs);
 -      if (!ret && copy_to_user(addr, &fqs, sizeof(fqs)))
 +      if (ret)
 +              return ret;
 +
 +      if (compat_need_64bit_alignment_fixup())
 +              return compat_copy_fs_quota_stat(addr, &fqs);
 +      if (copy_to_user(addr, &fqs, sizeof(fqs)))
                return -EFAULT;
 -      return ret;
 +      return 0;
  }
  
  static int quota_getstatev(struct super_block *sb, int type,
@@@ -532,6 -481,14 +532,14 @@@ static inline u64 quota_btobb(u64 bytes
        return (bytes + (1 << XFS_BB_SHIFT) - 1) >> XFS_BB_SHIFT;
  }
  
+ static inline s64 copy_from_xfs_dqblk_ts(const struct fs_disk_quota *d,
+               __s32 timer, __s8 timer_hi)
+ {
+       if (d->d_fieldmask & FS_DQ_BIGTIME)
+               return (u32)timer | (s64)timer_hi << 32;
+       return timer;
+ }
  static void copy_from_xfs_dqblk(struct qc_dqblk *dst, struct fs_disk_quota *src)
  {
        dst->d_spc_hardlimit = quota_bbtob(src->d_blk_hardlimit);
        dst->d_ino_softlimit = src->d_ino_softlimit;
        dst->d_space = quota_bbtob(src->d_bcount);
        dst->d_ino_count = src->d_icount;
-       dst->d_ino_timer = src->d_itimer;
-       dst->d_spc_timer = src->d_btimer;
+       dst->d_ino_timer = copy_from_xfs_dqblk_ts(src, src->d_itimer,
+                                                 src->d_itimer_hi);
+       dst->d_spc_timer = copy_from_xfs_dqblk_ts(src, src->d_btimer,
+                                                 src->d_btimer_hi);
        dst->d_ino_warns = src->d_iwarns;
        dst->d_spc_warns = src->d_bwarns;
        dst->d_rt_spc_hardlimit = quota_bbtob(src->d_rtb_hardlimit);
        dst->d_rt_spc_softlimit = quota_bbtob(src->d_rtb_softlimit);
        dst->d_rt_space = quota_bbtob(src->d_rtbcount);
-       dst->d_rt_spc_timer = src->d_rtbtimer;
+       dst->d_rt_spc_timer = copy_from_xfs_dqblk_ts(src, src->d_rtbtimer,
+                                                    src->d_rtbtimer_hi);
        dst->d_rt_spc_warns = src->d_rtbwarns;
        dst->d_fieldmask = 0;
        if (src->d_fieldmask & FS_DQ_ISOFT)
@@@ -639,10 -599,26 +650,26 @@@ static int quota_setxquota(struct super
        return sb->s_qcop->set_dqblk(sb, qid, &qdq);
  }
  
+ static inline void copy_to_xfs_dqblk_ts(const struct fs_disk_quota *d,
+               __s32 *timer_lo, __s8 *timer_hi, s64 timer)
+ {
+       *timer_lo = timer;
+       if (d->d_fieldmask & FS_DQ_BIGTIME)
+               *timer_hi = timer >> 32;
+ }
+ static inline bool want_bigtime(s64 timer)
+ {
+       return timer > S32_MAX || timer < S32_MIN;
+ }
  static void copy_to_xfs_dqblk(struct fs_disk_quota *dst, struct qc_dqblk *src,
                              int type, qid_t id)
  {
        memset(dst, 0, sizeof(*dst));
+       if (want_bigtime(src->d_ino_timer) || want_bigtime(src->d_spc_timer) ||
+           want_bigtime(src->d_rt_spc_timer))
+               dst->d_fieldmask |= FS_DQ_BIGTIME;
        dst->d_version = FS_DQUOT_VERSION;
        dst->d_id = id;
        if (type == USRQUOTA)
        dst->d_ino_softlimit = src->d_ino_softlimit;
        dst->d_bcount = quota_btobb(src->d_space);
        dst->d_icount = src->d_ino_count;
-       dst->d_itimer = src->d_ino_timer;
-       dst->d_btimer = src->d_spc_timer;
+       copy_to_xfs_dqblk_ts(dst, &dst->d_itimer, &dst->d_itimer_hi,
+                            src->d_ino_timer);
+       copy_to_xfs_dqblk_ts(dst, &dst->d_btimer, &dst->d_btimer_hi,
+                            src->d_spc_timer);
        dst->d_iwarns = src->d_ino_warns;
        dst->d_bwarns = src->d_spc_warns;
        dst->d_rtb_hardlimit = quota_btobb(src->d_rt_spc_hardlimit);
        dst->d_rtb_softlimit = quota_btobb(src->d_rt_spc_softlimit);
        dst->d_rtbcount = quota_btobb(src->d_rt_space);
-       dst->d_rtbtimer = src->d_rt_spc_timer;
+       copy_to_xfs_dqblk_ts(dst, &dst->d_rtbtimer, &dst->d_rtbtimer_hi,
+                            src->d_rt_spc_timer);
        dst->d_rtbwarns = src->d_rt_spc_warns;
  }
  
@@@ -867,8 -846,8 +897,8 @@@ static struct super_block *quotactl_blo
   * calls. Maybe we need to add the process quotas etc. in the future,
   * but we probably should use rlimits for that.
   */
 -int kernel_quotactl(unsigned int cmd, const char __user *special,
 -                  qid_t id, void __user *addr)
 +SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special,
 +              qid_t, id, void __user *, addr)
  {
        uint cmds, type;
        struct super_block *sb = NULL;
@@@ -922,3 -901,9 +952,3 @@@ out
                path_put(pathp);
        return ret;
  }
 -
 -SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special,
 -              qid_t, id, void __user *, addr)
 -{
 -      return kernel_quotactl(cmd, special, id, addr);
 -}
This page took 0.065559 seconds and 4 git commands to generate.