From dc21e8e7aae9e191aa9ac0a3d5fe1d4b64876a0d Mon Sep 17 00:00:00 2001 From: kpfleming Date: Thu, 29 Sep 2005 03:03:33 +0000 Subject: 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 --- zaptel.c | 64 ++++++++++++++++++++++++++++++++++++++-------------------------- 1 file 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 */ -- cgit v1.2.3