[zaptel-commits] mattf: trunk r2396 - /trunk/zaptel.c

zaptel-commits at lists.digium.com zaptel-commits at lists.digium.com
Sat Apr 7 09:43:47 MST 2007


Author: mattf
Date: Sat Apr  7 11:43:47 2007
New Revision: 2396

URL: http://svn.digium.com/view/zaptel?view=rev&rev=2396
Log:
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)

Modified:
    trunk/zaptel.c

Modified: trunk/zaptel.c
URL: http://svn.digium.com/view/zaptel/trunk/zaptel.c?view=diff&rev=2396&r1=2395&r2=2396
==============================================================================
--- trunk/zaptel.c (original)
+++ trunk/zaptel.c Sat Apr  7 11:43:47 2007
@@ -769,16 +769,19 @@
 	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 @@
 	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 @@
 #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 @@
 				if (pass > 128)
 					pass = 128;
 				for (x=0;x<pass;x++)
-					lindata[x] = ZT_XLAW(chan->readbuf[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 @@
 			}
 		}
 	} 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 @@
 	}
 
 #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 @@
 					return -EFAULT;
 				left -= pass;
 				for (x=0;x<pass;x++)
-					chan->writebuf[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->writeidx[chan->inwritebuf] = 0;
+			chan->writen[res] = amnt;
+		}
+		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 */



More information about the zaptel-commits mailing list