From: root Date: Sun, 8 Jan 2006 08:43:11 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://git.openbox.org/?a=commitdiff_plain;h=3ab3d5626b1ff2091c1c28dd083ab049cceed760;p=dana%2Furxvt.git *** empty log message *** --- diff --git a/Changes b/Changes index 8c990d31..1e4f5f0e 100644 --- a/Changes +++ b/Changes @@ -10,7 +10,6 @@ WISH: just for fun, do shade and tint with XRender. WISH: support tex fonts TODO: document transient_for, vt and the grab etc. functionality -TODO: add warning about perl interpreter and setuid/setgid - perl: implement additional hook: line_update, add_lines. - perl: urxvt::line now can set via ->t and ->r. @@ -19,6 +18,8 @@ TODO: add warning about perl interpreter and setuid/setgid - perl: much increased functionality, better overlays, popup support and much much more. - perl: anyevent support. + - perl: run tainted and ignore perl-eval/perl-lib if installed + setuid/setgid. - free the resource database: this plugs a massive memory hole. as a side effect, it also gets rid of XGetDefault calls. - free one of the cursors, fixes a small memory leaks. diff --git a/doc/rxvt.1.pod b/doc/rxvt.1.pod index 9fd984ce..665a003a 100644 --- a/doc/rxvt.1.pod +++ b/doc/rxvt.1.pod @@ -1105,15 +1105,17 @@ all instances, while B is used for specific instances. =item B: I -Perl code to be evaluated when all extensions have been registered. See the -@@RXVT_NAME@@perl(3) manpage. +Perl code to be evaluated when all extensions have been registered. See +the @@RXVT_NAME@@perl(3) manpage. Due to security reasons, this resource +will be ignored when running setuid/setgid. =item B: I Colon-separated list of additional directories that hold extension scripts. When looking for extensions specified by the C resource, @@RXVT_NAME@@ will first look in these directories and then in -F<@@RXVT_LIBDIR@@/urxvt/perl/>. +F<@@RXVT_LIBDIR@@/urxvt/perl/>. Due to security reasons, this resource +will be ignored when running setuid/setgid. See the @@RXVT_NAME@@perl(3) manpage. diff --git a/src/main.C b/src/main.C index 97cac986..90ea32c4 100644 --- a/src/main.C +++ b/src/main.C @@ -48,6 +48,11 @@ # include #endif +#if (defined(HAVE_SETEUID) || defined(HAVE_SETREUID)) && !defined(__CYGWIN32__) +static uid_t saved_euid; +static gid_t saved_egid; +#endif + vector rxvt_term::termlist; static char curlocale[128], savelocale[128]; @@ -499,7 +504,24 @@ rxvt_term::init (int argc, const char *const *argv) || (rs[Rs_perl_ext_2] && *rs[Rs_perl_ext_2]) || (rs[Rs_perl_eval] && *rs[Rs_perl_eval])) { - rxvt_perl.init (); + bool tainted = false; + +#if (defined(HAVE_SETEUID) || defined(HAVE_SETREUID)) && !defined(__CYGWIN32__) + // ignore some perl-related arguments if some bozo installed us set[ug]id + if (getuid () != saved_euid || getgid () != saved_egid) + { + tainted = true; + + if ((rs[Rs_perl_lib] && *rs[Rs_perl_lib]) + || (rs[Rs_perl_eval] && *rs[Rs_perl_eval])) + { + rxvt_warn ("running with elevated privileges: ignoring perl-lib and perl-eval.\n"); + rs[Rs_perl_lib] = 0; + rs[Rs_perl_eval] = "our $tainted = 1"; + } + } +#endif + rxvt_perl.init (tainted); HOOK_INVOKE ((this, HOOK_INIT, DT_END)); } #endif @@ -667,11 +689,6 @@ rxvt_realloc (void *ptr, size_t size) void rxvt_privileges (rxvt_privaction action) { -#if (defined(HAVE_SETEUID) || defined(HAVE_SETREUID)) && !defined(__CYGWIN32__) - static uid_t euid; - static gid_t egid; -#endif - #if ! defined(__CYGWIN32__) # if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) /* setreuid () is the poor man's setuid (), seteuid () */ @@ -691,12 +708,12 @@ rxvt_privileges (rxvt_privaction action) setegid (getgid ()); break; case SAVE: - euid = geteuid (); - egid = getegid (); + saved_euid = geteuid (); + saved_egid = getegid (); break; case RESTORE: - seteuid (euid); - setegid (egid); + seteuid (saved_euid); + setegid (saved_egid); break; } # else diff --git a/src/rxvtperl.h b/src/rxvtperl.h index bf69305d..747cf103 100644 --- a/src/rxvtperl.h +++ b/src/rxvtperl.h @@ -41,7 +41,7 @@ struct rxvt_perl_interp bool should_invoke[HOOK_NUM]; - void init (); + void init (bool tainted); bool invoke (rxvt_term *term, hook_type htype, ...); void line_update (rxvt_term *term); }; diff --git a/src/rxvtperl.xs b/src/rxvtperl.xs index d32ee753..530a67f7 100644 --- a/src/rxvtperl.xs +++ b/src/rxvtperl.xs @@ -51,6 +51,22 @@ ///////////////////////////////////////////////////////////////////////////// +static SV * +taint (SV *sv) +{ + SvTAINT (sv); + return sv; +} + +static SV * +taint_if (SV *sv, SV *src) +{ + if (SvTAINTED (src)) + SvTAINT (sv); + + return sv; +} + static wchar_t * sv2wcs (SV *sv) { @@ -392,19 +408,20 @@ rxvt_perl_interp::~rxvt_perl_interp () } void -rxvt_perl_interp::init () +rxvt_perl_interp::init (bool tainted) { if (!perl) { char *argv[] = { "", "-edo '" LIBDIR "/urxvt.pm' or ($@ and die $@) or exit 1", + "-T", }; perl = perl_alloc (); perl_construct (perl); - if (perl_parse (perl, xs_init, 2, argv, (char **)NULL) + if (perl_parse (perl, xs_init, 2 + !!tainted, argv, (char **)NULL) || perl_run (perl)) { rxvt_warn ("unable to initialize perl-interpreter, continuing without.\n"); @@ -475,7 +492,7 @@ rxvt_perl_interp::invoke (rxvt_term *term, hook_type htype, ...) break; case DT_STR: - XPUSHs (sv_2mortal (newSVpv (va_arg (ap, char *), 0))); + XPUSHs (taint (sv_2mortal (newSVpv (va_arg (ap, char *), 0)))); break; case DT_STR_LEN: @@ -483,7 +500,7 @@ rxvt_perl_interp::invoke (rxvt_term *term, hook_type htype, ...) char *str = va_arg (ap, char *); int len = va_arg (ap, int); - XPUSHs (sv_2mortal (newSVpvn (str, len))); + XPUSHs (taint (sv_2mortal (newSVpvn (str, len)))); } break; @@ -492,7 +509,7 @@ rxvt_perl_interp::invoke (rxvt_term *term, hook_type htype, ...) wchar_t *wstr = va_arg (ap, wchar_t *); int wlen = va_arg (ap, int); - XPUSHs (sv_2mortal (wcs2sv (wstr, wlen))); + XPUSHs (taint (sv_2mortal (wcs2sv (wstr, wlen)))); } break; @@ -816,7 +833,7 @@ rxvt_term::locale_encode (SV *str) free (wstr); - RETVAL = newSVpv (mbstr, 0); + RETVAL = taint_if (newSVpv (mbstr, 0), str); free (mbstr); } OUTPUT: @@ -833,7 +850,7 @@ rxvt_term::locale_decode (SV *octets) wchar_t *wstr = rxvt_mbstowcs (data, len); rxvt_pop_locale (); - RETVAL = wcs2sv (wstr); + RETVAL = taint_if (wcs2sv (wstr), octets); free (wstr); } OUTPUT: @@ -950,7 +967,7 @@ rxvt_term::ROW_t (int row_number, SV *new_text = 0, int start_col = 0, int start for (int col = 0; col < THIS->ncol; col++) wstr [col] = l.t [col]; - XPUSHs (sv_2mortal (wcs2sv (wstr, THIS->ncol))); + XPUSHs (taint (sv_2mortal (wcs2sv (wstr, THIS->ncol)))); delete [] wstr; } @@ -1081,7 +1098,7 @@ rxvt_term::special_encode (SV *string) rxvt_pop_locale (); - RETVAL = wcs2sv (rstr, r - rstr); + RETVAL = taint_if (wcs2sv (rstr, r - rstr), string); delete [] rstr; } @@ -1117,7 +1134,7 @@ rxvt_term::special_decode (SV *text) else *r++ = *s; - RETVAL = wcs2sv (rstr, r - rstr); + RETVAL = taint_if (wcs2sv (rstr, r - rstr), text); delete [] rstr; } @@ -1149,7 +1166,7 @@ rxvt_term::_resource (char *name, int index, SV *newval = 0) croak ("requested out-of-bound resource %s+%d,", name, index - rs->value); if (GIMME_V != G_VOID) - XPUSHs (THIS->rs [index] ? sv_2mortal (newSVpv (THIS->rs [index], 0)) : &PL_sv_undef); + XPUSHs (THIS->rs [index] ? sv_2mortal (taint (newSVpv (THIS->rs [index], 0))) : &PL_sv_undef); if (newval) { @@ -1240,7 +1257,7 @@ rxvt_term::selection (SV *newtext = 0) PPCODE: { if (GIMME_V != G_VOID) - XPUSHs (sv_2mortal (wcs2sv (THIS->selection.text, THIS->selection.len))); + XPUSHs (taint (sv_2mortal (wcs2sv (THIS->selection.text, THIS->selection.len)))); if (newtext) { diff --git a/src/urxvt.pm b/src/urxvt.pm index d64d4df3..e285d151 100644 --- a/src/urxvt.pm +++ b/src/urxvt.pm @@ -473,6 +473,8 @@ sub extension_package($) { . (do { local $/; <$fh> }) . "\n};\n1"; + $source =~ /(.*)/s and $source = $1; # untaint + eval $source or die "$path: $@"; $pkg