xref: /openbsd-src/gnu/usr.bin/perl/taint.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
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 #ifdef HAS_SETEUID
17     DEBUG_u(PerlIO_printf(Perl_debug_log,
18             "%s %d %"Uid_t_f" %"Uid_t_f"\n", s, PL_tainted, PL_uid, PL_euid));
19 #endif
20 
21     if (PL_tainted) {
22 	if (!f)
23 	    f = PL_no_security;
24 	if (PL_euid != PL_uid)
25 	    ug = " while running setuid";
26 	else if (PL_egid != PL_gid)
27 	    ug = " while running setgid";
28 	else
29 	    ug = " while running with -T switch";
30 	if (!PL_unsafe)
31 	    Perl_croak(aTHX_ f, s, ug);
32 	else if (ckWARN(WARN_TAINT))
33 	    Perl_warner(aTHX_ WARN_TAINT, f, s, ug);
34     }
35 }
36 
37 void
38 Perl_taint_env(pTHX)
39 {
40     SV** svp;
41     MAGIC* mg;
42     char** e;
43     static char* misc_env[] = {
44 	"IFS",		/* most shells' inter-field separators */
45 	"CDPATH",	/* ksh dain bramage #1 */
46 	"ENV",		/* ksh dain bramage #2 */
47 	"BASH_ENV",	/* bash dain bramage -- I guess it's contagious */
48 	NULL
49     };
50 
51     if (!PL_envgv)
52 	return;
53 
54 #ifdef VMS
55     {
56     int i = 0;
57     char name[10 + TYPE_DIGITS(int)] = "DCL$PATH";
58 
59     while (1) {
60 	if (i)
61 	    (void)sprintf(name,"DCL$PATH;%d", i);
62 	svp = hv_fetch(GvHVn(PL_envgv), name, strlen(name), FALSE);
63 	if (!svp || *svp == &PL_sv_undef)
64 	    break;
65 	if (SvTAINTED(*svp)) {
66 	    TAINT;
67 	    taint_proper("Insecure %s%s", "$ENV{DCL$PATH}");
68 	}
69 	if ((mg = mg_find(*svp, 'e')) && MgTAINTEDDIR(mg)) {
70 	    TAINT;
71 	    taint_proper("Insecure directory in %s%s", "$ENV{DCL$PATH}");
72 	}
73 	i++;
74     }
75   }
76 #endif /* VMS */
77 
78     svp = hv_fetch(GvHVn(PL_envgv),"PATH",4,FALSE);
79     if (svp && *svp) {
80 	if (SvTAINTED(*svp)) {
81 	    TAINT;
82 	    taint_proper("Insecure %s%s", "$ENV{PATH}");
83 	}
84 	if ((mg = mg_find(*svp, 'e')) && MgTAINTEDDIR(mg)) {
85 	    TAINT;
86 	    taint_proper("Insecure directory in %s%s", "$ENV{PATH}");
87 	}
88     }
89 
90 #ifndef VMS
91     /* tainted $TERM is okay if it contains no metachars */
92     svp = hv_fetch(GvHVn(PL_envgv),"TERM",4,FALSE);
93     if (svp && *svp && SvTAINTED(*svp)) {
94 	STRLEN n_a;
95 	bool was_tainted = PL_tainted;
96 	char *t = SvPV(*svp, n_a);
97 	char *e = t + n_a;
98 	PL_tainted = was_tainted;
99 	if (t < e && isALNUM(*t))
100 	    t++;
101 	while (t < e && (isALNUM(*t) || *t == '-' || *t == ':'))
102 	    t++;
103 	if (t < e) {
104 	    TAINT;
105 	    taint_proper("Insecure $ENV{%s}%s", "TERM");
106 	}
107     }
108 #endif /* !VMS */
109 
110     for (e = misc_env; *e; e++) {
111 	svp = hv_fetch(GvHVn(PL_envgv), *e, strlen(*e), FALSE);
112 	if (svp && *svp != &PL_sv_undef && SvTAINTED(*svp)) {
113 	    TAINT;
114 	    taint_proper("Insecure $ENV{%s}%s", *e);
115 	}
116     }
117 }
118