diff --git a/SOURCES/perl-5.16.3-Perl_my_setenv-handle-integer-wrap.patch b/SOURCES/perl-5.16.3-Perl_my_setenv-handle-integer-wrap.patch new file mode 100644 index 0000000..44ace06 --- /dev/null +++ b/SOURCES/perl-5.16.3-Perl_my_setenv-handle-integer-wrap.patch @@ -0,0 +1,175 @@ +From 17858779e42103ae815c8cf7c4d390207e485856 Mon Sep 17 00:00:00 2001 +From: Jitka Plesnikova <jplesnik@redhat.com> +Date: Mon, 7 Jan 2019 13:38:36 +0100 +Subject: [PATCH] Perl_my_setenv(); handle integer wrap + +RT #133204 + +Wean this function off int/I32 and onto UV/Size_t. +Also, replace all malloc-ish calls with a wrapper that does +overflow checks, + +In particular, it was doing (nlen + vlen + 2) which could wrap when +the combined length of the environment variable name and value +exceeded around 0x7fffffff. + +The wrapper check function is probably overkill, but belt and braces... + +NB this function has several variant parts, #ifdef'ed by platform +type; I have blindly changed the parts that aren't compiled under linux. + +Backported David Mitchell's patch to 5.16.3 +--- + util.c | 75 ++++++++++++++++++++++++++++++++++++++++------------------ + 1 file changed, 52 insertions(+), 23 deletions(-) + +diff --git a/util.c b/util.c +index c1dca62..1357ad5 100644 +--- a/util.c ++++ b/util.c +@@ -2029,7 +2029,38 @@ Perl_new_warnings_bitfield(pTHX_ STRLEN *buffer, const char *const bits, + *(s+(nlen+1+vlen)) = '\0' + + #ifdef USE_ENVIRON_ARRAY +- /* VMS' my_setenv() is in vms.c */ ++ ++/* small wrapper for use by Perl_my_setenv that mallocs, or reallocs if ++ * 'current' is non-null, with up to three sizes that are added together. ++ * It handles integer overflow. ++ */ ++static char * ++S_env_alloc(void *current, Size_t l1, Size_t l2, Size_t l3, Size_t size) ++{ ++ void *p; ++ Size_t sl, l = l1 + l2; ++ ++ if (l < l2) ++ goto panic; ++ l += l3; ++ if (l < l3) ++ goto panic; ++ sl = l * size; ++ if (sl < l) ++ goto panic; ++ ++ p = current ++ ? safesysrealloc(current, sl) ++ : safesysmalloc(sl); ++ if (p) ++ return (char*)p; ++ ++ panic: ++ Perl_croak_nocontext("%s", PL_memory_wrap); ++} ++ ++ ++/* VMS' my_setenv() is in vms.c */ + #if !defined(WIN32) && !defined(NETWARE) + void + Perl_my_setenv(pTHX_ const char *nam, const char *val) +@@ -2043,28 +2074,27 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val) + #ifndef PERL_USE_SAFE_PUTENV + if (!PL_use_safe_putenv) { + /* most putenv()s leak, so we manipulate environ directly */ +- register I32 i; +- register const I32 len = strlen(nam); +- int nlen, vlen; ++ UV i; ++ Size_t vlen, nlen = strlen(nam); + + /* where does it go? */ + for (i = 0; environ[i]; i++) { +- if (strnEQ(environ[i],nam,len) && environ[i][len] == '=') ++ if (strnEQ(environ[i], nam, nlen) && environ[i][nlen] == '=') + break; + } + + if (environ == PL_origenviron) { /* need we copy environment? */ +- I32 j; +- I32 max; ++ UV j, max; + char **tmpenv; + + max = i; + while (environ[max]) + max++; +- tmpenv = (char**)safesysmalloc((max+2) * sizeof(char*)); ++ /* XXX shouldn't that be max+1 rather than max+2 ??? - DAPM */ ++ tmpenv = (char**)S_env_alloc(NULL, max, 2, 0, sizeof(char*)); + for (j=0; j<max; j++) { /* copy environment */ +- const int len = strlen(environ[j]); +- tmpenv[j] = (char*)safesysmalloc((len+1)*sizeof(char)); ++ const Size_t len = strlen(environ[j]); ++ tmpenv[j] = S_env_alloc(NULL, len, 1, 0, 1); + Copy(environ[j], tmpenv[j], len+1, char); + } + tmpenv[max] = NULL; +@@ -2079,15 +2109,15 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val) + return; + } + if (!environ[i]) { /* does not exist yet */ +- environ = (char**)safesysrealloc(environ, (i+2) * sizeof(char*)); ++ environ = (char**)S_env_alloc(environ, i, 2, 0, sizeof(char*)); + environ[i+1] = NULL; /* make sure it's null terminated */ + } + else + safesysfree(environ[i]); +- nlen = strlen(nam); ++ + vlen = strlen(val); + +- environ[i] = (char*)safesysmalloc((nlen+vlen+2) * sizeof(char)); ++ environ[i] = S_env_alloc(NULL, nlen, vlen, 2, 1); + /* all that work just for this */ + my_setenv_format(environ[i], nam, nlen, val, vlen); + } else { +@@ -2107,22 +2137,21 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val) + if (val == NULL) { + (void)unsetenv(nam); + } else { +- const int nlen = strlen(nam); +- const int vlen = strlen(val); +- char * const new_env = +- (char*)safesysmalloc((nlen + vlen + 2) * sizeof(char)); ++ const Size_t nlen = strlen(nam); ++ const Size_t vlen = strlen(val); ++ char * const new_env = S_env_alloc(NULL, nlen, vlen, 2, 1); + my_setenv_format(new_env, nam, nlen, val, vlen); + (void)putenv(new_env); + } + # else /* ! HAS_UNSETENV */ + char *new_env; +- const int nlen = strlen(nam); +- int vlen; ++ const Size_t nlen = strlen(nam); ++ Size_t vlen; + if (!val) { + val = ""; + } + vlen = strlen(val); +- new_env = (char*)safesysmalloc((nlen + vlen + 2) * sizeof(char)); ++ new_env = S_env_alloc(NULL, nlen, vlen, 2, 1); + /* all that work just for this */ + my_setenv_format(new_env, nam, nlen, val, vlen); + (void)putenv(new_env); +@@ -2141,14 +2170,14 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val) + { + dVAR; + register char *envstr; +- const int nlen = strlen(nam); +- int vlen; ++ const Size_t nlen = strlen(nam); ++ Size_t vlen; + + if (!val) { + val = ""; + } + vlen = strlen(val); +- Newx(envstr, nlen+vlen+2, char); ++ envstr = S_env_alloc(NULL, nlen, vlen, 2, 1); + my_setenv_format(envstr, nam, nlen, val, vlen); + (void)PerlEnv_putenv(envstr); + Safefree(envstr); +-- +2.17.2 + diff --git a/SPECS/perl.spec b/SPECS/perl.spec index c7534d0..ea94be5 100644 --- a/SPECS/perl.spec +++ b/SPECS/perl.spec @@ -31,7 +31,7 @@ Name: perl Version: %{perl_version} # release number must be even higher, because dual-lived modules will be broken otherwise -Release: 293%{?dist} +Release: 294%{?dist} Epoch: %{perl_epoch} Summary: Practical Extraction and Report Language Group: Development/Languages @@ -175,6 +175,10 @@ Patch41: perl-5.16.3-use-SNI-for-SSL-support-in-SMTP.patch # fixed in Math-BigInt-1.999718 Patch42: perl-5.16.3-Fix-Math-BigInt-overload-warning.patch +# Fix an integer wrap when allocating memory for an environment variable, +# RT#133204, in upstream after 5.29.0 - CVE-2018-18311 +Patch43: perl-5.16.3-Perl_my_setenv-handle-integer-wrap.patch + # Update some of the bundled modules # see http://fedoraproject.org/wiki/Perl/perl.spec for instructions @@ -1976,6 +1980,7 @@ tarball from perl.org. %patch40 -p1 %patch41 -p1 %patch42 -p1 +%patch43 -p1 %if !%{defined perl_bootstrap} # Local patch tracking @@ -2020,6 +2025,7 @@ perl -x patchlevel.h \ 'RHEL Patch40: Add SSL support to Net::SMTP (CPAN RT#93823) [3]' \ 'RHEL Patch41: Add SSL support to Net::SMTP (CPAN RT#93823) [4]' \ 'RHEL Patch42: Do not overload ".." in Math::BigInt (CPAN RT#80182)' \ + 'RHEL Patch43: Fix CVE-2018-18311 Integer overflow leading to buffer overflow' \ %{nil} %endif @@ -3702,6 +3708,9 @@ sed \ # Old changelog entries are preserved in CVS. %changelog +* Mon Jan 07 2019 Jitka Plesnikova <jplesnik@redhat.com> - 4:5.16.3-294 +- Fix CVE-2018-18311 Integer overflow leading to buffer overflow (bug #1661064) + * Wed Mar 21 2018 Petr Pisar <ppisar@redhat.com> - 4:5.16.3-293 - Add SSL support to Net::SMTP (bug #1557574) - Do not overload ".." in Math::BigInt (bug #1497734)