r-lib / pak

A fresh approach to package installation
https://pak.r-lib.org
682 stars 62 forks source link

pkgsearch (`pkg_history()`) does not use embedded certs in binary builds #693

Closed pat-s closed 1 month ago

pat-s commented 1 month ago

As they are referencing Ubuntu-specific paths, e.g. for CURL_CA_BUNDLE (maybe others in addition). Installing from source solves it as then curl is properly linked.

docker run --rm -it almalinux/9 bash

dnf install -y epel-release
dnf config-manager --set-enabled crb

dnf install -y -q R R-devel libcurl-devel 

# install binary
R -q -e 'install.packages("pak", repos = sprintf("https://r-lib.github.io/p/pak/stable/%s/%s/%s", .Platform$pkgType, R.Version()$os, R.Version()$arch))'

# fails
R -q -e "pak::pkg_history('pak')"
! Optional package `pillar` is not available for pak.
  Use `pak::pak_install_extra()` to install optional packages.
  Use `options(pak.no_extra_messages = TRUE)` to suppress this message.
Error:
! error in pak subprocess
Caused by error in `curl::curl_fetch_memory(url)`:
! error setting certificate verify locations:
  CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: none
---
Backtrace:
1. pak::pkg_history("pak")
2. pak:::remote(function(...) { …
3. err$throw(res$error)
---
Subprocess backtrace:
1. base::withCallingHandlers(cli_message = function(msg) { …
2. get("pkg_history_internal", asNamespace("pak"))(...)
3. pkgsearch::cran_package_history(pkg)
4. pkgsearch:::crandb_query(ept)
5. pkgsearch:::http_get(url0)
6. curl::curl_fetch_memory(url)
7. base::.handleSimpleError(function (e) …
8. global h(simpleError(msg

R -q -e "install.packages('pak', repos = 'cloud.r-project.org')"

# works
R -q -e "pak::pkg_history('pak')"
gaborcsardi commented 1 month ago

As they are referencing Ubuntu-specific paths, e.g. for CURL_CA_BUNDLE (maybe others in addition).

Where do they do that?

gaborcsardi commented 1 month ago

For me curl crashes on Almalinux 9 (aarch64):

> library(curl, lib.loc="/usr/lib64/R/library/pak/library")
Using libcurl 7.68.0 with OpenSSL/3.0.0g
> curl::curl_fetch_memory("https://example.com")

 *** caught segfault ***
address 0xfffffffffffffff9, cause 'memory not mapped

HTTP works, HTTPS does not, so I suspect it is an openssl (or Docker) issue.

Aarch64 RHEL 9 works, though.

On x86_64 both Almalinux 9 and RHeL 9 work for me.

gaborcsardi commented 1 month ago

Actually, for pkg_history() specifically, I do see the issue, but that seems to be a certificate problem with crandb.r-pkg.org, because I also see it on every distro, e.g. on Alpine as well.

gaborcsardi commented 1 month ago

Actually, this is simply a bug in pkg_history(), it does not set the certificate path to the bundled certificates like the other functions.

The workaround is to call pkgsearch::cran_package_history() directly, or indeed to compile pak on the system, so it'll use the system's cert bundle.

Will fix soon.

gaborcsardi commented 1 month ago

Fixed in the dev build, new Linux binaries are already deployed. I opened another issue for the aarch64 almalinux 9 crash: #694.

> source("https://pak.r-lib.org/install.R?stream=devel")
Installing pak from stream devel.
Installing package into ‘/root/R/aarch64-unknown-linux-gnu-library/4.4’
(as ‘lib’ is unspecified)
trying URL 'https://r-lib.github.io/p/pak/devel/source/linux-gnu/aarch64/src/contrib/../../../../../linux/aarch64/pak_0.8.0.9000_R-4-4_aarch64-linux.tar.gz'
Content type 'application/gzip' length 8866820 bytes (8.5 MB)
==================================================
downloaded 8.5 MB

* installing *binary* package ‘pak’ ...
* DONE (pak)

The downloaded source packages are in
    ‘/tmp/RtmpGu21au/downloaded_packages’
> pak::pkg_history("pak")
# A data frame: 14 × 30
   Package Version Title       Description `Authors@R` License Encoding LazyData
 * <chr>   <chr>   <chr>       <chr>       <chr>       <chr>   <chr>    <chr>
 1 pak     0.1.2   Another Ap… "The goal … "c(\nperso… GPL-3   UTF-8    true
 2 pak     0.1.2.1 Another Ap… "The goal … "c(\nperso… GPL-3   UTF-8    true
 3 pak     0.2.0   Another Ap… "The goal … "c(\nperso… GPL-3   UTF-8    true
 4 pak     0.2.1   Another Ap… "The goal … "c(\nperso… GPL-3   UTF-8    true
 5 pak     0.3.0   Another Ap… "The goal … "c(\nperso… GPL-3   UTF-8    true
 6 pak     0.3.1   Another Ap… "The goal … "c(\nperso… GPL-3   UTF-8    true
 7 pak     0.4.0   Another Ap… "The goal … "c(\nperso… GPL-3   UTF-8    true
 8 pak     0.5.0   Another Ap… "The goal … "c(\nperso… GPL-3   UTF-8    true
 9 pak     0.5.1   Another Ap… "The goal … "c(\nperso… GPL-3   UTF-8    true
10 pak     0.6.0   Another Ap… "The goal … "c(\nperso… GPL-3   UTF-8    true
11 pak     0.7.0   Another Ap… "The goal … "c(\nperso… GPL-3   UTF-8    NA
12 pak     0.7.1   Another Ap… "The goal … "c(\nperso… GPL-3   UTF-8    NA
13 pak     0.7.2   Another Ap… "The goal … "c(\nperso… GPL-3   UTF-8    NA
14 pak     0.8.0   Another Ap… "The goal … "c(\nperso… GPL-3   UTF-8    NA
# ℹ 22 more variables: ByteCompile <chr>, RoxygenNote <chr>, URL <chr>,
#   BugReports <chr>, NeedsCompilation <chr>, Packaged <chr>, Author <chr>,
#   Maintainer <chr>, Repository <chr>, `Date/Publication` <chr>,
#   crandb_file_date <chr>, MD5sum <chr>, date <chr>, dependencies <list>,
#   `Config/needs/dependencies` <chr>, `Config/testthat/edition` <chr>,
#   BuildResaveData <chr>, Note <chr>, `Config/Needs/website` <chr>,
#   `Config/build/extra-sources` <chr>, Biarch <chr>, …
pat-s commented 1 month ago

Where do they do that?

/etc/ssl/certs/ca-certificates.crt is a Debian/Ubuntu specific SSL location. In RHEL, this is usually under /etc/pki/[...]. This is what got me on the path that the binaries are debian-specific as they are only built on Ubuntu. At some point curl comes into play and tries to set CURL_CA_BUNDLE according to the underlying platform. After seeing that it works when building from source, I concluded it to be a binary/platform issue.

Actually, this is simply a bug in pkg_history(), it does not set the certificate path to the bundled certificates like the other functions.

Glad to hear that the report uncovered this then and led to a fix. I have of course not the insights to know what is exactly happening behind the scenes; there are also too many players involved (starting from {pak} at the top).

Thanks for the fix!

Aarch64 RHEL 9 works, though.

This is strange, usually RHEL 9 and Alma9 should behave identical in such cases.

gaborcsardi commented 1 month ago

as they are only built on Ubuntu.

They are not built on Ubuntu, they are built on Alpine. They also include a certificate bundle, which they use by default instead of the system's.

pat-s commented 1 month ago

Ah, sorry, missed the buildx step and only looked at the GA OS!