aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/perl/perl/CVE-2018-18311.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/perl/perl/CVE-2018-18311.patch')
-rw-r--r--meta/recipes-devtools/perl/perl/CVE-2018-18311.patch183
1 files changed, 183 insertions, 0 deletions
diff --git a/meta/recipes-devtools/perl/perl/CVE-2018-18311.patch b/meta/recipes-devtools/perl/perl/CVE-2018-18311.patch
new file mode 100644
index 0000000000..ba8cf151fd
--- /dev/null
+++ b/meta/recipes-devtools/perl/perl/CVE-2018-18311.patch
@@ -0,0 +1,183 @@
+From 4706b65d7c835c0bb219db160fbcdbcd98efab2d Mon Sep 17 00:00:00 2001
+From: David Mitchell <davem@iabyn.com>
+Date: Fri, 29 Jun 2018 13:37:03 +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.
+
+(cherry picked from commit 34716e2a6ee2af96078d62b065b7785c001194be)
+
+CVE: CVE-2018-18311
+Upstream-Status: Backport
+[https://perl5.git.perl.org/perl.git/commit/5737d31aac51360cc1eb412ef059e36147c9d6d6]
+
+Signed-off-by: Dan Tran <dantran@microsoft.com>
+---
+ util.c | 76 ++++++++++++++++++++++++++++++++++++++++------------------
+ 1 file changed, 53 insertions(+), 23 deletions(-)
+
+diff --git a/util.c b/util.c
+index 7c3d271f51..27f4eddf3b 100644
+--- a/util.c
++++ b/util.c
+@@ -2160,8 +2160,40 @@ 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:
++ croak_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)
+ {
+@@ -2177,28 +2209,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 */
+- I32 i;
+- 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;
+@@ -2217,15 +2248,15 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val)
+ #endif
+ }
+ 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 {
+@@ -2250,22 +2281,21 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val)
+ if (environ) /* old glibc can crash with null environ */
+ (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);
+@@ -2288,14 +2318,14 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val)
+ {
+ dVAR;
+ 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.22.0.vfs.1.1.57.gbaf16c8
+