Source-Changes-HG archive

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

[src/trunk]: src/sys/nfs NFSv2 is limited to use only 32bit in metadata. Prev...



details:   https://anonhg.NetBSD.org/src/rev/7b9a6bc2000d
branches:  trunk
changeset: 850406:7b9a6bc2000d
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Sat Apr 04 07:07:20 2020 +0000

description:
NFSv2 is limited to use only 32bit in metadata. Prevent that larger
metadata values are simply truncated.

-> clamp filesystem block counts to signed 32bit.
-> clamp file sizes to signed 32bit (*)

Some NFSv2 clients also have problems to handle buffer sizes larger
than (signed) 16bit.
-> clamp buffer sizes to signed 16bit for better compatibility.

(*) This can lead to erroneous behaviour for files larger than 2GB
that NFSv2 cannot handle but it is still better than before.
An alternative would be to (partially) reject operations on files
larger than 2GB, but which causes other problems.

diffstat:

 sys/nfs/nfs_serv.c  |  12 ++++++------
 sys/nfs/nfs_subs.c  |   8 ++++----
 sys/nfs/nfsm_subs.h |  10 +++++++++-
 3 files changed, 19 insertions(+), 11 deletions(-)

diffs (86 lines):

diff -r ae1b2ef48a61 -r 7b9a6bc2000d sys/nfs/nfs_serv.c
--- a/sys/nfs/nfs_serv.c        Sat Apr 04 07:03:57 2020 +0000
+++ b/sys/nfs/nfs_serv.c        Sat Apr 04 07:07:20 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nfs_serv.c,v 1.179 2020/01/17 20:08:09 ad Exp $        */
+/*     $NetBSD: nfs_serv.c,v 1.180 2020/04/04 07:07:20 mlelstv Exp $   */
 
 /*
  * Copyright (c) 1989, 1993
@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_serv.c,v 1.179 2020/01/17 20:08:09 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_serv.c,v 1.180 2020/04/04 07:07:20 mlelstv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -3394,10 +3394,10 @@
                sfp->sf_invarsec = 0;
        } else {
                sfp->sf_tsize = txdr_unsigned(NFS_MAXDGRAMDATA);
-               sfp->sf_bsize = txdr_unsigned(sf->f_frsize);
-               sfp->sf_blocks = txdr_unsigned(sf->f_blocks);
-               sfp->sf_bfree = txdr_unsigned(sf->f_bfree);
-               sfp->sf_bavail = txdr_unsigned(sf->f_bavail);
+               sfp->sf_bsize = txdr_unsigned(NFS_V2CLAMP16(sf->f_frsize));
+               sfp->sf_blocks = txdr_unsigned(NFS_V2CLAMP32(sf->f_blocks));
+               sfp->sf_bfree = txdr_unsigned(NFS_V2CLAMP32(sf->f_bfree));
+               sfp->sf_bavail = txdr_unsigned(NFS_V2CLAMP32(sf->f_bavail));
        }
 nfsmout:
        if (sf)
diff -r ae1b2ef48a61 -r 7b9a6bc2000d sys/nfs/nfs_subs.c
--- a/sys/nfs/nfs_subs.c        Sat Apr 04 07:03:57 2020 +0000
+++ b/sys/nfs/nfs_subs.c        Sat Apr 04 07:07:20 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nfs_subs.c,v 1.238 2020/03/08 22:12:42 mgorny Exp $    */
+/*     $NetBSD: nfs_subs.c,v 1.239 2020/04/04 07:07:20 mlelstv Exp $   */
 
 /*
  * Copyright (c) 1989, 1993
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.238 2020/03/08 22:12:42 mgorny Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.239 2020/04/04 07:07:20 mlelstv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_nfs.h"
@@ -1696,8 +1696,8 @@
        } else {
                fp->fa_type = vtonfsv2_type(vap->va_type);
                fp->fa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode);
-               fp->fa2_size = txdr_unsigned(vap->va_size);
-               fp->fa2_blocksize = txdr_unsigned(vap->va_blocksize);
+               fp->fa2_size = txdr_unsigned(NFS_V2CLAMP32(vap->va_size));
+               fp->fa2_blocksize = txdr_unsigned(NFS_V2CLAMP16(vap->va_blocksize));
                if (vap->va_type == VFIFO)
                        fp->fa2_rdev = 0xffffffff;
                else
diff -r ae1b2ef48a61 -r 7b9a6bc2000d sys/nfs/nfsm_subs.h
--- a/sys/nfs/nfsm_subs.h       Sat Apr 04 07:03:57 2020 +0000
+++ b/sys/nfs/nfsm_subs.h       Sat Apr 04 07:07:20 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nfsm_subs.h,v 1.53 2013/09/14 22:29:08 martin Exp $    */
+/*     $NetBSD: nfsm_subs.h,v 1.54 2020/04/04 07:07:20 mlelstv Exp $   */
 
 /*
  * Copyright (c) 1989, 1993
@@ -55,6 +55,14 @@
                                (((m)->m_flags & M_PKTHDR) ? MHLEN : MLEN))
 
 /*
+ * NFSv2 can only handle signed 32bit quantities and some clients
+ * get confused by larger than 16bit block sizes. Limit values
+ * for better compatibility.
+ */
+#define NFS_V2CLAMP32(x) ((x) > INT32_MAX ? INT32_MAX : (int32_t)(x))
+#define NFS_V2CLAMP16(x) ((x) > INT16_MAX ? INT16_MAX : (int32_t)(x))
+
+/*
  * Now for the macros that do the simple stuff and call the functions
  * for the hard stuff.
  * These macros use several vars. declared in nfsm_reqhead and these



Home | Main Index | Thread Index | Old Index