From b458d3c90603033918494e30e0e29cd5254dd027 Mon Sep 17 00:00:00 2001 From: mattf Date: Sat, 7 Apr 2007 16:43:47 +0000 Subject: chan variables are accessed without a lock, so they could change underneath us. Make sure we use a local variable for access to them. (#9208) git-svn-id: http://svn.digium.com/svn/zaptel/trunk@2396 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- zaptel.c | 59 +++++++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/zaptel.c b/zaptel.c index 3d27b28..c43db21 100644 --- a/zaptel.c +++ b/zaptel.c @@ -769,16 +769,19 @@ static int schluffen(wait_queue_head_t *q) if (!signal_pending(current)) schedule(); current->state = TASK_RUNNING; remove_wait_queue(q, &wait); - if (signal_pending(current)) return -ERESTARTSYS; + if (signal_pending(current)) { + printk(KERN_WARNING "zaptel.c:%d (pid %d: %s) got signal %08lX\n", __LINE__, current->pid, current->comm, current->pending.signal.sig[0]); + return -ERESTARTSYS; + } return(0); } -static inline void calc_fcs(struct zt_chan *ss) +static inline void calc_fcs(struct zt_chan *ss, int inwritebuf) { int x; unsigned int fcs=PPP_INITFCS; - unsigned char *data = ss->writebuf[ss->inwritebuf]; - int len = ss->writen[ss->inwritebuf]; + unsigned char *data = ss->writebuf[inwritebuf]; + int len = ss->writen[inwritebuf]; /* Not enough space to do FCS calculation */ if (len < 2) return; @@ -1765,8 +1768,8 @@ static ssize_t zt_chan_read(struct file *file, char *usrbuf, size_t count, int u if ((unit == 24) || (unit == 48) || (unit == 16) || (unit == 47)) { int myamnt = amnt; int x; - if (amnt > chan->readn[chan->outreadbuf]) - myamnt = chan->readn[chan->outreadbuf]; + if (amnt > chan->readn[res]) + myamnt = chan->readn[res]; printk("zt_chan_read(unit: %d, inwritebuf: %d, outwritebuf: %d amnt: %d\n", unit, chan->inwritebuf, chan->outwritebuf, myamnt); printk("\t("); for (x = 0; x < myamnt; x++) printk((x ? " %02x" : "%02x"), (unsigned char)usrbuf[x]); @@ -1775,8 +1778,8 @@ static ssize_t zt_chan_read(struct file *file, char *usrbuf, size_t count, int u #endif /* end addition */ if (chan->flags & ZT_FLAG_LINEAR) { - if (amnt > (chan->readn[chan->outreadbuf] << 1)) - amnt = chan->readn[chan->outreadbuf] << 1; + if (amnt > (chan->readn[res] << 1)) + amnt = chan->readn[res] << 1; if (amnt) { /* There seems to be a max stack size, so we have to do this in smaller pieces */ @@ -1789,7 +1792,7 @@ static ssize_t zt_chan_read(struct file *file, char *usrbuf, size_t count, int u if (pass > 128) pass = 128; for (x=0;xreadbuf[chan->outreadbuf][x + pos], chan); + lindata[x] = ZT_XLAW(chan->readbuf[res][x + pos], chan); if (copy_to_user(usrbuf + (pos << 1), lindata, pass << 1)) return -EFAULT; left -= pass; @@ -1797,18 +1800,18 @@ static ssize_t zt_chan_read(struct file *file, char *usrbuf, size_t count, int u } } } else { - if (amnt > chan->readn[chan->outreadbuf]) - amnt = chan->readn[chan->outreadbuf]; + if (amnt > chan->readn[res]) + amnt = chan->readn[res]; if (amnt) { - if (copy_to_user(usrbuf, chan->readbuf[chan->outreadbuf], amnt)) + if (copy_to_user(usrbuf, chan->readbuf[res], amnt)) return -EFAULT; } } spin_lock_irqsave(&chan->lock, flags); - chan->readidx[chan->outreadbuf] = 0; - chan->readn[chan->outreadbuf] = 0; - oldbuf = chan->outreadbuf; - chan->outreadbuf = (chan->outreadbuf + 1) % chan->numbufs; + chan->readidx[res] = 0; + chan->readn[res] = 0; + oldbuf = res; + res = (chan->outreadbuf + 1) % chan->numbufs; if (chan->outreadbuf == chan->inreadbuf) { /* Out of stuff */ chan->outreadbuf = -1; @@ -1870,14 +1873,14 @@ static ssize_t zt_chan_write(struct file *file, const char *usrbuf, size_t count } #ifdef CONFIG_ZAPATA_DEBUG - printk("zt_chan_write(unit: %d, inwritebuf: %d, outwritebuf: %d amnt: %d\n", - unit, chan->inwritebuf, chan->outwritebuf, amnt); + printk("zt_chan_write(unit: %d, res: %d, outwritebuf: %d amnt: %d\n", + unit, chan->res, chan->outwritebuf, amnt); #endif #if 0 if ((unit == 24) || (unit == 48) || (unit == 16) || (unit == 47)) { int x; - printk("zt_chan_write/in(unit: %d, inwritebuf: %d, outwritebuf: %d amnt: %d, txdisable: %d)\n", - unit, chan->inwritebuf, chan->outwritebuf, amnt, chan->txdisable); + printk("zt_chan_write/in(unit: %d, res: %d, outwritebuf: %d amnt: %d, txdisable: %d)\n", + unit, res, chan->outwritebuf, amnt, chan->txdisable); printk("\t("); for (x = 0; x < amnt; x++) printk((x ? " %02x" : "%02x"), (unsigned char)usrbuf[x]); printk(")\n"); } @@ -1899,21 +1902,21 @@ static ssize_t zt_chan_write(struct file *file, const char *usrbuf, size_t count return -EFAULT; left -= pass; for (x=0;xwritebuf[chan->inwritebuf][x + pos] = ZT_LIN2X(lindata[x], chan); + chan->writebuf[res][x + pos] = ZT_LIN2X(lindata[x], chan); pos += pass; } - chan->writen[chan->inwritebuf] = amnt >> 1; + chan->writen[res] = amnt >> 1; } else { - if (copy_from_user(chan->writebuf[chan->inwritebuf], usrbuf, amnt)) + if (copy_from_user(chan->writebuf[res], usrbuf, amnt)) return -EFAULT; - chan->writen[chan->inwritebuf] = amnt; + chan->writen[res] = amnt; } - chan->writeidx[chan->inwritebuf] = 0; + chan->writeidx[res] = 0; if (chan->flags & ZT_FLAG_FCS) - calc_fcs(chan); - oldbuf = chan->inwritebuf; + calc_fcs(chan, res); + oldbuf = res; spin_lock_irqsave(&chan->lock, flags); - chan->inwritebuf = (chan->inwritebuf + 1) % chan->numbufs; + chan->inwritebuf = (res + 1) % chan->numbufs; if (chan->inwritebuf == chan->outwritebuf) { /* Don't stomp on the transmitter, just wait for them to wake us up */ -- cgit v1.2.3