diff options
Diffstat (limited to 'package/samba/patches/250-writex.patch')
-rw-r--r-- | package/samba/patches/250-writex.patch | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/package/samba/patches/250-writex.patch b/package/samba/patches/250-writex.patch new file mode 100644 index 0000000000..ed0495e92b --- /dev/null +++ b/package/samba/patches/250-writex.patch @@ -0,0 +1,152 @@ +diff -ruN samba-2.0.10.orig/source/include/smb.h samba-2.0.10/source/include/smb.h +--- samba-2.0.10.orig/source/include/smb.h 2006-03-06 22:25:53.000000000 +0100 ++++ samba-2.0.10/source/include/smb.h 2006-03-06 22:27:31.000000000 +0100 +@@ -24,8 +24,14 @@ + #ifndef _SMB_H + #define _SMB_H + ++#if defined(LARGE_SMB_OFF_T) ++#define BUFFER_SIZE (128*1024) ++#else /* no large readwrite possible */ + #define BUFFER_SIZE (0xFFFF) ++#endif ++ + #define SAFETY_MARGIN 1024 ++#define LARGE_WRITEX_HDR_SIZE 65 + + #define NMB_PORT 137 + #define DGRAM_PORT 138 +diff -ruN samba-2.0.10.orig/source/lib/util_sock.c samba-2.0.10/source/lib/util_sock.c +--- samba-2.0.10.orig/source/lib/util_sock.c 2000-03-16 23:59:18.000000000 +0100 ++++ samba-2.0.10/source/lib/util_sock.c 2006-03-06 22:27:31.000000000 +0100 +@@ -649,19 +649,21 @@ + memset(buffer,'\0',smb_size + 100); + + len = read_smb_length_return_keepalive(fd,buffer,timeout); +- if (len < 0) +- { ++ if (len < 0) { + DEBUG(10,("receive_smb: length < 0!\n")); + return(False); + } + +- if (len > BUFFER_SIZE) { ++ /* ++ * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes ++ * of header. Don't print the error if this fits.... JRA. ++ */ ++ ++ if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) { + DEBUG(0,("Invalid packet length! (%d bytes).\n",len)); + if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) +- { + exit(1); + } +- } + + if(len > 0) { + ret = read_socket_data(fd,buffer+4,len); +diff -ruN samba-2.0.10.orig/source/smbd/oplock.c samba-2.0.10/source/smbd/oplock.c +--- samba-2.0.10.orig/source/smbd/oplock.c 2000-04-25 04:32:14.000000000 +0200 ++++ samba-2.0.10/source/smbd/oplock.c 2006-03-06 22:27:31.000000000 +0100 +@@ -887,13 +887,13 @@ + messages crossing on the wire. + */ + +- if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL) ++ if((inbuf = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN))==NULL) + { + DEBUG(0,("oplock_break: malloc fail for input buffer.\n")); + return False; + } + +- if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL) ++ if((outbuf = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN))==NULL) + { + DEBUG(0,("oplock_break: malloc fail for output buffer.\n")); + free(inbuf); +diff -ruN samba-2.0.10.orig/source/smbd/process.c samba-2.0.10/source/smbd/process.c +--- samba-2.0.10.orig/source/smbd/process.c 2006-03-06 22:25:28.000000000 +0100 ++++ samba-2.0.10/source/smbd/process.c 2006-03-06 22:27:31.000000000 +0100 +@@ -995,8 +995,8 @@ + time_t last_timeout_processing_time = time(NULL); + unsigned int num_smbs = 0; + +- InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); +- OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); ++ InBuffer = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN); ++ OutBuffer = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN); + if ((InBuffer == NULL) || (OutBuffer == NULL)) + return; + +@@ -1027,7 +1027,7 @@ + /* free up temporary memory */ + lp_talloc_free(); + +- while(!receive_message_or_smb(InBuffer,BUFFER_SIZE,select_timeout,&got_smb)) ++ while(!receive_message_or_smb(InBuffer,BUFFER_SIZE+LARGE_WRITEX_HDR_SIZE,select_timeout,&got_smb)) + { + if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time)) + return; +diff -ruN samba-2.0.10.orig/source/smbd/reply.c samba-2.0.10/source/smbd/reply.c +--- samba-2.0.10.orig/source/smbd/reply.c 2006-03-06 22:25:53.000000000 +0100 ++++ samba-2.0.10/source/smbd/reply.c 2006-03-06 22:27:31.000000000 +0100 +@@ -2551,17 +2551,28 @@ + size_t numtowrite = SVAL(inbuf,smb_vwv10); + BOOL write_through = BITSETW(inbuf+smb_vwv7,0); + ssize_t nwritten = -1; +- int smb_doff = SVAL(inbuf,smb_vwv11); ++ unsigned int smb_doff = SVAL(inbuf,smb_vwv11); ++ unsigned int smblen = smb_len(inbuf); + char *data; ++ BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF)); + + /* If it's an IPC, pass off the pipe handler. */ +- if (IS_IPC(conn)) ++ if (IS_IPC(conn)) { + return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize); ++ } + + CHECK_FSP(fsp,conn); + CHECK_WRITE(fsp); + CHECK_ERROR(fsp); + ++ /* Deal with possible LARGE_WRITEX */ ++ if (large_writeX) ++ numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16); ++ ++ if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) { ++ return(ERROR(ERRDOS,ERRbadmem)); ++ } ++ + data = smb_base(inbuf) + smb_doff; + + if(CVAL(inbuf,smb_wct) == 14) { +@@ -2586,8 +2597,9 @@ + #endif /* LARGE_SMB_OFF_T */ + } + +- if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK)) ++ if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { + return(ERROR(ERRDOS,ERRlock)); ++ } + + /* X/Open SMB protocol says that, unlike SMBwrite + if the length is zero then NO truncation is +@@ -2598,12 +2610,15 @@ + else + nwritten = write_file(fsp,data,startpos,numtowrite); + +- if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) ++ if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { + return(UNIXERROR(ERRDOS,ERRnoaccess)); ++ } + + set_message(outbuf,6,0,True); + + SSVAL(outbuf,smb_vwv2,nwritten); ++ if (large_writeX) ++ SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1); + + if (nwritten < (ssize_t)numtowrite) { + CVAL(outbuf,smb_rcls) = ERRHRD; |