laforge has submitted this change. ( https://gerrit.osmocom.org/c/dahdi-linux/+/27806 )
Change subject: Fix NULL pointer dereference for pseudo channels ......................................................................
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
Change-Id: I747a696c9a5865c11461b6357a10346a8d0d1621 Closes: OS#5531 --- M drivers/dahdi/dahdi-base.c 1 file changed, 3 insertions(+), 3 deletions(-)
Approvals: Jenkins Builder: Verified laforge: Looks good to me, approved
diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c index 96e4afd..2b6256b 100644 --- a/drivers/dahdi/dahdi-base.c +++ b/drivers/dahdi/dahdi-base.c @@ -9203,7 +9203,7 @@ 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 */ @@ -9375,7 +9375,7 @@ 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); } @@ -9443,7 +9443,7 @@ { 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); }