The debian-private mailing list leak, part 1. Volunteers have complained about Blackmail. Lynchings. Character assassination. Defamation. Cyberbullying. Volunteers who gave many years of their lives are picked out at random for cruel social experiments. The former DPL's girlfriend Molly de Blanc is given volunteers to experiment on for her crazy talks. These volunteers never consented to be used like lab rats. We don't either. debian-private can no longer be a safe space for the cabal. Let these monsters have nowhere to hide. Volunteers are not disposable. We stand with the victims.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Perl security hole (suid buffer overrun problem in 5.003)



The CERT Coordination Center has received reports of a buffer overflow
condition in suidperl built from Perl 4.n and Perl 5.n distributions on UNIX
systems. By calling this program with appropriately crafted parameters,
unauthorized local users can execute arbitrary commands as root.


     There is a buffer overflow condition in suidperl built from Perl 4.n and
     Perl 5.n distributions earlier than version 5.004. If this program is
     called with appropriately crafted parameters, an attacker can execute
     arbitrary commands as root.


Can you let me know if you are vulnerable, if you are shipping a fixed
5.003 (patch below if you need to fix it) or 5.004 which isnt vulnerable.
Target date for release is Friday.

Appendix B - Source Code Patch Information

The following patch information has been supplied by Chip Salzenberg. If you
built suidperl or sperl from 5.003 source code, we encouraged you to apply
this patch (see the explanation in Section III.C above).


Patch follows.

--------------------------------------------------------------------------

Index: patchlevel.h
***************
*** 41,42 ****
--- 41,43 ----
+ 	,"SUIDBUF - Buffer overflow fixes for suidperl security"
  	,NULL
  };

Index: perl.c
*************** char *s;
*** 1212,1216 ****
  #  endif
  #endif
! 	fputs("\n\t+ suidperl security patch", stdout);
  	fputs("\n\nCopyright 1987-1996, Larry Wall\n",stdout);
  #ifdef MSDOS
--- 1212,1216 ----
  #  endif
  #endif
! 	fputs("\n\t+ two suidperl security patches", stdout);
  	fputs("\n\nCopyright 1987-1996, Larry Wall\n",stdout);
  #ifdef MSDOS

Index: gv.c
*************** gv_fetchfile(name)
*** 59,67 ****
  char *name;
  {
!     char tmpbuf[1200];
      GV *gv;
  
!     sprintf(tmpbuf,"::_<%s", name);
      gv = gv_fetchpv(tmpbuf, TRUE, SVt_PVGV);
      sv_setpv(GvSV(gv), name);
      if (*name == '/' && (instr(name,"/lib/") || instr(name,".pm")))
--- 59,80 ----
  char *name;
  {
!     char smallbuf[256];
!     char *tmpbuf;
!     STRLEN tmplen;
      GV *gv;
  
!     tmplen = strlen(name) + 4;
!     if (tmplen < sizeof smallbuf)
! 	tmpbuf = smallbuf;
!     else
! 	New(603, tmpbuf, tmplen + 1, char);
!     tmpbuf[0] = ':';
!     tmpbuf[1] = ':';
!     tmpbuf[2] = '_';
!     tmpbuf[3] = '<';
!     strcpy(tmpbuf + 4, name);
      gv = gv_fetchpv(tmpbuf, TRUE, SVt_PVGV);
+     if (tmpbuf != smallbuf)
+ 	Safefree(tmpbuf);
      sv_setpv(GvSV(gv), name);
      if (*name == '/' && (instr(name,"/lib/") || instr(name,".pm")))

Index: toke.c
*************** static char *scan_const _((char *start))
*** 22,26 ****
  static char *scan_formline _((char *s));
  static char *scan_heredoc _((char *s));
! static char *scan_ident _((char *s, char *send, char *dest, I32 ck_uni));
  static char *scan_inputsymbol _((char *start));
  static char *scan_pat _((char *start));
--- 22,27 ----
  static char *scan_formline _((char *s));
  static char *scan_heredoc _((char *s));
! static char *scan_ident _((char *s, char *send, char *dest, STRLEN destlen,
! 			   I32 ck_uni));
  static char *scan_inputsymbol _((char *start));
  static char *scan_pat _((char *start));
*************** static char *scan_str _((char *start));
*** 28,32 ****
  static char *scan_subst _((char *start));
  static char *scan_trans _((char *start));
! static char *scan_word _((char *s, char *dest, int allow_package, STRLEN *slp));
  static char *skipspace _((char *s));
  static void checkcomma _((char *s, char *name, char *what));
--- 29,34 ----
  static char *scan_subst _((char *start));
  static char *scan_trans _((char *start));
! static char *scan_word _((char *s, char *dest, STRLEN destlen,
! 			  int allow_package, STRLEN *slp));
  static char *skipspace _((char *s));
  static void checkcomma _((char *s, char *name, char *what));
*************** static char * filter_gets _((SV *sv, FIL
*** 47,50 ****
--- 49,54 ----
  static void restore_rsfp _((void *f));
  
+ static char too_long[] = "Identifier too long";
+ 
  /* The following are arranged oddly so that the guard on the switch statement
   * can get by with a single comparison (if the compiler is smart enough).
*************** int allow_tick;
*** 475,479 ****
  	(allow_tick && *s == '\'') )
      {
! 	s = scan_word(s, tokenbuf, allow_pack, &len);
  	if (check_keyword && keyword(tokenbuf, len))
  	    return start;
--- 479,483 ----
  	(allow_tick && *s == '\'') )
      {
! 	s = scan_word(s, tokenbuf, sizeof tokenbuf, allow_pack, &len);
  	if (check_keyword && keyword(tokenbuf, len))
  	    return start;
*************** register char *s;
*** 847,851 ****
  	unsigned char un_char = 0, last_un_char;
  	char *send = strchr(s,']');
! 	char tmpbuf[512];
  
  	if (!send)		/* has to be an expression */
--- 851,855 ----
  	unsigned char un_char = 0, last_un_char;
  	char *send = strchr(s,']');
! 	char tmpbuf[sizeof tokenbuf * 4];
  
  	if (!send)		/* has to be an expression */
*************** register char *s;
*** 872,876 ****
  		weight -= seen[un_char] * 10;
  		if (isALNUM(s[1])) {
! 		    scan_ident(s,send,tmpbuf,FALSE);
  		    if ((int)strlen(tmpbuf) > 1 && gv_fetchpv(tmpbuf,FALSE, SVt_PV))
  			weight -= 100;
--- 876,880 ----
  		weight -= seen[un_char] * 10;
  		if (isALNUM(s[1])) {
! 		    scan_ident(s, send, tmpbuf, sizeof tmpbuf, FALSE);
  		    if ((int)strlen(tmpbuf) > 1 && gv_fetchpv(tmpbuf,FALSE, SVt_PV))
  			weight -= 100;
*************** GV *gv;
*** 942,946 ****
  {
      char *s = start + (*start == '$');
!     char tmpbuf[1024];
      STRLEN len;
      GV* indirgv;
--- 946,950 ----
  {
      char *s = start + (*start == '$');
!     char tmpbuf[sizeof tokenbuf];
      STRLEN len;
      GV* indirgv;
*************** GV *gv;
*** 952,956 ****
  	    gv = 0;
      }
!     s = scan_word(s, tmpbuf, TRUE, &len);
      if (*start == '$') {
  	if (gv || last_lop_op == OP_PRINT || isUPPER(*tokenbuf))
--- 956,960 ----
  	    gv = 0;
      }
!     s = scan_word(s, tmpbuf, sizeof tmpbuf, TRUE, &len);
      if (*start == '$') {
  	if (gv || last_lop_op == OP_PRINT || isUPPER(*tokenbuf))
*************** yylex()
*** 1629,1633 ****
      case '*':
  	if (expect != XOPERATOR) {
! 	    s = scan_ident(s, bufend, tokenbuf, TRUE);
  	    expect = XOPERATOR;
  	    force_ident(tokenbuf, '*');
--- 1633,1637 ----
      case '*':
  	if (expect != XOPERATOR) {
! 	    s = scan_ident(s, bufend, tokenbuf, sizeof tokenbuf, TRUE);
  	    expect = XOPERATOR;
  	    force_ident(tokenbuf, '*');
*************** yylex()
*** 1645,1649 ****
      case '%':
  	if (expect != XOPERATOR) {
! 	    s = scan_ident(s, bufend, tokenbuf + 1, TRUE);
  	    if (tokenbuf[1]) {
  		expect = XOPERATOR;
--- 1649,1653 ----
      case '%':
  	if (expect != XOPERATOR) {
! 	    s = scan_ident(s, bufend, tokenbuf + 1, sizeof tokenbuf - 1, TRUE);
  	    if (tokenbuf[1]) {
  		expect = XOPERATOR;
*************** yylex()
*** 1748,1752 ****
  		s++;
  	    if (s < bufend && isALPHA(*s)) {
! 		d = scan_word(s, tokenbuf, FALSE, &len);
  		while (d < bufend && (*d == ' ' || *d == '\t'))
  		    d++;
--- 1752,1756 ----
  		s++;
  	    if (s < bufend && isALPHA(*s)) {
! 		d = scan_word(s, tokenbuf, sizeof tokenbuf, FALSE, &len);
  		while (d < bufend && (*d == ' ' || *d == '\t'))
  		    d++;
*************** yylex()
*** 1847,1851 ****
  	}
  
! 	s = scan_ident(s-1, bufend, tokenbuf, TRUE);
  	if (*tokenbuf) {
  	    expect = XOPERATOR;
--- 1851,1855 ----
  	}
  
! 	s = scan_ident(s - 1, bufend, tokenbuf, sizeof tokenbuf, TRUE);
  	if (*tokenbuf) {
  	    expect = XOPERATOR;
*************** yylex()
*** 1956,1960 ****
      case '$':
  	if (s[1] == '#'  && (isALPHA(s[2]) || strchr("_{$:", s[2]))) {
! 	    s = scan_ident(s+1, bufend, tokenbuf+1, FALSE);
  	    if (expect == XOPERATOR) {
  		if (lex_formbrack && lex_brackets == lex_formbrack) {
--- 1960,1965 ----
      case '$':
  	if (s[1] == '#'  && (isALPHA(s[2]) || strchr("_{$:", s[2]))) {
! 	    s = scan_ident(s + 1, bufend, tokenbuf + 1, sizeof tokenbuf - 1,
! 			   FALSE);
  	    if (expect == XOPERATOR) {
  		if (lex_formbrack && lex_brackets == lex_formbrack) {
*************** yylex()
*** 1982,1986 ****
  	    TOKEN(DOLSHARP);
  	}
! 	s = scan_ident(s, bufend, tokenbuf+1, FALSE);
  	if (expect == XOPERATOR) {
  	    if (lex_formbrack && lex_brackets == lex_formbrack) {
--- 1987,1991 ----
  	    TOKEN(DOLSHARP);
  	}
! 	s = scan_ident(s, bufend, tokenbuf + 1, sizeof tokenbuf - 1, FALSE);
  	if (expect == XOPERATOR) {
  	    if (lex_formbrack && lex_brackets == lex_formbrack) {
*************** yylex()
*** 2016,2024 ****
  		if (*s == '{' && strEQ(tokenbuf, "$SIG") &&
  		  (t = strchr(s,'}')) && (t = strchr(t,'='))) {
! 		    char tmpbuf[1024];
  		    STRLEN len;
  		    for (t++; isSPACE(*t); t++) ;
  		    if (isIDFIRST(*t)) {
! 			t = scan_word(t, tmpbuf, TRUE, &len);
  			if (*t != '(' && perl_get_cv(tmpbuf, FALSE))
  			    warn("You need to quote \"%s\"", tmpbuf);
--- 2021,2029 ----
  		if (*s == '{' && strEQ(tokenbuf, "$SIG") &&
  		  (t = strchr(s,'}')) && (t = strchr(t,'='))) {
! 		    char tmpbuf[sizeof tokenbuf];
  		    STRLEN len;
  		    for (t++; isSPACE(*t); t++) ;
  		    if (isIDFIRST(*t)) {
! 			t = scan_word(t, tmpbuf, sizeof tmpbuf, TRUE, &len);
  			if (*t != '(' && perl_get_cv(tmpbuf, FALSE))
  			    warn("You need to quote \"%s\"", tmpbuf);
*************** yylex()
*** 2093,2097 ****
  
      case '@':
! 	s = scan_ident(s, bufend, tokenbuf+1, FALSE);
  	if (expect == XOPERATOR)
  	    no_op("Array",s);
--- 2098,2102 ----
  
      case '@':
! 	s = scan_ident(s, bufend, tokenbuf + 1, sizeof tokenbuf - 1, FALSE);
  	if (expect == XOPERATOR)
  	    no_op("Array",s);
*************** yylex()
*** 2129,2133 ****
  			: !GvHV(gv) )))
  	    {
! 		char tmpbuf[1024];
  		sprintf(tmpbuf, "Literal @%s now requires backslash",tokenbuf+1);
  		yyerror(tmpbuf);
--- 2134,2138 ----
  			: !GvHV(gv) )))
  	    {
! 		char tmpbuf[sizeof tokenbuf + 40];
  		sprintf(tmpbuf, "Literal @%s now requires backslash",tokenbuf+1);
  		yyerror(tmpbuf);
*************** yylex()
*** 2293,2297 ****
        keylookup:
  	bufptr = s;
! 	s = scan_word(s, tokenbuf, FALSE, &len);
  	
  	if (*s == ':' && s[1] == ':' && strNE(tokenbuf, "CORE"))
--- 2298,2302 ----
        keylookup:
  	bufptr = s;
! 	s = scan_word(s, tokenbuf, sizeof tokenbuf, FALSE, &len);
  	
  	if (*s == ':' && s[1] == ':' && strNE(tokenbuf, "CORE"))
*************** yylex()
*** 2338,2342 ****
  
  		if (*s == '\'' || *s == ':' && s[1] == ':') {
! 		    s = scan_word(s, tokenbuf + len, TRUE, &len);
  		    if (!len)
  			croak("Bad name after %s::", tokenbuf);
--- 2343,2348 ----
  
  		if (*s == '\'' || *s == ':' && s[1] == ':') {
! 		    s = scan_word(s, tokenbuf + len, sizeof tokenbuf - len,
! 				  TRUE, &len);
  		    if (!len)
  			croak("Bad name after %s::", tokenbuf);
*************** yylex()
*** 2557,2561 ****
  		s += 2;
  		d = s;
! 		s = scan_word(s, tokenbuf, FALSE, &len);
  		tmp = keyword(tokenbuf, len);
  		if (tmp < 0)
--- 2563,2567 ----
  		s += 2;
  		d = s;
! 		s = scan_word(s, tokenbuf, sizeof tokenbuf, FALSE, &len);
  		tmp = keyword(tokenbuf, len);
  		if (tmp < 0)
*************** yylex()
*** 3244,3250 ****
  
  	    if (isIDFIRST(*s) || *s == '\'' || *s == ':') {
! 		char tmpbuf[128];
  		expect = XBLOCK;
! 		d = scan_word(s, tmpbuf, TRUE, &len);
  		if (strchr(tmpbuf, ':'))
  		    sv_setpv(subname, tmpbuf);
--- 3250,3256 ----
  
  	    if (isIDFIRST(*s) || *s == '\'' || *s == ':') {
! 		char tmpbuf[sizeof tokenbuf];
  		expect = XBLOCK;
! 		d = scan_word(s, tmpbuf, sizeof tmpbuf, TRUE, &len);
  		if (strchr(tmpbuf, ':'))
  		    sv_setpv(subname, tmpbuf);
*************** char *what;
*** 4091,4102 ****
  
  static char *
! scan_word(s, dest, allow_package, slp)
  register char *s;
  char *dest;
  int allow_package;
  STRLEN *slp;
  {
      register char *d = dest;
      for (;;) {
  	if (isALNUM(*s))
  	    *d++ = *s++;
--- 4097,4112 ----
  
  static char *
! scan_word(s, dest, destlen, allow_package, slp)
  register char *s;
  char *dest;
+ STRLEN destlen;
  int allow_package;
  STRLEN *slp;
  {
      register char *d = dest;
+     register char *e = d + destlen - 3;  /* two-character token, ending NUL */
      for (;;) {
+ 	if (d >= e)
+ 	    croak(too_long);
  	if (isALNUM(*s))
  	    *d++ = *s++;
*************** STRLEN *slp;
*** 4119,4129 ****
  
  static char *
! scan_ident(s,send,dest,ck_uni)
  register char *s;
  register char *send;
  char *dest;
  I32 ck_uni;
  {
      register char *d;
      char *bracket = 0;
      char funny = *s++;
--- 4129,4141 ----
  
  static char *
! scan_ident(s, send, dest, destlen, ck_uni)
  register char *s;
  register char *send;
  char *dest;
+ STRLEN destlen;
  I32 ck_uni;
  {
      register char *d;
+     register char *e;
      char *bracket = 0;
      char funny = *s++;
*************** I32 ck_uni;
*** 4134,4143 ****
  	s = skipspace(s);
      d = dest;
      if (isDIGIT(*s)) {
! 	while (isDIGIT(*s))
  	    *d++ = *s++;
      }
      else {
  	for (;;) {
  	    if (isALNUM(*s))
  		*d++ = *s++;
--- 4146,4161 ----
  	s = skipspace(s);
      d = dest;
+     e = d + destlen - 3;	/* two-character token, ending NUL */
      if (isDIGIT(*s)) {
! 	while (isDIGIT(*s)) {
! 	    if (d >= e)
! 		croak(too_long);
  	    *d++ = *s++;
+ 	}
      }
      else {
  	for (;;) {
+ 	    if (d >= e)
+ 		croak(too_long);
  	    if (isALNUM(*s))
  		*d++ = *s++;

--------------------------------------------------------------------------

End of patch.


--
TO UNSUBSCRIBE FROM THIS MAILING LIST: e-mail the word "unsubscribe" to
debian-private-request@lists.debian.org . 
Trouble?  e-mail to templin@bucknell.edu .