Date: Sat, 2 Aug 1997 15:23:06 +0200 From: j@uriah.heep.sax.de (J Wunsch) To: ru@ucb.crimea.ua (Ruslan Ermilov) Cc: jkh@time.cdrom.com, freebsd-bugs@FreeBSD.ORG, imp@village.org Subject: Re: CERT Advisory CA-97.17 - Vulnerability in suidperl (sperl) question... Message-ID: <19970802152306.IZ53286@uriah.heep.sax.de> In-Reply-To: <199708021140.OAA07494@relay.ucb.crimea.ua>; from Ruslan Ermilov on Aug 2, 1997 14:40:38 %2B0300 References: <199708021140.OAA07494@relay.ucb.crimea.ua>
next in thread | previous in thread | raw e-mail | index | archive | help
As Ruslan Ermilov wrote: > As I know from my up-to-date CVS tree, FreeBSD Project didn't > anything to solve the problem described in CERT Advisory CA-97.17 - > Vulnerability in suidperl. That's not fully right. If you read Warner's name in the advisory, it shouldn't surprise you too much to see: revision 1.3 date: 1997/05/22 21:40:08; author: imp; state: Exp; lines: +5 -2 Fix buffer overload that might lead to root. (In Perl4, that's in stab.c.) The problem in toke.c was still unfixed. Below's a patch (basically the patch from the CA, adapted for Perl4). Warner, can you please review it? > I think you should at least make /usr/bin/suidperl not setuid in the > -stable and -current. That would be pointless. ``Your editor has a problem with storing files. Please, disable the feature to store files in the default distribution.'' If suidperl cannot be trusted, it's pointless to have it. > What is the reason why you can't upgrade perl ... Because nobody could come up yet with a good way to do it so that the Perl in the base distribution won't add more bloat (i.e., unnecessary modules) than Perl4 does already account for. Also note that this should in the end go hand in hand with moving out all the other stuff to the ports collection, so you can upgrade Perl5 to the full set by installing the port (without duplicating what's already in the base system, if possible). Index: /usr/src/gnu/usr.bin/perl/perl/consarg.c =================================================================== RCS file: /home/cvs/src/gnu/usr.bin/perl/perl/consarg.c,v retrieving revision 1.3 diff -u -u -r1.3 consarg.c --- consarg.c 1995/05/30 05:02:57 1.3 +++ consarg.c 1997/08/02 13:19:49 @@ -1240,7 +1240,7 @@ while (*s) { if (*s == '$' && s[1]) { - s = scanident(s,send,tokenbuf); + s = scanident(s,send,tokenbuf,sizeof tokenbuf); stab = stabent(tokenbuf,TRUE); if (marking) stab_lastexpr(stab) = exprnum; Index: /usr/src/gnu/usr.bin/perl/perl/str.c =================================================================== RCS file: /home/cvs/src/gnu/usr.bin/perl/perl/str.c,v retrieving revision 1.2 diff -u -u -r1.2 str.c --- str.c 1995/05/30 05:03:21 1.2 +++ str.c 1997/08/02 13:20:17 @@ -1027,7 +1027,7 @@ t = s; if (*s == '$' && s[1] == '#' && (isALPHA(s[2]) || s[2] == '_')) s++; - s = scanident(s,send,tokenbuf); + s = scanident(s,send,tokenbuf,sizeof tokenbuf); if (*t == '@' && (!(stab = stabent(tokenbuf,FALSE)) || (*s == '{' ? !stab_xhash(stab) : !stab_xarray(stab)) )) { @@ -1061,7 +1061,7 @@ case '@': case '&': case '*': - s = scanident(s,send,tokenbuf); + s = scanident(s,send,tokenbuf,sizeof tokenbuf); continue; case '\'': case '"': @@ -1115,7 +1115,7 @@ case '$': weight -= seen[un_char] * 10; if (isALNUM(d[1])) { - d = scanident(d,s,tokenbuf); + d = scanident(d,s,tokenbuf,sizeof tokenbuf); if (stabent(tokenbuf,FALSE)) weight -= 100; else Index: /usr/src/gnu/usr.bin/perl/perl/toke.c =================================================================== RCS file: /home/cvs/src/gnu/usr.bin/perl/perl/toke.c,v retrieving revision 1.2 diff -u -u -r1.2 toke.c --- toke.c 1995/05/30 05:03:26 1.2 +++ toke.c 1997/08/02 13:21:07 @@ -518,7 +518,7 @@ case '*': if (expectterm) { check_uni(); - s = scanident(s,bufend,tokenbuf); + s = scanident(s,bufend,tokenbuf,sizeof tokenbuf); yylval.stabval = stabent(tokenbuf,TRUE); TERM(STAR); } @@ -532,7 +532,7 @@ if (expectterm) { if (!isALPHA(s[1])) check_uni(); - s = scanident(s,bufend,tokenbuf); + s = scanident(s,bufend,tokenbuf,sizeof tokenbuf); yylval.stabval = hadd(stabent(tokenbuf,TRUE)); TERM(HSH); } @@ -650,12 +650,12 @@ case '$': if (s[1] == '#' && (isALPHA(s[2]) || s[2] == '_')) { s++; - s = scanident(s,bufend,tokenbuf); + s = scanident(s,bufend,tokenbuf,sizeof tokenbuf); yylval.stabval = aadd(stabent(tokenbuf,TRUE)); TERM(ARYLEN); } d = s; - s = scanident(s,bufend,tokenbuf); + s = scanident(s,bufend,tokenbuf,sizeof tokenbuf); if (reparse) { /* turn ${foo[bar]} into ($foo[bar]) */ do_reparse: s[-1] = ')'; @@ -683,7 +683,7 @@ case '@': d = s; - s = scanident(s,bufend,tokenbuf); + s = scanident(s,bufend,tokenbuf,sizeof tokenbuf); if (reparse) goto do_reparse; yylval.stabval = aadd(stabent(tokenbuf,TRUE)); @@ -1542,24 +1542,33 @@ } char * -scanident(s,send,dest) +scanident(s,send,dest,destlen) register char *s; register char *send; char *dest; +STRLEN destlen; { register char *d; + register char *e; int brackets = 0; reparse = Nullch; s++; d = dest; + e = d + destlen - 3; /* two-character token, ending NUL */ if (isDIGIT(*s)) { - while (isDIGIT(*s)) - *d++ = *s++; + while (isDIGIT(*s)) { + if (d >= e) + fatal("Identifier too long"); + *d++ = *s++; + } } else { - while (isALNUM(*s) || *s == '\'') + while (isALNUM(*s) || *s == '\'') { + if (d >= e) + fatal("Identifier too long"); *d++ = *s++; + } } while (d > dest+1 && d[-1] == '\'') d--,s--; -- cheers, J"org joerg_wunsch@uriah.heep.sax.de -- http://www.sax.de/~joerg/ -- NIC: JW11-RIPE Never trust an operating system you don't have sources for. ;-)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19970802152306.IZ53286>