The Samba-Bugzilla – Attachment 3835 Details for
Bug 5953
smbclient crashes: cli_list_new segmentation fault
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Complete patch on top of the v3-2-stable branch
bug_5953_complete.patch (text/plain), 7.06 KB, created by
Kai Blin
on 2008-12-29 08:11:11 UTC
(
hide
)
Description:
Complete patch on top of the v3-2-stable branch
Filename:
MIME Type:
Creator:
Kai Blin
Created:
2008-12-29 08:11:11 UTC
Size:
7.06 KB
patch
obsolete
>diff --git a/source/lib/system.c b/source/lib/system.c >index eabb6d6..5b06d3c 100644 >--- a/source/lib/system.c >+++ b/source/lib/system.c >@@ -142,6 +142,20 @@ ssize_t sys_write(int fd, const void *buf, size_t count) > } > > /******************************************************************* >+A writev wrapper that will deal with EINTR. >+********************************************************************/ >+ >+ssize_t sys_writev(int fd, const struct iovec *iov, int iovcnt) >+{ >+ ssize_t ret; >+ >+ do { >+ ret = writev(fd, iov, iovcnt); >+ } while (ret == -1 && errno == EINTR); >+ return ret; >+} >+ >+/******************************************************************* > A pread wrapper that will deal with EINTR and 64-bit file offsets. > ********************************************************************/ > >diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c >index e64b003..9c37e0c 100644 >--- a/source/lib/util_sock.c >+++ b/source/lib/util_sock.c >@@ -1037,40 +1037,109 @@ NTSTATUS read_data(int fd, char *buffer, size_t N) > } > > /**************************************************************************** >- Write data to a fd. >+ Write all data from an iov array > ****************************************************************************/ > >-ssize_t write_data(int fd, const char *buffer, size_t N) >+ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt) > { >- size_t total=0; >- ssize_t ret; >- char addr[INET6_ADDRSTRLEN]; >+ int i; >+ size_t to_send; >+ ssize_t thistime; >+ size_t sent; >+ struct iovec *iov_copy, *iov; > >- while (total < N) { >- ret = sys_write(fd,buffer + total,N - total); >+ to_send = 0; >+ for (i=0; i<iovcnt; i++) { >+ to_send += orig_iov[i].iov_len; >+ } > >- if (ret == -1) { >- if (fd == get_client_fd()) { >- /* Try and give an error message saying >- * what client failed. */ >- DEBUG(0,("write_data: write failure in " >- "writing to client %s. Error %s\n", >- get_peer_addr(fd,addr,sizeof(addr)), >- strerror(errno) )); >- } else { >- DEBUG(0,("write_data: write failure. " >- "Error = %s\n", strerror(errno) )); >+ thistime = sys_writev(fd, orig_iov, iovcnt); >+ if ((thistime <= 0) || (thistime == to_send)) { >+ return thistime; >+ } >+ sent = thistime; >+ >+ /* >+ * We could not send everything in one call. Make a copy of iov that >+ * we can mess with. We keep a copy of the array start in iov_copy for >+ * the TALLOC_FREE, because we're going to modify iov later on, >+ * discarding elements. >+ */ >+ >+ iov_copy = (struct iovec *)TALLOC_MEMDUP( >+ talloc_tos(), orig_iov, sizeof(struct iovec) * iovcnt); >+ >+ if (iov_copy == NULL) { >+ errno = ENOMEM; >+ return -1; >+ } >+ iov = iov_copy; >+ >+ while (sent < to_send) { >+ /* >+ * We have to discard "thistime" bytes from the beginning >+ * iov array, "thistime" contains the number of bytes sent >+ * via writev last. >+ */ >+ while (thistime > 0) { >+ if (thistime < iov[0].iov_len) { >+ char *new_base = >+ (char *)iov[0].iov_base + thistime; >+ iov[0].iov_base = new_base; >+ iov[0].iov_len -= thistime; >+ break; > } >- return -1; >+ thistime -= iov[0].iov_len; >+ iov += 1; >+ iovcnt -= 1; > } > >- if (ret == 0) { >- return total; >+ thistime = sys_writev(fd, iov, iovcnt); >+ if (thistime <= 0) { >+ break; > } >+ sent += thistime; >+ } >+ >+ TALLOC_FREE(iov_copy); >+ return sent; >+} >+ >+/**************************************************************************** >+ Write data to a fd. >+****************************************************************************/ >+ >+/**************************************************************************** >+ Write data to a fd. >+****************************************************************************/ >+ >+ssize_t write_data(int fd, const char *buffer, size_t N) >+{ >+ ssize_t ret; >+ struct iovec iov; >+ >+ iov.iov_base = CONST_DISCARD(char *, buffer); >+ iov.iov_len = N; >+ >+ ret = write_data_iov(fd, &iov, 1); >+ if (ret >= 0) { >+ return ret; >+ } > >- total += ret; >+ if (fd == get_client_fd()) { >+ char addr[INET6_ADDRSTRLEN]; >+ /* >+ * Try and give an error message saying what client failed. >+ */ >+ DEBUG(0, ("write_data: write failure in writing to client %s. " >+ "Error %s\n", get_peer_addr(fd,addr,sizeof(addr)), >+ strerror(errno))); >+ } else { >+ DEBUG(0,("write_data: write failure. Error = %s\n", >+ strerror(errno) )); > } >- return (ssize_t)total; >+ >+ return -1; > } > > /**************************************************************************** >diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c >index d6d26e4..aeb1c28 100644 >--- a/source/libsmb/clientgen.c >+++ b/source/libsmb/clientgen.c >@@ -315,7 +315,7 @@ bool cli_send_smb_direct_writeX(struct cli_state *cli, > /* First length to send is the offset to the data. */ > size_t len = SVAL(cli->outbuf,smb_vwv11) + 4; > size_t nwritten=0; >- ssize_t ret; >+ struct iovec iov[2]; > > /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ > if (cli->fd == -1) { >@@ -327,33 +327,19 @@ bool cli_send_smb_direct_writeX(struct cli_state *cli, > return false; > } > >- while (nwritten < len) { >- ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); >- if (ret <= 0) { >- close(cli->fd); >- cli->fd = -1; >- cli->smb_rw_error = SMB_WRITE_ERROR; >- DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", >- (int)len,(int)ret, strerror(errno) )); >- return false; >- } >- nwritten += ret; >- } >+ iov[0].iov_base = cli->outbuf; >+ iov[0].iov_len = len; >+ iov[1].iov_base = CONST_DISCARD(char *, p); >+ iov[1].iov_len = extradata; > >- /* Now write the extra data. */ >- nwritten=0; >- while (nwritten < extradata) { >- ret = write_socket(cli->fd,p+nwritten,extradata - nwritten); >- if (ret <= 0) { >- close(cli->fd); >- cli->fd = -1; >- cli->smb_rw_error = SMB_WRITE_ERROR; >- DEBUG(0,("Error writing %d extradata " >- "bytes to client. %d (%s)\n", >- (int)extradata,(int)ret, strerror(errno) )); >- return false; >- } >- nwritten += ret; >+ nwritten = write_data_iov(cli->fd, iov, 2); >+ if (nwritten < (len + extradata)) { >+ close(cli->fd); >+ cli->fd = -1; >+ cli->smb_rw_error = SMB_WRITE_ERROR; >+ DEBUG(0,("Error writing %d bytes to client. (%s)\n", >+ (int)(len+extradata), strerror(errno))); >+ return false; > } > > /* Increment the mid so we can tell between responses. */ >diff --git a/source/libsmb/clilist.c b/source/libsmb/clilist.c >index cebafc6..1431b80 100644 >--- a/source/libsmb/clilist.c >+++ b/source/libsmb/clilist.c >@@ -79,16 +79,17 @@ static size_t interpret_long_filename(TALLOC_CTX *ctx, > p += 27; > p += clistr_align_in(cli, p, 0); > >- /* We can safely use +1 here (which is required by OS/2) >- * instead of +2 as the STR_TERMINATE flag below is >+ /* We can safely use len here (which is required by OS/2) >+ * and the NAS-BASIC server instead of +2 or +1 as the >+ * STR_TERMINATE flag below is > * actually used as the length calculation. >- * The len+2 is merely an upper bound. >+ * The len is merely an upper bound. > * Due to the explicit 2 byte null termination > * in cli_receive_trans/cli_receive_nt_trans > * we know this is safe. JRA + kukks > */ > >- if (p + len + 1 > pdata_end) { >+ if (p + len > pdata_end) { > return pdata_end - base; > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 5953
:
3787
|
3789
|
3790
|
3805
|
3809
|
3814
|
3816
|
3818
|
3820
|
3821
|
3822
|
3823
|
3824
| 3835