author | Vladimir Marek <Vladimir.Marek@oracle.com> |
Mon, 09 May 2016 16:20:59 +0200 | |
branch | s11u3-sru |
changeset 6015 | cf9d441012dc |
permissions | -rw-r--r-- |
6015
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
1 |
(fixed in perl 5.22.2. I have changed SvREFCNT_dec_NN to SvREFCNT_dec as perl |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
2 |
5.12 does not have the former available. 'NN' stands for NonNull meaning that |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
3 |
the function can rely on a fact that input parameter is not null for better |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
4 |
optimization. SvREFCNT_dec is thus more general and safe to replace) |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
5 |
|
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
6 |
From ae37b791a73a9e78dedb89fb2429d2628cf58076 Mon Sep 17 00:00:00 2001 |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
7 |
From: Tony Cook <[email protected]> |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
8 |
Date: Wed, 27 Jan 2016 11:52:15 +1100 |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
9 |
Subject: [PATCH 1/1] remove duplicate environment variables from environ |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
10 |
|
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
11 |
If we see duplicate environment variables while iterating over |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
12 |
environ[]: |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
13 |
|
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
14 |
a) make sure we use the same value in %ENV that getenv() returns. |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
15 |
|
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
16 |
Previously on a duplicate, %ENV would have the last entry for the name |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
17 |
from environ[], but a typical getenv() would return the first entry. |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
18 |
|
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
19 |
Rather than assuming all getenv() implementations return the first entry |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
20 |
explicitly call getenv() to ensure they agree. |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
21 |
|
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
22 |
b) remove duplicate entries from environ |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
23 |
|
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
24 |
Previously if there was a duplicate definition for a name in environ[] |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
25 |
setting that name in %ENV could result in an unsafe value being passed |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
26 |
to a child process, so ensure environ[] has no duplicates. |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
27 |
|
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
28 |
CVE-2016-2381 |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
29 |
--- |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
30 |
perl.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
31 |
1 file changed, 49 insertions(+), 2 deletions(-) |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
32 |
|
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
33 |
diff --git a/perl.c b/perl.c |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
34 |
index 4a324c6..5c71fd0 100644 |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
35 |
--- a/perl.c |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
36 |
+++ b/perl.c |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
37 |
@@ -4329,23 +4329,70 @@ S_init_postdump_symbols(pTHX_ int argc, char **argv, char **env) |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
38 |
} |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
39 |
if (env) { |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
40 |
char *s, *old_var; |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
41 |
+ STRLEN nlen; |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
42 |
SV *sv; |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
43 |
+ HV *dups = newHV(); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
44 |
+ |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
45 |
for (; *env; env++) { |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
46 |
old_var = *env; |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
47 |
|
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
48 |
if (!(s = strchr(old_var,'=')) || s == old_var) |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
49 |
continue; |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
50 |
+ nlen = s - old_var; |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
51 |
|
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
52 |
#if defined(MSDOS) && !defined(DJGPP) |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
53 |
*s = '\0'; |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
54 |
(void)strupr(old_var); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
55 |
*s = '='; |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
56 |
#endif |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
57 |
- sv = newSVpv(s+1, 0); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
58 |
- (void)hv_store(hv, old_var, s - old_var, sv, 0); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
59 |
+ if (hv_exists(hv, old_var, nlen)) { |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
60 |
+ const char *name = savepvn(old_var, nlen); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
61 |
+ |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
62 |
+ /* make sure we use the same value as getenv(), otherwise code that |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
63 |
+ uses getenv() (like setlocale()) might see a different value to %ENV |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
64 |
+ */ |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
65 |
+ sv = newSVpv(PerlEnv_getenv(name), 0); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
66 |
+ |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
67 |
+ /* keep a count of the dups of this name so we can de-dup environ later */ |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
68 |
+ if (hv_exists(dups, name, nlen)) |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
69 |
+ ++SvIVX(*hv_fetch(dups, name, nlen, 0)); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
70 |
+ else |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
71 |
+ (void)hv_store(dups, name, nlen, newSViv(1), 0); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
72 |
+ |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
73 |
+ Safefree(name); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
74 |
+ } |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
75 |
+ else { |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
76 |
+ sv = newSVpv(s+1, 0); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
77 |
+ } |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
78 |
+ (void)hv_store(hv, old_var, nlen, sv, 0); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
79 |
if (env_is_not_environ) |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
80 |
mg_set(sv); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
81 |
} |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
82 |
+ if (HvKEYS(dups)) { |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
83 |
+ /* environ has some duplicate definitions, remove them */ |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
84 |
+ HE *entry; |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
85 |
+ hv_iterinit(dups); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
86 |
+ while ((entry = hv_iternext_flags(dups, 0))) { |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
87 |
+ STRLEN nlen; |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
88 |
+ const char *name = HePV(entry, nlen); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
89 |
+ IV count = SvIV(HeVAL(entry)); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
90 |
+ IV i; |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
91 |
+ SV **valp = hv_fetch(hv, name, nlen, 0); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
92 |
+ |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
93 |
+ assert(valp); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
94 |
+ |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
95 |
+ /* try to remove any duplicate names, depending on the |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
96 |
+ * implementation used in my_setenv() the iteration might |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
97 |
+ * not be necessary, but let's be safe. |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
98 |
+ */ |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
99 |
+ for (i = 0; i < count; ++i) |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
100 |
+ my_setenv(name, 0); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
101 |
+ |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
102 |
+ /* and set it back to the value we set $ENV{name} to */ |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
103 |
+ my_setenv(name, SvPV_nolen(*valp)); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
104 |
+ } |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
105 |
+ } |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
106 |
+ SvREFCNT_dec(dups); |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
107 |
} |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
108 |
#endif /* USE_ENVIRON_ARRAY */ |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
109 |
#endif /* !PERL_MICRO */ |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
110 |
-- |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
111 |
2.8.2-513-g68575d3 |
cf9d441012dc
23238179 problem in UTILITY/PERL
Vladimir Marek <Vladimir.Marek@oracle.com>
parents:
diff
changeset
|
112 |