all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
blob 2c913b856415cc87fc0dd9422f9beb011cc873bb 4028 bytes (raw)
name: gnu/packages/patches/perl-CVE-2016-2381.patch 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
 
Fix CVE-2016-2381 (ambiguous handling of duplicated environment variables).

Copied from Debian:
https://sources.debian.net/src/perl/5.22.1-8/debian/patches/fixes/CVE-2016-2381_duplicate_env.diff/

References:
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-2381
http://www.nntp.perl.org/group/perl.perl5.porters/2016/03/msg234747.html
https://security-tracker.debian.org/tracker/CVE-2016-2381

---

From 1237ea93fb2475a5ae576d5ee1358a5bb4ebe426 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Wed, 27 Jan 2016 11:52:15 +1100
Subject: remove duplicate environment variables from environ

If we see duplicate environment variables while iterating over
environ[]:

a) make sure we use the same value in %ENV that getenv() returns.

Previously on a duplicate, %ENV would have the last entry for the name
from environ[], but a typical getenv() would return the first entry.

Rather than assuming all getenv() implementations return the first entry
explicitly call getenv() to ensure they agree.

b) remove duplicate entries from environ

Previously if there was a duplicate definition for a name in environ[]
setting that name in %ENV could result in an unsafe value being passed
to a child process, so ensure environ[] has no duplicates.

Patch-Name: fixes/CVE-2016-2381_duplicate_env.diff
---
 perl.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/perl.c b/perl.c
index 67d32ce..26aeb91 100644
--- a/perl.c
+++ b/perl.c
@@ -4277,23 +4277,70 @@ S_init_postdump_symbols(pTHX_ int argc, char **argv, char **env)
 	}
 	if (env) {
 	  char *s, *old_var;
+          STRLEN nlen;
 	  SV *sv;
+          HV *dups = newHV();
+
 	  for (; *env; env++) {
 	    old_var = *env;
 
 	    if (!(s = strchr(old_var,'=')) || s == old_var)
 		continue;
+            nlen = s - old_var;
 
 #if defined(MSDOS) && !defined(DJGPP)
 	    *s = '\0';
 	    (void)strupr(old_var);
 	    *s = '=';
 #endif
-	    sv = newSVpv(s+1, 0);
-	    (void)hv_store(hv, old_var, s - old_var, sv, 0);
+            if (hv_exists(hv, old_var, nlen)) {
+                const char *name = savepvn(old_var, nlen);
+
+                /* make sure we use the same value as getenv(), otherwise code that
+                   uses getenv() (like setlocale()) might see a different value to %ENV
+                 */
+                sv = newSVpv(PerlEnv_getenv(name), 0);
+
+                /* keep a count of the dups of this name so we can de-dup environ later */
+                if (hv_exists(dups, name, nlen))
+                    ++SvIVX(*hv_fetch(dups, name, nlen, 0));
+                else
+                    (void)hv_store(dups, name, nlen, newSViv(1), 0);
+
+                Safefree(name);
+            }
+            else {
+                sv = newSVpv(s+1, 0);
+            }
+	    (void)hv_store(hv, old_var, nlen, sv, 0);
 	    if (env_is_not_environ)
 	        mg_set(sv);
 	  }
+          if (HvKEYS(dups)) {
+              /* environ has some duplicate definitions, remove them */
+              HE *entry;
+              hv_iterinit(dups);
+              while ((entry = hv_iternext_flags(dups, 0))) {
+                  STRLEN nlen;
+                  const char *name = HePV(entry, nlen);
+                  IV count = SvIV(HeVAL(entry));
+                  IV i;
+                  SV **valp = hv_fetch(hv, name, nlen, 0);
+
+                  assert(valp);
+
+                  /* try to remove any duplicate names, depending on the
+                   * implementation used in my_setenv() the iteration might
+                   * not be necessary, but let's be safe.
+                   */
+                  for (i = 0; i < count; ++i)
+                      my_setenv(name, 0);
+
+                  /* and set it back to the value we set $ENV{name} to */
+                  my_setenv(name, SvPV_nolen(*valp));
+              }
+          }
+          SvREFCNT_dec_NN(dups);
       }
 #endif /* USE_ENVIRON_ARRAY */
 #endif /* !PERL_MICRO */

debug log:

solving 2c913b8 ...
found 2c913b8 in https://yhetil.org/guix/92cf16de48838de4d9d060886f0bc9915e8f52e1.1456947844.git.leo@famulari.name/

applying [1/1] https://yhetil.org/guix/92cf16de48838de4d9d060886f0bc9915e8f52e1.1456947844.git.leo@famulari.name/
diff --git a/gnu/packages/patches/perl-CVE-2016-2381.patch b/gnu/packages/patches/perl-CVE-2016-2381.patch
new file mode 100644
index 0000000..2c913b8

1:51: space before tab in indent.
 	}
1:52: space before tab in indent.
 	if (env) {
1:53: space before tab in indent.
 	  char *s, *old_var;
1:55: space before tab in indent.
 	  SV *sv;
1:58: space before tab in indent.
 	  for (; *env; env++) {
Checking patch gnu/packages/patches/perl-CVE-2016-2381.patch...
Applied patch gnu/packages/patches/perl-CVE-2016-2381.patch cleanly.
warning: squelched 11 whitespace errors
warning: 16 lines add whitespace errors.

index at:
100644 2c913b856415cc87fc0dd9422f9beb011cc873bb	gnu/packages/patches/perl-CVE-2016-2381.patch

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.