[pacman-dev] [PATCH] libalpm: prevent 301 redirect loop from hanging the process
If a mirror responds with a 301 redirect to itself, it will create an infinite redirect loop. This will cause pacman to hang, unresponsive to even a SIGINT. The result is pacman being unable to sync or download any package from a particular repo if its current mirror is stuck in a redirect loop. Setting libcurl's MAXREDIRS option effectively prevents a redirect loop from hanging the process. Signed-off-by: Mark Ulrich <mark.ulrich.86@gmail.com> --- lib/libalpm/dload.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index 36ae4ee1..d04a5e46 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -259,6 +259,7 @@ static void curl_set_handle_opts(struct dload_payload *payload, curl_easy_setopt(curl, CURLOPT_URL, payload->fileurl); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_buffer); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 1L); curl_easy_setopt(curl, CURLOPT_FILETIME, 1L); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); -- 2.20.1
On Wed, Feb 06, 2019 at 05:22:46AM -0600, Mark Ulrich wrote:
If a mirror responds with a 301 redirect to itself, it will create an infinite redirect loop. This will cause pacman to hang, unresponsive to even a SIGINT. The result is pacman being unable to sync or download any package from a particular repo if its current mirror is stuck in a redirect loop. Setting libcurl's MAXREDIRS option effectively prevents a redirect loop from hanging the process.
Signed-off-by: Mark Ulrich <mark.ulrich.86@gmail.com> --- lib/libalpm/dload.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index 36ae4ee1..d04a5e46 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -259,6 +259,7 @@ static void curl_set_handle_opts(struct dload_payload *payload, curl_easy_setopt(curl, CURLOPT_URL, payload->fileurl); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_buffer); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 1L);
But what if you have a mirror which legitimately has 2 hops? I could see someone trying to run something like: pacman -U https://www.archlinux.org/packages/core/x86_64/pacman/download/ This is guaranteed 1 redirect already, what if the mirror that it redirects to has a legitimate second hop in order to account for some reorganizing? I'm fine with the spirit of the patch, but limiting this to a single hop isn't enough. A larger number like 10 still accomplishes the same goal while allowing some mirror flexibility/brokenness.
curl_easy_setopt(curl, CURLOPT_FILETIME, 1L); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); -- 2.20.1
But what if you have a mirror which legitimately has 2 hops? I could see someone trying to run something like:
pacman -U https://www.archlinux.org/packages/core/x86_64/pacman/download/
This is guaranteed 1 redirect already, what if the mirror that it redirects to has a legitimate second hop in order to account for some reorganizing?
I'm fine with the spirit of the patch, but limiting this to a single hop isn't enough. A larger number like 10 still accomplishes the same goal while allowing some mirror flexibility/brokenness.
That makes sense. I will change it to 10 redirects and resubmit. -- Mark Ulrich <mark.ulrich.86@gmail.com>
If a mirror responds with a 301 redirect to itself, it will create an infinite redirect loop. This will cause pacman to hang, unresponsive to even a SIGINT. The result is pacman being unable to sync or download any package from a particular repo if its current mirror is stuck in a redirect loop. Setting libcurl's MAXREDIRS option effectively prevents a redirect loop from hanging the process. Signed-off-by: Mark Ulrich <mark.ulrich.86@gmail.com> --- lib/libalpm/dload.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index 36ae4ee1..7b114230 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -259,6 +259,7 @@ static void curl_set_handle_opts(struct dload_payload *payload, curl_easy_setopt(curl, CURLOPT_URL, payload->fileurl); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_buffer); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 10L); curl_easy_setopt(curl, CURLOPT_FILETIME, 1L); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); -- 2.20.1
On 7/2/19 12:36 am, Mark Ulrich wrote:
If a mirror responds with a 301 redirect to itself, it will create an infinite redirect loop. This will cause pacman to hang, unresponsive to even a SIGINT. The result is pacman being unable to sync or download any package from a particular repo if its current mirror is stuck in a redirect loop. Setting libcurl's MAXREDIRS option effectively prevents a redirect loop from hanging the process.
Signed-off-by: Mark Ulrich <mark.ulrich.86@gmail.com> --- lib/libalpm/dload.c | 1 + 1 file changed, 1 insertion(+)
Great! Applied. Allan
diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index 36ae4ee1..7b114230 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -259,6 +259,7 @@ static void curl_set_handle_opts(struct dload_payload *payload, curl_easy_setopt(curl, CURLOPT_URL, payload->fileurl); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_buffer); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 10L); curl_easy_setopt(curl, CURLOPT_FILETIME, 1L); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
participants (3)
-
Allan McRae
-
Dave Reisner
-
Mark Ulrich