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