summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2005-09-29 03:03:33 +0000
committerkpfleming <kpfleming@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2005-09-29 03:03:33 +0000
commitdc21e8e7aae9e191aa9ac0a3d5fe1d4b64876a0d (patch)
treeb9bb92dd4fcbb29a10e94e380eec918bebdc1e70
parentbb9675a0268c73b0ad7c8af51b47967e99cda828 (diff)
check results of copy_from/to_user (issue #5316)
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@782 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rwxr-xr-xzaptel.c64
1 files changed, 38 insertions, 26 deletions
diff --git a/zaptel.c b/zaptel.c
index 6c7c596..d86f3dc 100755
--- a/zaptel.c
+++ b/zaptel.c
@@ -1758,7 +1758,8 @@ static ssize_t zt_chan_write(struct file *file, const char *usrbuf, size_t count
}
chan->writen[chan->inwritebuf] = amnt >> 1;
} else {
- copy_from_user(chan->writebuf[chan->inwritebuf], usrbuf, amnt);
+ if (copy_from_user(chan->writebuf[chan->inwritebuf], usrbuf, amnt))
+ return -EFAULT;
chan->writen[chan->inwritebuf] = amnt;
}
chan->writeidx[chan->inwritebuf] = 0;
@@ -2405,7 +2406,8 @@ ioctl_load_zone(unsigned long data)
memset(samples, 0, sizeof(samples));
/* XXX Unnecessary XXX */
memset(next, 0, sizeof(next));
- copy_from_user(&th, (struct zt_tone_def_header *)data, sizeof(th));
+ if (copy_from_user(&th, (struct zt_tone_def_header *)data, sizeof(th)))
+ return -EFAULT;
if ((th.count < 0) || (th.count > MAX_TONES)) {
printk("Too many tones included\n");
return -EINVAL;
@@ -2436,7 +2438,7 @@ ioctl_load_zone(unsigned long data)
}
if (copy_from_user(&td, (struct zt_tone_def *)data, sizeof(struct zt_tone_def))) {
kfree(slab);
- return -EIO;
+ return -EFAULT;
}
/* Index the current sample */
samples[x] = t = (struct zt_tone *)ptr;
@@ -2758,7 +2760,8 @@ static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int c
switch(cmd) {
case ZT_GET_PARAMS: /* get channel timing parameters */
- copy_from_user(&stack.param,(struct zt_params *)data,sizeof(stack.param));
+ if (copy_from_user(&stack.param,(struct zt_params *)data,sizeof(stack.param)))
+ return -EFAULT;
/* check to see if the caller wants to receive our master channel number */
if (stack.param.channo & ZT_GET_PARAMS_RETURN_MASTER) {
@@ -2830,10 +2833,12 @@ static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int c
stack.param.curlaw = ZT_LAW_ALAW;
else
stack.param.curlaw = ZT_LAW_MULAW;
- copy_to_user((struct zt_params *)data,&stack.param,sizeof(stack.param));
+ if (copy_to_user((struct zt_params *)data,&stack.param,sizeof(stack.param)))
+ return -EFAULT;
break;
case ZT_SET_PARAMS: /* set channel timing stack.paramters */
- copy_from_user(&stack.param,(struct zt_params *)data,sizeof(stack.param));
+ if (copy_from_user(&stack.param,(struct zt_params *)data,sizeof(stack.param)))
+ return -EFAULT;
/* Pick the right channo's */
if (!stack.param.channo || unit) {
stack.param.channo = unit;
@@ -2861,7 +2866,7 @@ static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int c
break;
case ZT_GETGAINS: /* get gain stuff */
if (copy_from_user(&stack.gain,(struct zt_gains *) data,sizeof(stack.gain)))
- return -EIO;
+ return -EFAULT;
i = stack.gain.chan; /* get channel no */
/* if zero, use current channel no */
if (!i) i = unit;
@@ -2875,11 +2880,11 @@ static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int c
stack.gain.rxgain[j] = chans[i]->rxgain[j];
}
if (copy_to_user((struct zt_gains *) data,&stack.gain,sizeof(stack.gain)))
- return -EIO;
+ return -EFAULT;
break;
case ZT_SETGAINS: /* set gain stuff */
if (copy_from_user(&stack.gain,(struct zt_gains *) data,sizeof(stack.gain)))
- return -EIO;
+ return -EFAULT;
i = stack.gain.chan; /* get channel no */
/* if zero, use current channel no */
if (!i) i = unit;
@@ -2912,10 +2917,11 @@ static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int c
chans[i]->gainalloc = 0;
}
if (copy_to_user((struct zt_gains *) data,&stack.gain,sizeof(stack.gain)))
- return -EIO;
+ return -EFAULT;
break;
case ZT_SPANSTAT:
- copy_from_user(&stack.span,(struct zt_spaninfo *) data,sizeof(stack.span));
+ if (copy_from_user(&stack.span,(struct zt_spaninfo *) data,sizeof(stack.span)))
+ return -EFAULT;
i = stack.span.spanno; /* get specified span number */
if ((i < 0) || (i >= maxspans)) return(-EINVAL); /* if bad span no */
if (i == 0) /* if to figure it out for this chan */
@@ -2945,7 +2951,8 @@ static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int c
for (j=0; j < spans[i]->channels; j++)
if (spans[i]->chans[j].sig)
stack.span.numchans++;
- copy_to_user((struct zt_spaninfo *) data,&stack.span,sizeof(stack.span));
+ if (copy_to_user((struct zt_spaninfo *) data,&stack.span,sizeof(stack.span)))
+ return -EFAULT;
break;
#ifdef ALLOW_CHAN_DIAG
case ZT_CHANDIAG:
@@ -3333,7 +3340,7 @@ static int zt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd
return 0;
case ZT_SET_DIALPARAMS:
if (copy_from_user(&tdp, (struct zt_dialparams *)data, sizeof(tdp)))
- return -EIO;
+ return -EFAULT;
if ((tdp.dtmf_tonelen > 4000) || (tdp.dtmf_tonelen < 10))
return -EINVAL;
if ((tdp.mfv1_tonelen > 4000) || (tdp.mfv1_tonelen < 10))
@@ -3355,12 +3362,12 @@ static int zt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd
tdp.reserved[2] = 0;
tdp.reserved[3] = 0;
if (copy_to_user((struct zt_dialparams *)data, &tdp, sizeof(tdp)))
- return -EIO;
+ return -EFAULT;
break;
case ZT_MAINT: /* do maintence stuff */
/* get struct from user */
- if (copy_from_user(&maint,(struct zt_maintinfo *) data,
- sizeof(maint))) return -EIO;
+ if (copy_from_user(&maint,(struct zt_maintinfo *) data, sizeof(maint)))
+ return -EFAULT;
/* must be valid span number */
if ((maint.spanno < 1) || (maint.spanno > ZT_MAX_SPANS) || (!spans[maint.spanno]))
return -EINVAL;
@@ -3435,11 +3442,11 @@ static int zt_chanandpseudo_ioctl(struct inode *inode, struct file *file, unsign
j = chan->dialing;
spin_unlock_irqrestore(&chan->lock, flags);
if (copy_to_user((int *)data,&j,sizeof(int)))
- return -EIO;
+ return -EFAULT;
return 0;
case ZT_DIAL:
if (copy_from_user(&stack.tdo, (struct zt_dialoperation *)data, sizeof(stack.tdo)))
- return -EIO;
+ return -EFAULT;
rv = 0;
/* Force proper NULL termination */
stack.tdo.dialstr[ZT_MAX_DTMF_BUF - 1] = '\0';
@@ -3484,11 +3491,11 @@ static int zt_chanandpseudo_ioctl(struct inode *inode, struct file *file, unsign
stack.bi.readbufs = -1;
stack.bi.writebufs = -1;
if (copy_to_user((struct zt_bufferinfo *)data, &stack.bi, sizeof(stack.bi)))
- return -EIO;
+ return -EFAULT;
break;
case ZT_SET_BUFINFO:
if (copy_from_user(&stack.bi, (struct zt_bufferinfo *)data, sizeof(stack.bi)))
- return -EIO;
+ return -EFAULT;
if (stack.bi.bufsize > ZT_MAX_BLOCKSIZE)
return -EINVAL;
if (stack.bi.bufsize < 16)
@@ -3667,7 +3674,8 @@ static int zt_chanandpseudo_ioctl(struct inode *inode, struct file *file, unsign
spin_unlock_irqrestore(&chan->lock, flags);
return rv;
case ZT_GETCONF: /* get conf stuff */
- copy_from_user(&stack.conf,(struct zt_confinfo *) data,sizeof(stack.conf));
+ if (copy_from_user(&stack.conf,(struct zt_confinfo *) data,sizeof(stack.conf)))
+ return -EFAULT;
i = stack.conf.chan; /* get channel no */
/* if zero, use current channel no */
if (!i) i = chan->channo;
@@ -3677,10 +3685,12 @@ static int zt_chanandpseudo_ioctl(struct inode *inode, struct file *file, unsign
stack.conf.chan = i; /* get channel number */
stack.conf.confno = chans[i]->confna; /* get conference number */
stack.conf.confmode = chans[i]->confmode; /* get conference mode */
- copy_to_user((struct zt_confinfo *) data,&stack.conf,sizeof(stack.conf));
+ if (copy_to_user((struct zt_confinfo *) data,&stack.conf,sizeof(stack.conf)))
+ return -EFAULT;
break;
case ZT_SETCONF: /* set conf stuff */
- copy_from_user(&stack.conf,(struct zt_confinfo *) data,sizeof(stack.conf));
+ if (copy_from_user(&stack.conf,(struct zt_confinfo *) data,sizeof(stack.conf)))
+ return -EFAULT;
i = stack.conf.chan; /* get channel no */
/* if zero, use current channel no */
if (!i) i = chan->channo;
@@ -3739,11 +3749,13 @@ static int zt_chanandpseudo_ioctl(struct inode *inode, struct file *file, unsign
}
spin_unlock_irqrestore(&chan->lock, flags);
spin_unlock_irqrestore(&bigzaplock, flagso);
- copy_to_user((struct zt_confinfo *) data,&stack.conf,sizeof(stack.conf));
+ if (copy_to_user((struct zt_confinfo *) data,&stack.conf,sizeof(stack.conf)))
+ return -EFAULT;
break;
case ZT_CONFLINK: /* do conf link stuff */
if (!(chan->flags & ZT_FLAG_AUDIO)) return (-EINVAL);
- copy_from_user(&stack.conf,(struct zt_confinfo *) data,sizeof(stack.conf));
+ if (copy_from_user(&stack.conf,(struct zt_confinfo *) data,sizeof(stack.conf)))
+ return -EFAULT;
/* check sanity of arguments */
if ((stack.conf.chan < 0) || (stack.conf.chan > ZT_MAX_CONF)) return(-EINVAL);
if ((stack.conf.confno < 0) || (stack.conf.confno > ZT_MAX_CONF)) return(-EINVAL);
@@ -3868,7 +3880,7 @@ static int zt_chanandpseudo_ioctl(struct inode *inode, struct file *file, unsign
if (data) {
/* Use specific ring cadence */
if (copy_from_user(&stack.cad, (struct zt_ring_cadence *)data, sizeof(stack.cad)))
- return -EIO;
+ return -EFAULT;
memcpy(chan->ringcadence, &stack.cad, sizeof(chan->ringcadence));
chan->firstcadencepos = 0;
/* Looking for negative ringing time indicating where to loop back into ringcadence */