This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Slight tweaks on the MM_Win32.t.
[perl5.git] / taint.c
1 /*
2  * "...we will have peace, when you and all your works have perished--and
3  * the works of your dark master to whom you would deliver us.  You are a
4  * liar, Saruman, and a corrupter of men's hearts."  --Theoden
5  */
6
7 #include "EXTERN.h"
8 #define PERL_IN_TAINT_C
9 #include "perl.h"
10
11 void
12 Perl_taint_proper(pTHX_ const char *f, const char *s)
13 {
14     char *ug;
15
16 #if defined(HAS_SETEUID) && defined(DEBUGGING)
17 #   if Uid_t_size == 1
18     {
19          UV  uid = PL_uid;
20          UV euid = PL_euid;
21
22          DEBUG_u(PerlIO_printf(Perl_debug_log,
23                                "%s %d %"UVuf" %"UVuf"\n",
24                                s, PL_tainted, uid, euid));
25     }
26 #   else
27     {
28          IV  uid = PL_uid;
29          IV euid = PL_euid;
30
31          DEBUG_u(PerlIO_printf(Perl_debug_log,
32                                "%s %d %"IVdf" %"IVdf"\n",
33                                s, PL_tainted, uid, euid));
34     }
35 #   endif
36 #endif
37
38     if (PL_tainted) {
39         if (!f)
40             f = PL_no_security;
41         if (PL_euid != PL_uid)
42             ug = " while running setuid";
43         else if (PL_egid != PL_gid)
44             ug = " while running setgid";
45         else if (PL_taint_warn)
46             ug = " while running with -t switch";
47         else
48             ug = " while running with -T switch";
49         if (PL_unsafe || PL_taint_warn) {
50             if(ckWARN(WARN_TAINT))
51                 Perl_warner(aTHX_ WARN_TAINT, f, s, ug);
52         }
53         else {
54             Perl_croak(aTHX_ f, s, ug);
55         }
56     }
57 }
58
59 void
60 Perl_taint_env(pTHX)
61 {
62     SV** svp;
63     MAGIC* mg;
64     char** e;
65     static char* misc_env[] = {
66         "IFS",          /* most shells' inter-field separators */
67         "CDPATH",       /* ksh dain bramage #1 */
68         "ENV",          /* ksh dain bramage #2 */
69         "BASH_ENV",     /* bash dain bramage -- I guess it's contagious */
70         NULL
71     };
72
73     if (!PL_envgv)
74         return;
75
76 #ifdef VMS
77     {
78     int i = 0;
79     char name[10 + TYPE_DIGITS(int)] = "DCL$PATH";
80
81     while (1) {
82         if (i)
83             (void)sprintf(name,"DCL$PATH;%d", i);
84         svp = hv_fetch(GvHVn(PL_envgv), name, strlen(name), FALSE);
85         if (!svp || *svp == &PL_sv_undef)
86             break;
87         if (SvTAINTED(*svp)) {
88             TAINT;
89             taint_proper("Insecure %s%s", "$ENV{DCL$PATH}");
90         }
91         if ((mg = mg_find(*svp, PERL_MAGIC_envelem)) && MgTAINTEDDIR(mg)) {
92             TAINT;
93             taint_proper("Insecure directory in %s%s", "$ENV{DCL$PATH}");
94         }
95         i++;
96     }
97   }
98 #endif /* VMS */
99
100     svp = hv_fetch(GvHVn(PL_envgv),"PATH",4,FALSE);
101     if (svp && *svp) {
102         if (SvTAINTED(*svp)) {
103             TAINT;
104             taint_proper("Insecure %s%s", "$ENV{PATH}");
105         }
106         if ((mg = mg_find(*svp, PERL_MAGIC_envelem)) && MgTAINTEDDIR(mg)) {
107             TAINT;
108             taint_proper("Insecure directory in %s%s", "$ENV{PATH}");
109         }
110     }
111
112 #ifndef VMS
113     /* tainted $TERM is okay if it contains no metachars */
114     svp = hv_fetch(GvHVn(PL_envgv),"TERM",4,FALSE);
115     if (svp && *svp && SvTAINTED(*svp)) {
116         STRLEN n_a;
117         bool was_tainted = PL_tainted;
118         char *t = SvPV(*svp, n_a);
119         char *e = t + n_a;
120         PL_tainted = was_tainted;
121         if (t < e && isALNUM(*t))
122             t++;
123         while (t < e && (isALNUM(*t) || *t == '-' || *t == ':'))
124             t++;
125         if (t < e) {
126             TAINT;
127             taint_proper("Insecure $ENV{%s}%s", "TERM");
128         }
129     }
130 #endif /* !VMS */
131
132     for (e = misc_env; *e; e++) {
133         svp = hv_fetch(GvHVn(PL_envgv), *e, strlen(*e), FALSE);
134         if (svp && *svp != &PL_sv_undef && SvTAINTED(*svp)) {
135             TAINT;
136             taint_proper("Insecure $ENV{%s}%s", *e);
137         }
138     }
139 }