ppp: remove ioctls that never worked and crash the kernel

Remove vestigial bits of PPP HDLC support that never worked on netbsd.
The TIOCRCVFRAME ioctl was apparently intended to be called only from
within the kernel, but nothing prevents user code from calling this ioctl
and crashing the kernel.

Reported-by: syzbot+53e4620d0d17a4dd08fa@syzkaller.appspotmail.com
Reported-by: syzbot+d3a8b784fed1e32e0768@syzkaller.appspotmail.com
Reported-by: syzbot+375bab63345a6a7a3331@syzkaller.appspotmail.com
Reported-by: syzbot+ba7ac85196274a20b54a@syzkaller.appspotmail.com
Reported-by: syzbot+57ddb63a3d1d3299ef18@syzkaller.appspotmail.com
This commit is contained in:
chs 2022-12-21 19:08:22 +00:00
parent fc887601fd
commit 238664abb5
5 changed files with 3 additions and 208 deletions

View File

@ -1267,8 +1267,6 @@ static void ioctl_table_fill() {
_(TIOCGFLAGS, WRITE, sizeof(int));
_(TIOCSFLAGS, READ, sizeof(int));
_(TIOCDCDTIMESTAMP, WRITE, struct_timeval_sz);
_(TIOCRCVFRAME, READ, sizeof(uptr));
_(TIOCXMTFRAME, READ, sizeof(uptr));
_(TIOCPTMGET, WRITE, struct_ptmget_sz);
_(TIOCGRANTPT, NONE, 0);
_(TIOCPTSNAME, WRITE, struct_ptmget_sz);

View File

@ -2341,8 +2341,6 @@ unsigned IOCTL_TIOCDRAIN = TIOCDRAIN;
unsigned IOCTL_TIOCGFLAGS = TIOCGFLAGS;
unsigned IOCTL_TIOCSFLAGS = TIOCSFLAGS;
unsigned IOCTL_TIOCDCDTIMESTAMP = TIOCDCDTIMESTAMP;
unsigned IOCTL_TIOCRCVFRAME = TIOCRCVFRAME;
unsigned IOCTL_TIOCXMTFRAME = TIOCXMTFRAME;
unsigned IOCTL_TIOCPTMGET = TIOCPTMGET;
unsigned IOCTL_TIOCGRANTPT = TIOCGRANTPT;
unsigned IOCTL_TIOCPTSNAME = TIOCPTSNAME;

View File

@ -2194,8 +2194,6 @@ extern unsigned IOCTL_TIOCDRAIN;
extern unsigned IOCTL_TIOCGFLAGS;
extern unsigned IOCTL_TIOCSFLAGS;
extern unsigned IOCTL_TIOCDCDTIMESTAMP;
extern unsigned IOCTL_TIOCRCVFRAME;
extern unsigned IOCTL_TIOCXMTFRAME;
extern unsigned IOCTL_TIOCPTMGET;
extern unsigned IOCTL_TIOCGRANTPT;
extern unsigned IOCTL_TIOCPTSNAME;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ppp_tty.c,v 1.71 2022/10/26 23:42:56 riastradh Exp $ */
/* $NetBSD: ppp_tty.c,v 1.72 2022/12/21 19:08:22 chs Exp $ */
/* Id: ppp_tty.c,v 1.3 1996/07/01 01:04:11 paulus Exp */
/*
@ -93,7 +93,7 @@
/* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ppp_tty.c,v 1.71 2022/10/26 23:42:56 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: ppp_tty.c,v 1.72 2022/12/21 19:08:22 chs Exp $");
#ifdef _KERNEL_OPT
#include "ppp.h"
@ -153,9 +153,7 @@ struct linesw ppp_disc = { /* XXX should be static */
.l_poll = ttpoll
};
static void ppprcvframe(struct ppp_softc *sc, struct mbuf *m);
static uint16_t pppfcs(uint16_t fcs, const uint8_t *cp, int len);
static void pppsyncstart(struct ppp_softc *sc);
static void pppasyncstart(struct ppp_softc *);
static void pppasyncctlp(struct ppp_softc *);
static void pppasyncrelinq(struct ppp_softc *);
@ -163,7 +161,6 @@ static void ppp_timeout(void *);
static void pppgetm(struct ppp_softc *sc);
static void pppdumpb(u_char *b, int l);
static void ppplogchar(struct ppp_softc *, int);
static void pppdumpframe(struct ppp_softc *sc, struct mbuf* m, int xmit);
/*
* Does c need to be escaped?
@ -438,10 +435,6 @@ ppptioctl(struct tty *tp, u_long cmd, void *data, int flag, struct lwp *l)
error = 0;
switch (cmd) {
case TIOCRCVFRAME:
ppprcvframe(sc,*((struct mbuf **)data));
break;
case PPPIOCSASYNCMAP:
if ((error = kauth_authorize_device_tty(l->l_cred,
KAUTH_DEVICE_TTY_PRIVSET, tp)) != 0)
@ -491,113 +484,6 @@ ppptioctl(struct tty *tp, u_long cmd, void *data, int flag, struct lwp *l)
return error;
}
/* receive a complete ppp frame from device in synchronous
* hdlc mode. caller gives up ownership of mbuf
*/
static void
ppprcvframe(struct ppp_softc *sc, struct mbuf *m)
{
int len, s;
struct mbuf *n;
u_char hdr[4];
int hlen,count;
for (n=m,len=0;n != NULL;n = n->m_next)
len += n->m_len;
if (len==0) {
m_freem(m);
return;
}
/* extract PPP header from mbuf chain (1 to 4 bytes) */
for (n=m,hlen=0;n!=NULL && hlen<sizeof(hdr);n=n->m_next) {
count = (sizeof(hdr)-hlen) < n->m_len ?
sizeof(hdr)-hlen : n->m_len;
bcopy(mtod(n,u_char*),&hdr[hlen],count);
hlen+=count;
}
s = spltty();
/* if AFCF compressed then prepend AFCF */
if (hdr[0] != PPP_ALLSTATIONS) {
if (sc->sc_flags & SC_REJ_COMP_AC) {
if (sc->sc_flags & SC_DEBUG)
printf(
"%s: garbage received: 0x%x (need 0xFF)\n",
sc->sc_if.if_xname, hdr[0]);
goto bail;
}
M_PREPEND(m,2,M_DONTWAIT);
if (m==NULL) {
splx(s);
return;
}
hdr[3] = hdr[1];
hdr[2] = hdr[0];
hdr[0] = PPP_ALLSTATIONS;
hdr[1] = PPP_UI;
len += 2;
}
/* if protocol field compressed, add MSB of protocol field = 0 */
if (hdr[2] & 1) {
/* a compressed protocol */
M_PREPEND(m,1,M_DONTWAIT);
if (m==NULL) {
splx(s);
return;
}
hdr[3] = hdr[2];
hdr[2] = 0;
len++;
}
/* valid LSB of protocol field has bit0 set */
if (!(hdr[3] & 1)) {
if (sc->sc_flags & SC_DEBUG)
printf("%s: bad protocol %x\n", sc->sc_if.if_xname,
(hdr[2] << 8) + hdr[3]);
goto bail;
}
/* packet beyond configured mru? */
if (len > sc->sc_mru + PPP_HDRLEN) {
if (sc->sc_flags & SC_DEBUG)
printf("%s: packet too big\n", sc->sc_if.if_xname);
goto bail;
}
/* add expanded 4 byte header to mbuf chain */
for (n=m,hlen=0;n!=NULL && hlen<sizeof(hdr);n=n->m_next) {
count = (sizeof(hdr)-hlen) < n->m_len ?
sizeof(hdr)-hlen : n->m_len;
bcopy(&hdr[hlen],mtod(n,u_char*),count);
hlen+=count;
}
/* if_ppp.c requires the PPP header and IP header */
/* to be contiguous */
count = len < MHLEN ? len : MHLEN;
if (m->m_len < count) {
m = m_pullup(m,count);
if (m==NULL)
goto bail;
}
sc->sc_stats.ppp_ibytes += len;
if (sc->sc_flags & SC_LOG_RAWIN)
pppdumpframe(sc,m,0);
ppppktin(sc, m, 0);
splx(s);
return;
bail:
m_freem(m);
splx(s);
}
/*
* FCS lookup table as calculated by genfcstab.
*/
@ -647,42 +533,6 @@ pppfcs(uint16_t fcs, const uint8_t *cp, int len)
return (fcs);
}
/* This gets called at splsoftnet from pppasyncstart at various times
* when there is data ready to be sent.
*/
static void
pppsyncstart(struct ppp_softc *sc)
{
struct tty *tp = (struct tty *) sc->sc_devp;
struct mbuf *m, *n;
const struct cdevsw *cdev;
int len;
for(m = sc->sc_outm;;) {
if (m == NULL) {
m = ppp_dequeue(sc); /* get new packet */
if (m == NULL)
break; /* no more packets */
if (sc->sc_flags & SC_DEBUG)
pppdumpframe(sc,m,1);
}
for(n=m,len=0;n!=NULL;n=n->m_next)
len += n->m_len;
/* call device driver IOCTL to transmit a frame */
cdev = cdevsw_lookup(tp->t_dev);
if (cdev == NULL ||
(*cdev->d_ioctl)(tp->t_dev, TIOCXMTFRAME, (void *)&m,
0, 0)) {
/* busy or error, set as current packet */
sc->sc_outm = m;
break;
}
sc->sc_outm = m = NULL;
sc->sc_stats.ppp_obytes += len;
}
}
/*
* This gets called at splsoftnet from if_ppp.c at various times
* when there is data ready to be sent.
@ -697,11 +547,6 @@ pppasyncstart(struct ppp_softc *sc)
int n, ndone, done, idle;
struct mbuf *m2;
if (sc->sc_flags & SC_SYNC){
pppsyncstart(sc);
return;
}
ttylock(tp);
idle = 0;
@ -1243,44 +1088,3 @@ pppdumpb(u_char *b, int l)
*bp = 0;
printf("%s\n", bf);
}
static void
pppdumpframe(struct ppp_softc *sc, struct mbuf *m, int xmit)
{
int i,lcount,copycount,count;
char lbuf[16];
char *data;
if (m == NULL)
return;
for(count=m->m_len,data=mtod(m,char*);m != NULL;) {
/* build a line of output */
for(lcount=0;lcount < sizeof(lbuf);lcount += copycount) {
if (!count) {
m = m->m_next;
if (m == NULL)
break;
count = m->m_len;
data = mtod(m,char*);
}
copycount = (count > sizeof(lbuf)-lcount) ?
sizeof(lbuf)-lcount : count;
bcopy(data,&lbuf[lcount],copycount);
data += copycount;
count -= copycount;
}
/* output line (hex 1st, then ascii) */
printf("%s %s:", sc->sc_if.if_xname,
xmit ? "output" : "input ");
for(i=0;i<lcount;i++)
printf("%02x ",(u_char)lbuf[i]);
for(;i<sizeof(lbuf);i++)
printf(" ");
for(i=0;i<lcount;i++)
printf("%c",(lbuf[i] >= 040 &&
lbuf[i] <= 0176) ? lbuf[i] : '.');
printf("\n");
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ttycom.h,v 1.21 2017/10/25 06:32:59 kre Exp $ */
/* $NetBSD: ttycom.h,v 1.22 2022/12/21 19:08:22 chs Exp $ */
/*-
* Copyright (c) 1982, 1986, 1990, 1993, 1994
@ -159,9 +159,6 @@ typedef char linedn_t[TTLINEDNAMELEN];
#define TIOCDCDTIMESTAMP _IOR('t', 88, struct timeval) /* get timestamp of last
* Cd rise, stamp next rise */
#define TIOCRCVFRAME _IOW('t', 69, struct mbuf *)/* data frame received */
#define TIOCXMTFRAME _IOW('t', 68, struct mbuf *)/* data frame transmit */
#define TIOCPTMGET _IOR('t', 70, struct ptmget) /* get ptys */
#define TIOCGRANTPT _IO('t', 71) /* grantpt(3) */
#define TIOCPTSNAME _IOR('t', 72, struct ptmget) /* ptsname(3) */