[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