Accepting request 142224 from home:elvigia:branches:devel:libraries:c_c++

- Curl 7.28.1
* FTP: prevent the multi interface from blocking Obsoletes
  curl-ftp-prevent-the-multi-interface-from-blocking.patch
* don't send '#' fragments when using proxy
* OpenSSL: Disable SSL/TLS compression - avoid the "CRIME" attack
* TFTP: handle resend
* memory leak: CURLOPT_RESOLVE with multi interface
* SSL: Several SSL-backend related fixes

OBS-URL: https://build.opensuse.org/request/show/142224
OBS-URL: https://build.opensuse.org/package/show/devel:libraries:c_c++/curl?expand=0&rev=81
This commit is contained in:
Ismail Dönmez 2012-11-21 13:55:02 +00:00 committed by Git OBS Bridge
parent 1edb8f7e94
commit 9ef148d620
8 changed files with 35 additions and 452 deletions

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b986186140e0ef0102e11094873f1e71bca1159d12fe869a8aa2ce649f02b238
size 2037300

View File

@ -1,7 +0,0 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)
iEYEABECAAYFAlATBJgACgkQeOEcayedXJG7qwCgpx6vCgDNTRZ2th1SnQw+V8WD
eIQAn1FrMLQyxZIF/9oDW67e4jnctUV4
=31wG
-----END PGP SIGNATURE-----

3
curl-7.28.1.tar.lzma Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dda2516ffdf991ec0a7bfae319527d40aaefb8ec78c60c85f6c0381f8876708d
size 2059467

7
curl-7.28.1.tar.lzma.asc Normal file
View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)
iEYEABECAAYFAlCrLdwACgkQeOEcayedXJEWfACgwzpFlCeVscTbj9lVpcDstIeH
Jy4AnjMtLsxo3wBfcLQg2vS/RqGVvLyq
=NHEU
-----END PGP SIGNATURE-----

View File

@ -1,407 +0,0 @@
From b2954e66e87be7414a4508f8167ca531e653bea8 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sun, 4 Nov 2012 18:22:48 +0100
Subject: [PATCH] FTP: prevent the multi interface from blocking
As pointed out in Bug report #3579064, curl_multi_perform() would
wrongly use a blocking mechanism internally for some commands which
could lead to for example a very long block if the LIST response never
showed.
The solution was to make sure to properly continue to use the multi
interface non-blocking state machine.
The new test 1501 verifies the fix.
Bug: http://curl.haxx.se/bug/view.cgi?id=3579064
Reported by: Guido Berhoerster
Index: curl-7.27.0/lib/ftp.c
===================================================================
--- curl-7.27.0.orig/lib/ftp.c
+++ curl-7.27.0/lib/ftp.c
@@ -650,11 +650,18 @@ static CURLcode ftp_readresp(curl_socket
if(ftpcode)
*ftpcode = code;
- if(421 == code)
+ if(421 == code) {
/* 421 means "Service not available, closing control connection." and FTP
* servers use it to signal that idle session timeout has been exceeded.
- * If we ignored the response, it could end up hanging in some cases. */
+ * If we ignored the response, it could end up hanging in some cases.
+ *
+ * This response code can come at any point so having it treated
+ * generically is a good idea.
+ */
+ infof(data, "We got a 421 - timeout!\n");
+ state(conn, FTP_STOP);
return CURLE_OPERATION_TIMEDOUT;
+ }
return result;
}
@@ -2378,6 +2385,7 @@ static CURLcode ftp_state_stor_resp(stru
if(ftpcode>=400) {
failf(data, "Failed FTP upload: %0d", ftpcode);
+ state(conn, FTP_STOP);
/* oops, we never close the sockets! */
return CURLE_UPLOAD_FAILED;
}
@@ -2395,9 +2403,6 @@ static CURLcode ftp_state_stor_resp(stru
if(!connected) {
struct ftp_conn *ftpc = &conn->proto.ftpc;
infof(data, "Data conn was not available immediately\n");
- /* as there's not necessarily an immediate action on the control
- connection now, we halt the state machine */
- state(conn, FTP_STOP);
ftpc->wait_data_conn = TRUE;
}
@@ -3647,6 +3652,8 @@ static CURLcode ftp_do_more(struct conne
/* the ftp struct is inited in ftp_connect() */
struct FTP *ftp = data->state.proto.ftp;
+ *complete = FALSE;
+
/* if the second connection isn't done yet, wait for it */
if(!conn->bits.tcpconnect[SECONDARYSOCKET]) {
result = Curl_is_connected(conn, SECONDARYSOCKET, &connected);
@@ -3659,6 +3666,18 @@ static CURLcode ftp_do_more(struct conne
return result;
}
+ if((data->state.used_interface == Curl_if_multi) &&
+ ftpc->state) {
+ /* multi interface and already in a state so skip the intial commands.
+ They are only done to kickstart the do_more state */
+ result = ftp_multi_statemach(conn, complete);
+
+ /* if we got an error or if we don't wait for a data connection return
+ immediately */
+ if(result || (ftpc->wait_data_conn != TRUE))
+ return result;
+ }
+
if(ftp->transfer <= FTPTRANSFER_INFO) {
/* a transfer is about to take place, or if not a file name was given
so we'll do a SIZE on it later and then we need the right TYPE first */
@@ -3712,7 +3731,13 @@ static CURLcode ftp_do_more(struct conne
return result;
}
}
- result = ftp_easy_statemach(conn);
+ if(data->state.used_interface == Curl_if_multi) {
+ result = ftp_multi_statemach(conn, complete);
+
+ return result;
+ }
+ else
+ result = ftp_easy_statemach(conn);
}
if((result == CURLE_OK) && (ftp->transfer != FTPTRANSFER_BODY))
@@ -4386,20 +4411,21 @@ CURLcode ftp_parse_url_path(struct conne
static CURLcode ftp_dophase_done(struct connectdata *conn,
bool connected)
{
- CURLcode result = CURLE_OK;
struct FTP *ftp = conn->data->state.proto.ftp;
struct ftp_conn *ftpc = &conn->proto.ftpc;
if(connected) {
bool completed;
- result = ftp_do_more(conn, &completed);
- }
+ CURLcode result = ftp_do_more(conn, &completed);
- if(result && (conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD)) {
- /* Failure detected, close the second socket if it was created already */
- Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
- conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
- return result;
+ if(result) {
+ if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) {
+ /* close the second socket if it was created already */
+ Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
+ conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
+ }
+ return result;
+ }
}
if(ftp->transfer != FTPTRANSFER_BODY)
@@ -4411,7 +4437,7 @@ static CURLcode ftp_dophase_done(struct
ftpc->ctl_valid = TRUE; /* seems good */
- return result;
+ return CURLE_OK;
}
/* called from multi.c while DOing */
Index: curl-7.27.0/lib/pingpong.c
===================================================================
--- curl-7.27.0.orig/lib/pingpong.c
+++ curl-7.27.0/lib/pingpong.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -424,6 +424,9 @@ CURLcode Curl_pp_readresp(curl_socket_t
it may actually contain another end of response already! */
clipamount = gotbytes - i;
restart = TRUE;
+ DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing "
+ "server response left\n",
+ (int)clipamount));
}
else if(keepon) {
Index: curl-7.27.0/tests/data/Makefile.am
===================================================================
--- curl-7.27.0.orig/tests/data/Makefile.am
+++ curl-7.27.0/tests/data/Makefile.am
@@ -93,6 +93,7 @@ test1379 test1380 test1381 test1382 test
test1387 test1388 test1389 test1390 test1391 test1392 test1393 \
test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 \
test1408 test1409 test1410 \
+test1501 \
test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
test2016 test2017 test2018 test2019 test2020 test2021 test2022
Index: curl-7.27.0/tests/data/test1501
===================================================================
--- /dev/null
+++ curl-7.27.0/tests/data/test1501
@@ -0,0 +1,53 @@
+<testcase>
+<info>
+<keywords>
+FTP
+RETR
+multi
+LIST
+</keywords>
+</info>
+
+# Server-side
+<reply>
+<data>
+</data>
+<servercmd>
+DELAY LIST 2
+DELAY TYPE 2
+</servercmd>
+</reply>
+
+# Client-side
+<client>
+<server>
+ftp
+</server>
+<tool>
+lib1501
+</tool>
+ <name>
+FTP with multi interface and slow LIST response
+ </name>
+ <command>
+ftp://%HOSTIP:%FTPPORT/1501/
+</command>
+</client>
+# Verify data after the test has been "shot"
+<verify>
+<errorcode>
+0
+</errorcode>
+<protocol>
+USER anonymous
+PASS ftp@example.com
+PWD
+CWD 1501
+EPSV
+TYPE A
+LIST
+QUIT
+</protocol>
+
+</verify>
+</testcase>
Index: curl-7.27.0/tests/data/test591
===================================================================
--- curl-7.27.0.orig/tests/data/test591
+++ curl-7.27.0/tests/data/test591
@@ -63,8 +63,9 @@ TYPE I
STOR 591
QUIT
</protocol>
+# CURLE_UPLOAD_FAILED = 25
<errorcode>
-10
+25
</errorcode>
<upload>
</upload>
Index: curl-7.27.0/tests/data/test592
===================================================================
--- curl-7.27.0.orig/tests/data/test592
+++ curl-7.27.0/tests/data/test592
@@ -52,6 +52,7 @@ Moooooooooooo for 592
s/^PORT (.*)/PORT/
s/^EPRT \|1\|(.*)/EPRT \|1\|/
</strippart>
+# a 421 response must prevent further commands from being sent
<protocol>
USER anonymous
PASS ftp@example.com
@@ -61,10 +62,10 @@ EPRT |1|
PORT
TYPE I
STOR 592
-QUIT
</protocol>
+# 28 == CURLE_OPERATION_TIMEDOUT
<errorcode>
-10
+28
</errorcode>
<upload>
</upload>
Index: curl-7.27.0/tests/libtest/lib1501.c
===================================================================
--- /dev/null
+++ curl-7.27.0/tests/libtest/lib1501.c
@@ -0,0 +1,126 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "test.h"
+
+#include <fcntl.h>
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+#define TEST_HANG_TIMEOUT 30 * 1000
+
+/* 500 milliseconds allowed. An extreme number but lets be really conservative
+ to allow old and slow machines to run this test too */
+#define MAX_BLOCKED_TIME_US 500000
+
+/* return the number of microseconds between two time stamps */
+static int elapsed(struct timeval *before,
+ struct timeval *after)
+{
+ ssize_t result;
+
+ result = (after->tv_sec - before->tv_sec) * 1000000 +
+ after->tv_usec - before->tv_usec;
+ if (result < 0)
+ result = 0;
+
+ return curlx_sztosi(result);
+}
+
+
+int test(char *URL)
+{
+ CURL *handle = NULL;
+ CURLM *mhandle = NULL;
+ int res = 0;
+ int still_running = 0;
+
+ start_test_timing();
+
+ global_init(CURL_GLOBAL_ALL);
+
+ easy_init(handle);
+
+ easy_setopt(handle, CURLOPT_URL, URL);
+ easy_setopt(handle, CURLOPT_VERBOSE, 1L);
+
+ multi_init(mhandle);
+
+ multi_add_handle(mhandle, handle);
+
+ multi_perform(mhandle, &still_running);
+
+ abort_on_test_timeout();
+
+ while(still_running) {
+ struct timeval timeout;
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ int maxfd = -99;
+ struct timeval before;
+ struct timeval after;
+ int e;
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 100000L; /* 100 ms */
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ multi_fdset(mhandle, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
+
+ select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+ abort_on_test_timeout();
+
+ fprintf(stderr, "ping\n");
+ gettimeofday(&before, 0);
+
+ multi_perform(mhandle, &still_running);
+
+ abort_on_test_timeout();
+
+ gettimeofday(&after, 0);
+ e = elapsed(&before, &after);
+ fprintf(stderr, "pong = %d\n", e);
+
+ if(e > MAX_BLOCKED_TIME_US) {
+ res = 100;
+ break;
+ }
+ }
+
+test_cleanup:
+
+ /* undocumented cleanup sequence - type UA */
+
+ curl_multi_cleanup(mhandle);
+ curl_easy_cleanup(handle);
+ curl_global_cleanup();
+
+ return res;
+}

View File

@ -1,3 +1,15 @@
-------------------------------------------------------------------
Tue Nov 20 23:43:24 UTC 2012 - crrodriguez@opensuse.org
- Curl 7.28.1
* FTP: prevent the multi interface from blocking Obsoletes
curl-ftp-prevent-the-multi-interface-from-blocking.patch
* don't send '#' fragments when using proxy
* OpenSSL: Disable SSL/TLS compression - avoid the "CRIME" attack
* TFTP: handle resend
* memory leak: CURLOPT_RESOLVE with multi interface
* SSL: Several SSL-backend related fixes
-------------------------------------------------------------------
Sun Nov 4 19:57:33 UTC 2012 - gber@opensuse.org

View File

@ -21,7 +21,7 @@
%bcond_without testsuite
Name: curl
Version: 7.27.0
Version: 7.28.1
Release: 0
Summary: A Tool for Transferring Data from URLs
License: BSD-3-Clause and MIT
@ -32,8 +32,6 @@ Source2: http://curl.haxx.se/download/%{name}-%{version}.tar.lzma.asc
Source3: baselibs.conf
Patch: libcurl-ocloexec.patch
Patch1: dont-mess-with-rpmoptflags.diff
# PATCH-FIX-UPSTREAM curl-ftp-prevent-the-multi-interface-from-blocking.patch sf#3579064 gber@opensuse.org -- Prevent the multi interface from blocking when using ftp and the remote end responds very slowly (backported from upstream git)
Patch2: curl-ftp-prevent-the-multi-interface-from-blocking.patch
BuildRequires: libidn-devel
BuildRequires: libtool
BuildRequires: lzma
@ -47,7 +45,6 @@ BuildRequires: openssl-devel
BuildRequires: mozilla-nss-devel
%endif
BuildRequires: krb5-devel
BuildRequires: libcares-devel
BuildRequires: libssh2-devel
BuildRequires: openssh
%if 0%{?_with_stunnel:1}
@ -93,7 +90,6 @@ user interaction or any kind of interactivity.
%setup -q
%patch
%patch1
%patch2 -p1
%build
autoreconf -fi

View File

@ -38,33 +38,15 @@ compile time is not enough.
file->path = real_path;
#endif
file->freepath = real_path; /* free this when done */
@@ -336,7 +336,7 @@ static CURLcode file_upload(struct conne
return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
@@ -347,7 +347,7 @@ static CURLcode file_upload(struct conne
else
mode = MODE_DEFAULT|O_TRUNC;
if(data->state.resume_from)
- fp = fopen( file->path, "ab" );
+ fp = fopen( file->path, "abe" );
else {
int fd;
@@ -344,7 +344,7 @@ static CURLcode file_upload(struct conne
fd = open(file->path, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
conn->data->set.new_file_perms);
#else
- fd = open(file->path, O_WRONLY|O_CREAT|O_TRUNC,
+ fd = open(file->path, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC,
conn->data->set.new_file_perms);
#endif
if(fd < 0) {
@@ -352,7 +352,7 @@ static CURLcode file_upload(struct conne
return CURLE_WRITE_ERROR;
}
close(fd);
- fp = fopen(file->path, "wb");
+ fp = fopen(file->path, "wbe");
}
if(!fp) {
- fd = open(file->path, mode, conn->data->set.new_file_perms);
+ fd = open(file->path, mode | O_CLOEXEC, conn->data->set.new_file_perms);
if(fd < 0) {
failf(data, "Can't open %s for writing", file->path);
return CURLE_WRITE_ERROR;
--- lib/formdata.c.orig
+++ lib/formdata.c
@@ -1207,7 +1207,7 @@ CURLcode Curl_getformdata(struct Session
@ -101,7 +83,7 @@ compile time is not enough.
if(-1 == ipv6_works) {
/* probe to see if we have a working IPv6 stack */
- curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
+ curl_socket_t s = socket(PF_INET6, SOCK_DGRAM | O_CLOEXEC, 0);
+ curl_socket_t s = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if(s == CURL_SOCKET_BAD)
/* an ipv6 address was requested but we can't get/use one */
ipv6_works = 0;
@ -129,7 +111,7 @@ compile time is not enough.
char *tok_buf;
--- lib/ssluse.c.orig
+++ lib/ssluse.c
@@ -435,7 +435,7 @@ int cert_stuff(struct connectdata *conn,
@@ -437,7 +437,7 @@ int cert_stuff(struct connectdata *conn,
STACK_OF(X509) *ca = NULL;
int i;
@ -138,7 +120,7 @@ compile time is not enough.
if(!f) {
failf(data, "could not open PKCS12 file '%s'", cert_file);
return 0;
@@ -2338,7 +2338,7 @@ static CURLcode servercert(struct connec
@@ -2274,7 +2274,7 @@ static CURLcode servercert(struct connec
/* e.g. match issuer name with provided issuer certificate */
if(data->set.str[STRING_SSL_ISSUERCERT]) {
@ -149,7 +131,7 @@ compile time is not enough.
failf(data, "SSL: Unable to open issuer cert (%s)",
--- lib/connect.c.orig
+++ lib/connect.c
@@ -1236,7 +1236,7 @@ CURLcode Curl_socket(struct connectdata
@@ -1238,7 +1238,7 @@ CURLcode Curl_socket(struct connectdata
(struct curl_sockaddr *)addr);
else
/* opensocket callback not set, so simply create the socket now */