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