Hello,

I have found some NULL dereferencing bugs and buffer overflows in
lynx. They cause crashes under various circumstances. Despite being
buffer overflows, I see no security impact at all. The bugs affect
at least the versions 2.8.6dev.13 and 2.8.5. All patches are made
against 2.8.6dev.13.


1) NULL dereferencing crash with unexpected data from Gopher server

I have attached a fake Gopher server, lynx-gopher-crash.pl, that
illustrates this issue. Run it, connect to it with lynx (lynx
gopher://fake.server), select the Search menu item, press s, search
for something.. notice how lynx crashes.

The attached patch lynx.gophercrash.patch corrects this bug.


2) Buffer overflow when handling overly long prefix/suffix strings
in lynx.cfg

You can test this issue by applying the lynxcfg.prefixsuffix.patch
file to lynx.cfg and then using lynx to connect to a host with no
dots (lynx a).. notice how lynx crashes.

The attached patch lynx.prefixsuffixcrash.patch corrects this bug.


3) Buffer overflow when lex() parses data from files

I have attached the lynx.lexoverflow.patch file for this issue.


// Ulf Harnhammar

#!/usr/bin/perl --

# lynx-gopher-crash
# by Ulf Harnhammar in 2005
# I hereby place this program in the public domain.

use strict;
use IO::Socket;

$main::port = 70;
$main::timeout = 5;


# *** SUBROUTINES ***


sub mysend($$)
{
  my $file = shift;
  my $str = shift;

  print $file "$str\n";
  print "SENT:  $str\n";
} # sub mysend


sub myreceive($)
{
  my $file = shift;
  my $inp;

  eval
  {
    local $SIG{ALRM} = sub { die "alarm\n" };
    alarm $main::timeout;
    $inp = <$file>;
    alarm 0;
  };

  if ($@ eq "alarm\n") { $inp = ''; print "TIMED OUT\n"; }
  $inp =~ tr/\015\012\000//d;
  print "RECEIVED:  $inp\n";
  $inp;
} # sub myreceive


# *** MAIN PROGRAM ***


{
  die "usage: $0 my_own_hostname\n" unless @ARGV == 1;

  my $server = IO::Socket::INET->new( Proto     => 'tcp',
                                      LocalPort => $main::port,
                                      Listen    => SOMAXCONN,
                                      Reuse     => 1);
  die "can't set up server!\n" unless $server;


  while (my $client = $server->accept())
  {
    $client->autoflush(1);
    print 'connection from '.$client->peerhost."\n";

    my $str = myreceive($client);
    if ($str eq '')
    { mysend($client, "2Search\tsearch\t$ARGV[0]\t$main::port"); }
    else
    { mysend($client, '-a'); }

    close $client;
    print "closed\n\n\n";
  } # while client=server->accept()
}
--- WWW/Library/Implementation/HTGopher.c.old   2005-01-03 00:35:21.000000000 
+0100
+++ WWW/Library/Implementation/HTGopher.c       2005-09-24 20:39:17.046628248 
+0200
@@ -455,7 +455,7 @@ static void parse_cso(const char *arg,
     int ich;
     char line[BIG];
     char *p = line;
-    char *second_colon, last_char = '\0';
+    char *first_colon, *second_colon, last_char = '\0';
     const char *title;
 
     START(HTML_HEAD);
@@ -524,7 +524,11 @@ static void parse_cso(const char *arg,
                /*
                 * Find the second_colon.
                 */
-               second_colon = strchr(strchr(p, ':') + 1, ':');
+               second_colon = NULL;
+               first_colon = strchr(p, ':');
+               if (first_colon != NULL) {
+                       second_colon = strchr(first_colon + 1, ':');
+               }
 
                if (second_colon != NULL) {     /* error check */
 
--- lynx.cfg.old        2004-12-30 13:11:59.000000000 +0100
+++ lynx.cfg    2005-09-25 00:43:49.853694800 +0200
@@ -626,8 +626,8 @@
 # and use "http://"; as the default (e.g., gopher.wfbr.edu or gopher.wfbr.
 # will be made gopher://gopher.wfbr.edu).
 #
-#URL_DOMAIN_PREFIXES:www.
-#URL_DOMAIN_SUFFIXES:.com,.edu,.net,.org
+URL_DOMAIN_PREFIXES:UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU.
+URL_DOMAIN_SUFFIXES:.com,.edu,.net,.UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU,.org
 
 
 .h2 FORMS_OPTIONS
--- src/LYUtils.c.old   2005-06-03 00:36:59.000000000 +0200
+++ src/LYUtils.c       2005-09-25 00:53:39.621036536 +0200
@@ -4368,6 +4368,7 @@ BOOLEAN LYExpandHostForURL(char **Alloca
     char DomainPrefix[80];
     const char *StartP, *EndP;
     char DomainSuffix[80];
+    unsigned int fixcount;
     const char *StartS, *EndS;
     char *Str = NULL, *StrColon = NULL, *MsgStr = NULL;
     char *Host = NULL, *HostColon = NULL, *host = NULL;
@@ -4521,7 +4522,10 @@ BOOLEAN LYExpandHostForURL(char **Alloca
     while (*EndP && !WHITE(*EndP) && *EndP != ',') {
        EndP++;                 /* Find separator */
     }
-    LYstrncpy(DomainPrefix, StartP, (EndP - StartP));
+    fixcount = EndP - StartP;
+    if (fixcount > 79)
+        fixcount = 79;
+    LYstrncpy(DomainPrefix, StartP, fixcount);
 
     /*
      * Test each prefix with each suffix.  - FM
@@ -4541,7 +4545,10 @@ BOOLEAN LYExpandHostForURL(char **Alloca
        while (*EndS && !WHITE(*EndS) && *EndS != ',') {
            EndS++;             /* Find separator */
        }
-       LYstrncpy(DomainSuffix, StartS, (EndS - StartS));
+       fixcount = EndS - StartS;
+       if (fixcount > 79)
+           fixcount = 79;
+       LYstrncpy(DomainSuffix, StartS, fixcount);
 
        /*
         * Create domain names and do DNS tests.  - FM
@@ -4597,7 +4604,10 @@ BOOLEAN LYExpandHostForURL(char **Alloca
                while (*EndS && !WHITE(*EndS) && *EndS != ',') {
                    EndS++;     /* Find separator */
                }
-               LYstrncpy(DomainSuffix, StartS, (EndS - StartS));
+               fixcount = EndS - StartS;
+               if (fixcount > 79)
+                   fixcount = 79;
+               LYstrncpy(DomainSuffix, StartS, fixcount);
            }
        } while ((GotHost == FALSE) && (*DomainSuffix != '\0'));
 
@@ -4613,7 +4623,10 @@ BOOLEAN LYExpandHostForURL(char **Alloca
            while (*EndP && !WHITE(*EndP) && *EndP != ',') {
                EndP++;         /* Find separator */
            }
-           LYstrncpy(DomainPrefix, StartP, (EndP - StartP));
+           fixcount = EndP - StartP;
+           if (fixcount > 79)
+               fixcount = 79;
+           LYstrncpy(DomainPrefix, StartP, fixcount);
        }
     } while ((GotHost == FALSE) && (*DomainPrefix != '\0'));
 
--- WWW/Library/Implementation/HTLex.c.old      2004-11-07 18:43:13.000000000 
+0100
+++ WWW/Library/Implementation/HTLex.c  2005-09-25 01:19:13.153904104 +0200
@@ -97,7 +97,8 @@ LexItem lex(FILE *fp)
                }
            break;
        default:
-           HTlex_buffer[lex_cnt++] = (char) ch;
+           if (lex_cnt < 39)
+               HTlex_buffer[lex_cnt++] = (char) ch;
            HTlex_buffer[lex_cnt] = '\0';
            if ('*' == ch)
                lex_template = YES;
_______________________________________________
Lynx-dev mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/lynx-dev

Reply via email to