On Sat, Feb 16, 2019 at 10:27:30AM +0100, Theo Buehler wrote:
> When running R with vm.malloc_conf=F, doing
> 
> > install.package("any")
> 
> on a fresh R install leads a segfault due to a use-after-free in
> src/modules/internet/libcurl.c:
> 
> 644     for (int i = 0; i < nurls; i++) {
> 
> ...
> 
> here hnd[0] is freed:
> 
> 656         curl_easy_cleanup(hnd[i]);
> 657     }
> 658     // This can show an invalid read: can it be improved?
> 659     long status = 0L;
> 660     if(nurls == 1)
> 661         curl_easy_getinfo(hnd[0], CURLINFO_RESPONSE_CODE, &status);
> 
> and here it is used again to retrieve the status code.
> 
> Note that the value of status is used later only in case nurls == 1
> for error reporting. The patch below should therefore preserve the
> intended behavior since curl_easy_getinfo() is idempotent.

OK feinerer@

Upstream commit has SVN revision 76143
(https://github.com/wch/r-source/commit/36bcd78ffd71547e1132903c00c5a6dae6e43609)

> Index: Makefile
> ===================================================================
> RCS file: /var/cvs/ports/math/R/Makefile,v
> retrieving revision 1.105
> diff -u -p -r1.105 Makefile
> --- Makefile  23 Dec 2018 08:03:45 -0000      1.105
> +++ Makefile  16 Feb 2019 08:54:02 -0000
> @@ -2,6 +2,7 @@
>  
>  COMMENT=     powerful math/statistics/graphics language
>  DISTNAME=    R-3.5.2
> +REVISION=    0
>  
>  SO_VERSION=  34.2
>  .for _lib in R Rblas Rlapack
> Index: patches/patch-src_modules_internet_libcurl_c
> ===================================================================
> RCS file: patches/patch-src_modules_internet_libcurl_c
> diff -N patches/patch-src_modules_internet_libcurl_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-src_modules_internet_libcurl_c      16 Feb 2019 08:43:53 
> -0000
> @@ -0,0 +1,31 @@
> +$OpenBSD$
> +
> +Avoid use-after-free.
> +Index: src/modules/internet/libcurl.c
> +--- src/modules/internet/libcurl.c.orig
> ++++ src/modules/internet/libcurl.c
> +@@ -641,12 +641,12 @@ in_do_curlDownload(SEXP call, SEXP op, SEXP args, SEXP
> + 
> +     n_err += curlMultiCheckerrs(mhnd);
> + 
> ++    long status = 0L;
> +     for (int i = 0; i < nurls; i++) {
> +     if (out[i]) {
> +         fclose(out[i]);
> +         double dl;
> +         curl_easy_getinfo(hnd[i], CURLINFO_SIZE_DOWNLOAD, &dl);
> +-        long status;
> +         curl_easy_getinfo(hnd[i], CURLINFO_RESPONSE_CODE, &status);
> +         // should we do something about incomplete transfers?
> +         if (status != 200 && dl == 0. && strchr(mode, 'w'))
> +@@ -655,10 +655,6 @@ in_do_curlDownload(SEXP call, SEXP op, SEXP args, SEXP
> +     curl_multi_remove_handle(mhnd, hnd[i]);
> +     curl_easy_cleanup(hnd[i]);
> +     }
> +-    // This can show an invalid read: can it be improved?
> +-    long status = 0L;
> +-    if(nurls == 1)
> +-    curl_easy_getinfo(hnd[0], CURLINFO_RESPONSE_CODE, &status);
> +     curl_multi_cleanup(mhnd);
> +     if (!cacheOK) curl_slist_free_all(slist1);
> + 

Reply via email to