kern/180979: [netsmb][patch]: Fix large files handling

Maxim Samsonov xors at mailup.net
Wed Jul 31 19:00:00 UTC 2013


>Number:         180979
>Category:       kern
>Synopsis:       [netsmb][patch]: Fix large files handling
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jul 31 19:00:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator:     Maxim Samsonov
>Release:        9.2-BETA2
>Organization:
>Environment:
FreeBSD fern.localbroom.net 9.2-BETA2 FreeBSD 9.2-BETA2 #0: Wed Jul 31 13:50:29 MSK 2013     xors at fern.localbroom.net:/usr/obj/usr/src/sys/FERN  amd64
>Description:
NETSMB should honour SMB_CAP_LARGE_FILES capability as well as SMB_CAP_LARGE_READX and SMB_CAP_LARGE_WRITEX capabilities in order to read/write large files (over 4G) correctly.
So 64-bit file offsets are supported if SMB_CAP_LARGE_FILES capability is detected.

This fix was inspired from the following NetBSD patch:
http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/netsmb/smb_smb.c?rev=1.31&content-type=text/x-cvsweb-markup&only_with_tag=MAIN
..
Fix detection of SMB capabilities according to the CIFS spec:
1.) SMB_CAP_LARGE_FILES advertises support for 64-bit file offsets.
2.) SMB_CAP_LARGE_READX and SMB_CAP_LARGE_WRITEX advertise support for
    large reads and writes (larger than 64KB).
The code previously only used SMB_CAP_LARGE_READX and SMB_CAP_LARGE_WRITEX
which is not correct and doesn't work for the Apple Time Capsule which
only supports SMB_CAP_LARGE_FILES.
..

>How-To-Repeat:

>Fix:


Patch attached with submission follows:

diff --git a/sys/netsmb/smb_smb.c b/sys/netsmb/smb_smb.c
--- a/sys/netsmb/smb_smb.c
+++ b/sys/netsmb/smb_smb.c
@@ -771,7 +771,12 @@
 	u_int8_t wc;
 	int error, rlen, blksz;
 
-	if (SSTOVC(ssp)->vc_sopt.sv_caps & SMB_CAP_LARGE_READX)
+	if (uio->uio_offset > UINT32_MAX
+		&& !(SSTOVC(ssp)->vc_sopt.sv_caps & SMB_CAP_LARGE_FILES)) {
+		return (EFBIG);
+	}
+
+	if (SSTOVC(ssp)->vc_sopt.sv_caps & (SMB_CAP_LARGE_READX | SMB_CAP_LARGE_FILES))
 		return (smb_smb_readx(ssp, fid, len, rresid, uio, scred));
 
 	error = smb_rq_alloc(SSTOCP(ssp), SMB_COM_READ, scred, &rqp);
@@ -850,7 +855,12 @@
 	u_int8_t wc;
 	int error, blksz;
 
-	if (*len && SSTOVC(ssp)->vc_sopt.sv_caps & SMB_CAP_LARGE_WRITEX)
+	if (uio->uio_offset > UINT32_MAX
+		&& !(SSTOVC(ssp)->vc_sopt.sv_caps & SMB_CAP_LARGE_FILES)) {
+		return (EFBIG);
+	}
+
+	if (*len && SSTOVC(ssp)->vc_sopt.sv_caps & (SMB_CAP_LARGE_WRITEX | SMB_CAP_LARGE_FILES))
 		return (smb_smb_writex(ssp, fid, len, rresid, uio, scred));
  
 	blksz = SSTOVC(ssp)->vc_txmax - SMB_HDRLEN - 16;


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list