Synopsis: Remote Buffer Overflow Vulnerability in BSD Line Printer Daemon
NetBSD versions: 1.4, 1.4.1, 1.4.2, 1.4.3, 1.5, 1.5.1, 1.5.2, -current
Thanks to: Jun-ichiro Hagino
Reported in NetBSD Security Advisory: NetBSD-SA2001-018

Index: displayq.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/lpr/common_source/displayq.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -c -p -r1.20 -r1.21
*** displayq.c  2001/06/25 11:04:52     1.20
--- displayq.c  2001/08/30 00:51:50     1.21
*************** extern int      users;          /* # of users in user
*** 76,83 ****
 extern uid_t  uid, euid;

 static int    col;            /* column on screen */
! static char   current[40];    /* current file being printed */
! static char   file[132];      /* print file name */
 static int    first;          /* first file in ``files'' column? */
 static int    garbage;        /* # of garbage cf files */
 static int    lflag;          /* long output option */
--- 76,83 ----
 extern uid_t  uid, euid;

 static int    col;            /* column on screen */
! static char   current[MAXPATHLEN]; /* current file being printed */
! static char   file[MAXPATHLEN]; /* print file name */
 static int    first;          /* first file in ``files'' column? */
 static int    garbage;        /* # of garbage cf files */
 static int    lflag;          /* long output option */
*************** displayq(format)
*** 100,106 ****
 {
       struct queue *q;
       int i, nitems, fd, ret;
!       char *cp;
       struct queue **queue;
       struct stat statb;
       FILE *fp;
--- 100,106 ----
 {
       struct queue *q;
       int i, nitems, fd, ret;
!       char *cp, *ecp;
       struct queue **queue;
       struct stat statb;
       FILE *fp;
*************** displayq(format)
*** 173,180 ****
               else {
                       /* get daemon pid */
                       cp = current;
!                       while ((i = getc(fp)) != EOF && i != '\n')
!                               *cp++ = i;
                       *cp = '\0';
                       i = atoi(current);
                       if (i <= 0) {
--- 173,183 ----
               else {
                       /* get daemon pid */
                       cp = current;
!                       ecp = cp + sizeof(current) - 1;
!                       while ((i = getc(fp)) != EOF && i != '\n') {
!                               if (cp < ecp)
!                                       *cp++ = i;
!                       }
                       *cp = '\0';
                       i = atoi(current);
                       if (i <= 0) {
*************** displayq(format)
*** 189,196 ****
                       } else {
                               /* read current file name */
                               cp = current;
!                               while ((i = getc(fp)) != EOF && i != '\n')
!                                       *cp++ = i;
                               *cp = '\0';
                               /*
                                * Print the status file.
--- 192,202 ----
                       } else {
                               /* read current file name */
                               cp = current;
!                               ecp = cp + sizeof(current) - 1;
!                               while ((i = getc(fp)) != EOF && i != '\n') {
!                                       if (cp < ecp)
!                                               *cp++ = i;
!                               }
                               *cp = '\0';
                               /*
                                * Print the status file.