Package: trickle
Version: 1.07-10
Severity: normal
Tags: upstream patch

Dear Maintainer,

As reported here: https://bugs.archlinux.org/task/35872

trickle segfaults repeatedly on some applications (eg. bitcoin-qt). The
explanation and fix patch are available in the Arch bug report.



-- System Information:
Debian Release: jessie/sid
  APT prefers testing-updates
  APT policy: (500, 'testing-updates'), (500, 'testing')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.14-1-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_GB.utf8, LC_CTYPE=en_GB.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages trickle depends on:
ii  libbsd0         0.6.0-2
ii  libc6           2.19-3
ii  libevent-2.0-5  2.0.21-stable-1

trickle recommends no packages.

trickle suggests no packages.

-- no debconf information
--- trickle-overload.c.orig	2013-06-21 00:23:01.053833665 -0400
+++ trickle-overload.c	2013-06-21 01:19:03.574792790 -0400
@@ -393,18 +393,14 @@ select_delay(struct delayhead *dhead, st
 }
 
 static struct delay *
-select_shift(struct delayhead *dhead, struct timeval *inittv,
+select_shift(struct delayhead *dhead, struct timeval *difftv,
     struct timeval **delaytv)
 {
-	struct timeval curtv, difftv;
 	struct delay *d;
 	struct sockdesc *sd;
 
-	gettimeofday(&curtv, NULL);
-	timersub(&curtv, inittv, &difftv);
-
 	TAILQ_FOREACH(d, dhead, next) {
-		if (timercmp(&d->delaytv, &difftv, >))
+		if (timercmp(&d->delaytv, difftv, >))
 			break;
 		sd = d->sd;
 
@@ -413,7 +409,7 @@ select_shift(struct delayhead *dhead, st
 	}
 
 	if (d != NULL)
-		timersub(&d->delaytv, &difftv, *delaytv);
+		timersub(&d->delaytv, difftv, *delaytv);
 	else 
 		*delaytv = NULL;
 
@@ -431,8 +427,8 @@ _select(int nfds, fd_set *rfds, fd_set *
 {
 	struct sockdesc *sd;
 	fd_set *fdsets[] = { wfds, rfds }, *fds;
-	struct timeval *delaytv, *selecttv = NULL, *timeout = NULL, _timeout,
-	    inittv, curtv, difftv;
+	struct timeval *delaytv, _delaytv, *selecttv = NULL, *timeout = NULL,
+	    _timeout, inittv, curtv, difftv;
 	short which;
 	struct delayhead dhead;
 	struct delay *d, *_d;
@@ -462,15 +458,18 @@ _select(int nfds, fd_set *rfds, fd_set *
 			    FD_ISSET(sd->sock, fds) &&
 			    select_delay(&dhead, sd, which)) {
 				FD_CLR(sd->sock, fds);
-				nfds--;
 			}
 
 	gettimeofday(&inittv, NULL);
 	curtv = inittv;
 	d = TAILQ_FIRST(&dhead);
-	delaytv = d != NULL ? &d->delaytv : NULL;
+	if (d != NULL) {
+		_delaytv = d->delaytv;
+		delaytv = &_delaytv;
+	} else
+		delaytv = NULL;
+	timersub(&curtv, &inittv, &difftv);
  again:
-	timersub(&inittv, &curtv, &difftv);
 	selecttv = NULL;
 
 	if (delaytv != NULL)
@@ -498,15 +497,15 @@ _select(int nfds, fd_set *rfds, fd_set *
 #endif /* DEBUG */
 
 	if (ret == 0 && delaytv != NULL && selecttv == delaytv) {
-		_d = select_shift(&dhead, &inittv, &delaytv);
+		gettimeofday(&curtv, NULL);
+		timersub(&curtv, &inittv, &difftv);
+		_d = select_shift(&dhead, &difftv, &delaytv);
 		while ((d = TAILQ_FIRST(&dhead)) != _d) {
 			FD_SET(d->sd->sock, fdsets[d->which]);
-			nfds++;
 			TAILQ_REMOVE(&dhead, d, next);
 			free(d);
 		}
 
-		gettimeofday(&curtv, NULL);
 		goto again;
 	}
 

Reply via email to