Skip to content

Update cURL pin - #1083

Open
msarahan wants to merge 9 commits into
rapidsai:mainfrom
msarahan:codex/update-curl-cpm-8.22.0
Open

msarahan wants to merge 9 commits into
rapidsai:mainfrom
msarahan:codex/update-curl-cpm-8.22.0

Conversation

@msarahan

@msarahan msarahan commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Update cURL pin to the most recent release, 8.23.0.

This was done to avoid security issues associated with versions <8.22.

8.22 is not an option, because it has a performance bug that is described in comments below. 8.23.0 is supposed to fix the performance bug and keep the security issue fixes.

This is complicated by the fact that cURL >=8.18 requires openssl 3.x, which is not in our default build environment. Static libraries for openssl 3.x do not seem to be available for RockyLinux 8. This PR changes openssl to be built from source for wheels and statically linked. For conda, it changes to dynamic linkage for openssl, rather than static linkage, which is better hygiene in the conda ecosystem, and allows security fixes for openssl to be deployed without rebuilding kvikio.

@msarahan
msarahan requested a review from a team as a code owner October 1, 2026 13:31
@msarahan msarahan added improvement Improves an existing functionality non-breaking Introduces a non-breaking change labels Oct 1, 2026
robertmaynard
robertmaynard previously approved these changes Oct 1, 2026
@kingcrimsontianyu

kingcrimsontianyu commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Libcurl >= 8.21 carries a performance bug that unexpectedly disables caching for the CA bundle file and causes it to be repeatedly re-parsed during TLS. Microbenchmark shows the TLS time for stead-state S3 read is:

KvikIO main + curl 8.13 (as shipped): 0.28-0.31 s (where we are now)
KvikIO main + curl 8.22.0: 5.8-7.2 s (performance bug if we upgrade curl)

I will need to further evaluate the end-to-end performance impact using Polars and Presto GPU TPC-H. If it is trivial, then we can upgrade.

#1080 tried to work around this performance bug, but caused another severe regression for Presto GPU TPC-H benchmark, so I reverted the change in #1081.

@kingcrimsontianyu

Copy link
Copy Markdown
Contributor

I've made several tests. The TL;DR of my findings are:

  • curl >=8.21 causes significant bandwidth drop and TLS time increase for AWS S3 small-size read (1.5 MiB and 8 MiB tested), reflected in the microbenchmark and Polars TPC-H SF-1K benchmark.
  • Upgrading to OpenSSL 3.5.8 can be a temporary workaround.
  • There is an existing curl PR (Revert 'setopt: claer the "custom" CA booleans when set to NULL' curl/curl#23202) submitted by curl's dev on Sep 30, 2026, that reverts some of the previous changes that caused the regression.

Microbenchmark

  • Measures the bandwidth for small workload (1.5 MiB and 8 MiB task size)
HTTPS into host memory, 1.5 MiB reads
+-----------------+---------+---------------------+-----------------------------+--------------------+
| Curl version    | OpenSSL | Mean                | Runs (GiB/s)                | TLS per connection |
+-----------------+---------+---------------------+-----------------------------+--------------------+
| 8.13.0          | 3.0.13  |  6.05 GiB/s   base  | 6.04  5.66  6.13  6.36      |      54 ms         |
| 8.22.0          | 3.0.13  |  3.89 GiB/s -35.7%  | 3.98  3.73  4.10  3.75      |    1629 ms         |
| PR 23202 parent | 3.0.13  |  3.92 GiB/s -35.1%  | 3.55  3.94  4.16  4.05      |    1667 ms         |
| PR 23202 head   | 3.0.13  |  6.22 GiB/s  +2.9%  | 5.72  6.64  5.65  6.86      |      49 ms         |
| 8.22.0          | 3.5.8   |  5.97 GiB/s  -1.2%  | 5.55  6.08  6.03  6.23      |      19 ms         |
+-----------------+---------+---------------------+-----------------------------+--------------------+

HTTPS into host memory, 8 MiB reads
+-----------------+---------+---------------------+-----------------------------+--------------------+
| Curl version    | OpenSSL | Mean                | Runs (GiB/s)                | TLS per connection |
+-----------------+---------+---------------------+-----------------------------+--------------------+
| 8.13.0          | 3.0.13  | 23.11 GiB/s   base  | 25.14  23.97  21.62  21.71  |      68 ms         |
| 8.22.0          | 3.0.13  | 16.60 GiB/s -28.2%  | 14.36  18.77  17.15  16.11  |    1885 ms         |
| PR 23202 parent | 3.0.13  | 17.68 GiB/s -23.5%  | 17.82  16.49  18.12  18.30  |    1726 ms         |
| PR 23202 head   | 3.0.13  | 23.46 GiB/s  +1.5%  | 22.20  24.38  22.74  24.50  |      61 ms         |
| 8.22.0          | 3.5.8   | 23.83 GiB/s  +3.1%  | 23.69  24.36  22.79  24.47  |      27 ms         |
+-----------------+---------+---------------------+-----------------------------+--------------------+

KvikIO MULTI_POLL with 48 reactors
cap of 384 concurrent requests, 64 MiB tasks, 4 interleaved runs per row. 
TLS per connection: mean APPCONNECT - CONNECT time over all new connections in a run.

Polars

+-------+---------+-----------+-----------+-------------+-------------+------------+---------------+
| curl  | OpenSSL | Run 1 s   | Run 2 s   | Mean iter 1 | Mean iter 2 | Mean total | vs 8.13 / 3.0 |
+-------+---------+-----------+-----------+-------------+-------------+------------+---------------+
| 8.13  | 3.0.13  |     296.5 |     283.0 |       154.5 |       135.3 |      289.8 |          base |
| 8.22  | 3.0.13  |     337.9 |     330.6 |       176.4 |       157.9 |      334.3 |        +15.4% |
| 8.13  | 3.5.8   |     300.4 |     284.9 |       156.2 |       136.5 |      292.7 |         +1.0% |
| 8.22  | 3.5.8   |     290.5 |     286.4 |       153.2 |       135.3 |      288.5 |         -0.4% |
+-------+---------+-----------+-----------+-------------+-------------+------------+---------------+

Presto GPU

Interestingly, in Presto GPU, KvikIO does not use its own libcurl library, but the one bundled in Velox, which currently pins to 8.4.0, and is not affected by the regression issue.

@kingcrimsontianyu

kingcrimsontianyu commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

So I think we should either hold off the upgrade until the curl PR is merged into a newer version of curl, or we proceed with the upgrade and advise users to upgrade their OpenSSL if they are using this common backend.

@msarahan

Copy link
Copy Markdown
Contributor Author

curl v2.18+ requires openssl 3.x. We have to find a source for that. RHEL 8 does not seem to provide static libraries here - only dynamic builds. This PR obtains the conda-forge openssl-static package and links it statically into the wheel builds. Statically linking OpenSSL is not good in general, because if there's a security issue, you must rebuild packages to fix the issue. Dynamic linking would allow drop-in of a new openssl shared library, without touching kvikio or other consumers. This said, static linking is already what we were doing with the system openssl, so at least we're not any worse. I am verifying that there are no compatibility concerns as far as libgcc, ABI, or otherwise.

@msarahan
msarahan changed the base branch from release/26.10 to main October 14, 2026 17:56
Avoid the curl CA-cache regression in the bundled source dependency while preserving conda's older build floor and run_exports. Require the conda host shared library so CPM cannot silently replace it with a source build. Add the required Bandit and flake8-bugbear pre-commit checks.
The build.sh parser requires literal quotes around --cmake-args. Shell quoting alone removed them, so the conda C++ job rejected the options before invoking CMake. Preserve the inner quotes and exercise the actual recipe command with normal and long conda prefixes, checking that the supplied shared curl options reach CMake.
Use checksum-pinned conda-forge archives and matching headers without installing conda, so curl 8.23 can build on the existing manylinux images. Initialize the private OpenSSL copy through its supported API before curl, preserving OPENSSL_CONF overrides and failing on invalid selected configuration. Keep installed curl handling unchanged for conda builds.

Add GPU-independent configuration and TLS handshake regressions to wheel CI, and include the OpenSSL license in wheel installs.
The TLS policy test invokes the build image's openssl command, whose compiled default configuration path may not exist. Supply a minimal request configuration when generating the local server certificate so that missing image configuration cannot prevent the handshake regression from running. Let pytest capture stderr directly so future certificate failures include their diagnostics.
Replace conda-forge binary archives with the checksum-pinned upstream OpenSSL 3.6.5 release. Build private PIC static libraries before curl runs its configuration checks, preserving assembly optimizations and host configuration handling. Keep generated files outside CPM's shared source cache and reuse completed builds until the source version, compiler, or configuration changes.

Ensure wheel CI has the Perl core modules required by OpenSSL 3, and extend dependency-selection tests to prove that conda builds bypass the source build even when static OpenSSL is enabled. Validate both architectures and the production curl CPM path, including HTTPS, S3, certificate rejection, and license installation.
Main now determines the CUDA version before processing build targets. Keep the conda argument regression independent of a CUDA installation by supplying the version explicitly while continuing to stub CMake.
@msarahan
msarahan force-pushed the codex/update-curl-cpm-8.22.0 branch from f28c2b6 to 32de9de Compare October 14, 2026 18:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement Improves an existing functionality non-breaking Introduces a non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants