From 20bdb20ab83463e207f5f89c7a4889396264746a Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sat, 16 Apr 2022 13:32:57 +0200 Subject: [PATCH] Fix NULL pointer dereference for pseudo channels pseudo channels are characterized by the fact that they have their span member set to NULL. This is illustrated by the is_pseudo_chan() function. However, when using RXMIRROR/TXMIRROR, __putbuf_chunk() is called not just on the real channel, but also on the mirror (pseudo) channel. Hence, __putbuf_chunk() and friends must not dereference the ->span member without first checking that this channel actually does have a non-NULL span assigned. I originally thought that those unconditional de-references must have been introduced after the RXMIRROR/TXMIRROR was merged - but checked the git history and it seems like the bug has been present ever sicne this functionality was merged in 2010 in commit 9090c6fcd289b497e00e8e5fb9cc3546e0dfe7d6 --- drivers/dahdi/dahdi-base.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c index 6077392..f531ef8 100644 --- a/drivers/dahdi/dahdi-base.c +++ b/drivers/dahdi/dahdi-base.c @@ -9247,7 +9247,7 @@ static void __putbuf_chunk(struct dahdi_chan *ss, unsigned char *rxb, int bytes) buf[ms->readidx[ms->inreadbuf]++] = rxc; /* Pay attention to the possibility of an overrun */ if (ms->readidx[ms->inreadbuf] >= ms->blocksize) { - if (!ss->span->alarms) + if (ss->span && !ss->span->alarms) module_printk(KERN_WARNING, "HDLC Receiver overrun on channel %s (master=%s)\n", ss->name, ss->master->name); abort=DAHDI_EVENT_OVERRUN; /* Force the HDLC state back to frame-search mode */ @@ -9419,7 +9419,7 @@ that the waitqueue is empty. */ tasklet_schedule(&ms->ppp_calls); } else #endif - if (test_bit(DAHDI_FLAGBIT_OPEN, &ms->flags) && !ss->span->alarms) { + if (test_bit(DAHDI_FLAGBIT_OPEN, &ms->flags) && ss->span && !ss->span->alarms) { /* Notify the receiver... */ __qevent(ss->master, abort); } @@ -9487,7 +9487,7 @@ static void __dahdi_hdlc_abort(struct dahdi_chan *ss, int event) { if (ss->inreadbuf >= 0) ss->readidx[ss->inreadbuf] = 0; - if (test_bit(DAHDI_FLAGBIT_OPEN, &ss->flags) && !ss->span->alarms) + if (test_bit(DAHDI_FLAGBIT_OPEN, &ss->flags) && ss->span && !ss->span->alarms) __qevent(ss->master, event); } -- 2.30.2