[Pkg-samba-maint] r2330 - in trunk/samba/debian: . patches
bubulle at alioth.debian.org
bubulle at alioth.debian.org
Sun Jan 11 11:19:38 UTC 2009
tags 500129 pending
tags 509101 pending
tags 510450 pending
thanks
Author: bubulle
Date: 2009-01-11 11:19:28 +0000 (Sun, 11 Jan 2009)
New Revision: 2330
Added:
trunk/samba/debian/patches/bug_500129_upstream_5953.patch
trunk/samba/debian/patches/bug_509101_upstream_5904.patch
Modified:
trunk/samba/debian/changelog
trunk/samba/debian/patches/series
Log:
Patches for bugs #509101 and #500129 are reported to be OK. Commit them
before uploading
Modified: trunk/samba/debian/changelog
===================================================================
--- trunk/samba/debian/changelog 2009-01-07 18:38:09 UTC (rev 2329)
+++ trunk/samba/debian/changelog 2009-01-11 11:19:28 UTC (rev 2330)
@@ -1,3 +1,12 @@
+samba (2:3.2.5-4) unstable; urgency=low
+
+ * Fix segfault whan accessign some NAS devices running old versions of Samba
+ Closes: #500129
+ * Fix process crush when using gethostbyname_r in several threads
+ Closes: #509101, #510450
+
+ -- Christian Perrier <bubulle at debian.org> Thu, 08 Jan 2009 05:59:17 +0100
+
samba (2:3.2.5-3) unstable; urgency=high
* Security update
Added: trunk/samba/debian/patches/bug_500129_upstream_5953.patch
===================================================================
--- trunk/samba/debian/patches/bug_500129_upstream_5953.patch (rev 0)
+++ trunk/samba/debian/patches/bug_500129_upstream_5953.patch 2009-01-11 11:19:28 UTC (rev 2330)
@@ -0,0 +1,259 @@
+Goal: Fix segfault whan accessign some NAS devices running old versions of Samba
+
+Fixes: #500129
+
+Status wrt upstream: Fixed in 3.2.6
+
+Author: Kai Blin <kai at samba.org> and Volker Lendecke <vl at samba.org>
+
+Note: This bug was a regression in Samba 3.2 and may affect etch->lenny
+ upgrades, introducing regressions. See also Launchpad bug #264943
+ (Ubuntu Hardy->Intrepid regression)
+
+Index: samba-3.2.5/source/lib/system.c
+===================================================================
+--- samba-3.2.5.orig/source/lib/system.c
++++ samba-3.2.5/source/lib/system.c
+@@ -142,6 +142,20 @@
+ }
+
+ /*******************************************************************
++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.
+ ********************************************************************/
+
+Index: samba-3.2.5/source/lib/util_sock.c
+===================================================================
+--- samba-3.2.5.orig/source/lib/util_sock.c
++++ samba-3.2.5/source/lib/util_sock.c
+@@ -1037,40 +1037,109 @@
+ }
+
+ /****************************************************************************
+- 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;
++
++ to_send = 0;
++ for (i=0; i<iovcnt; i++) {
++ to_send += orig_iov[i].iov_len;
++ }
++
++ thistime = sys_writev(fd, orig_iov, iovcnt);
++ if ((thistime <= 0) || (thistime == to_send)) {
++ return thistime;
++ }
++ sent = thistime;
+
+- while (total < N) {
+- ret = sys_write(fd,buffer + total,N - total);
++ /*
++ * 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.
++ */
+
+- 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) ));
++ 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;
++}
+
+- total += ret;
++/****************************************************************************
++ 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;
++ }
++
++ 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;
+ }
+
+ /****************************************************************************
+Index: samba-3.2.5/source/libsmb/clientgen.c
+===================================================================
+--- samba-3.2.5.orig/source/libsmb/clientgen.c
++++ samba-3.2.5/source/libsmb/clientgen.c
+@@ -315,7 +315,7 @@
+ /* 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 at ninja.nl) */
+ if (cli->fd == -1) {
+@@ -327,33 +327,19 @@
+ 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. */
+Index: samba-3.2.5/source/libsmb/clilist.c
+===================================================================
+--- samba-3.2.5.orig/source/libsmb/clilist.c
++++ samba-3.2.5/source/libsmb/clilist.c
+@@ -79,16 +79,17 @@
+ 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;
+ }
+
Added: trunk/samba/debian/patches/bug_509101_upstream_5904.patch
===================================================================
--- trunk/samba/debian/patches/bug_509101_upstream_5904.patch (rev 0)
+++ trunk/samba/debian/patches/bug_509101_upstream_5904.patch 2009-01-11 11:19:28 UTC (rev 2330)
@@ -0,0 +1,150 @@
+Goal: Fix process crush when using gethostbyname_r in several threads
+
+Fixes: #509101, #510450
+
+Status wrt upstream: Fixed in 3.2.6
+
+Author: Jeremy Allison <jra at samba.org>
+
+Note: This bug induces web browser crashes (see #510450) and is a regression
+ for many desktop users in etch->lenny upgrades
+
+Index: samba-3.2.5/source/nsswitch/wins.c
+===================================================================
+--- samba-3.2.5.orig/source/nsswitch/wins.c
++++ samba-3.2.5/source/nsswitch/wins.c
+@@ -25,6 +25,14 @@
+ #include <ns_daemon.h>
+ #endif
+
++#if HAVE_PTHREAD_H
++#include <pthread.h>
++#endif
++
++#if HAVE_PTHREAD
++static pthread_mutex_t wins_nss_mutex = PTHREAD_MUTEX_INITIALIZER;
++#endif
++
+ #ifndef INADDRSZ
+ #define INADDRSZ 4
+ #endif
+@@ -321,11 +329,16 @@
+ _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he,
+ char *buffer, size_t buflen, int *h_errnop)
+ {
++ NSS_STATUS nss_status = NSS_STATUS_SUCCESS;
+ struct in_addr *ip_list;
+ int i, count;
+ fstring name;
+ size_t namelen;
+
++#if HAVE_PTHREAD
++ pthread_mutex_lock(&wins_nss_mutex);
++#endif
++
+ memset(he, '\0', sizeof(*he));
+ fstrcpy(name, hostname);
+
+@@ -333,8 +346,10 @@
+
+ ip_list = lookup_byname_backend(name, &count);
+
+- if (!ip_list)
+- return NSS_STATUS_NOTFOUND;
++ if (!ip_list) {
++ nss_status = NSS_STATUS_NOTFOUND;
++ goto out;
++ }
+
+ /* Copy h_name */
+
+@@ -342,7 +357,8 @@
+
+ if ((he->h_name = get_static(&buffer, &buflen, namelen)) == NULL) {
+ free(ip_list);
+- return NSS_STATUS_TRYAGAIN;
++ nss_status = NSS_STATUS_TRYAGAIN;
++ goto out;
+ }
+
+ memcpy(he->h_name, name, namelen);
+@@ -354,20 +370,23 @@
+
+ if (get_static(&buffer, &buflen, i) == NULL) {
+ free(ip_list);
+- return NSS_STATUS_TRYAGAIN;
++ nss_status = NSS_STATUS_TRYAGAIN;
++ goto out;
+ }
+
+ if ((he->h_addr_list = (char **)get_static(
+ &buffer, &buflen, (count + 1) * sizeof(char *))) == NULL) {
+ free(ip_list);
+- return NSS_STATUS_TRYAGAIN;
++ nss_status = NSS_STATUS_TRYAGAIN;
++ goto out;
+ }
+
+ for (i = 0; i < count; i++) {
+ if ((he->h_addr_list[i] = get_static(&buffer, &buflen,
+ INADDRSZ)) == NULL) {
+ free(ip_list);
+- return NSS_STATUS_TRYAGAIN;
++ nss_status = NSS_STATUS_TRYAGAIN;
++ goto out;
+ }
+ memcpy(he->h_addr_list[i], &ip_list[i], INADDRSZ);
+ }
+@@ -386,16 +405,27 @@
+ if ((i = (unsigned long)(buffer) % sizeof(char*)) != 0)
+ i = sizeof(char*) - i;
+
+- if (get_static(&buffer, &buflen, i) == NULL)
+- return NSS_STATUS_TRYAGAIN;
++ if (get_static(&buffer, &buflen, i) == NULL) {
++ nss_status = NSS_STATUS_TRYAGAIN;
++ goto out;
++ }
+
+ if ((he->h_aliases = (char **)get_static(
+- &buffer, &buflen, sizeof(char *))) == NULL)
+- return NSS_STATUS_TRYAGAIN;
++ &buffer, &buflen, sizeof(char *))) == NULL) {
++ nss_status = NSS_STATUS_TRYAGAIN;
++ goto out;
++ }
+
+ he->h_aliases[0] = NULL;
+
+- return NSS_STATUS_SUCCESS;
++ nss_status = NSS_STATUS_SUCCESS;
++
++ out:
++
++#if HAVE_PTHREAD
++ pthread_mutex_unlock(&wins_nss_mutex);
++#endif
++ return nss_status;
+ }
+
+
+@@ -403,12 +433,15 @@
+ _nss_wins_gethostbyname2_r(const char *name, int af, struct hostent *he,
+ char *buffer, size_t buflen, int *h_errnop)
+ {
++ NSS_STATUS nss_status;
++
+ if(af!=AF_INET) {
+ *h_errnop = NO_DATA;
+- return NSS_STATUS_UNAVAIL;
++ nss_status = NSS_STATUS_UNAVAIL;
++ } else {
++ nss_status = _nss_wins_gethostbyname_r(
++ name, he, buffer, buflen, h_errnop);
+ }
+-
+- return _nss_wins_gethostbyname_r(
+- name, he, buffer, buflen, h_errnop);
++ return nss_status;
+ }
+ #endif
Modified: trunk/samba/debian/patches/series
===================================================================
--- trunk/samba/debian/patches/series 2009-01-07 18:38:09 UTC (rev 2329)
+++ trunk/samba/debian/patches/series 2009-01-11 11:19:28 UTC (rev 2330)
@@ -21,3 +21,5 @@
documentation-links.patch
documentation-links-debian.patch
smbd-prevent-access-to-root-filesystem-when-connect.patch
+bug_500129_upstream_5953.patch
+bug_509101_upstream_5904.patch
More information about the Pkg-samba-maint
mailing list