From f67ad3bba13254b84674d0aef55cfa5046f5b347 Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Mon, 8 Feb 2010 22:49:32 +0000 Subject: dahdi-base: Minor changes for sparse. Mostly making sure __user flag is caried through appropriately on user mode access, but also two cases of removing dynamically sized arrays (which unduly complicate using the kernel backtrace when you don't have a debugger attached since you do not know how much data is really on the stack), and editing dahdi_chan_register so that the lock/unlock context is clear. git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@8004 a0bf4364-ded3-4de4-8d8a-66a801d63aff --- drivers/dahdi/dahdi-base.c | 224 ++++++++++++++++++++++++++------------------- 1 file changed, 130 insertions(+), 94 deletions(-) (limited to 'drivers/dahdi') diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c index 39aa64b..85958b4 100644 --- a/drivers/dahdi/dahdi-base.c +++ b/drivers/dahdi/dahdi-base.c @@ -1166,12 +1166,16 @@ static void reset_conf(struct dahdi_chan *chan) static const struct dahdi_echocan_factory *find_echocan(const char *name) { struct ecfactory *cur; - char name_upper[strlen(name) + 1]; + char *name_upper; char *c; const char *d; char modname_buf[128] = "dahdi_echocan_"; unsigned int tried_once = 0; + name_upper = kmalloc(strlen(name) + 1, GFP_KERNEL); + if (!name_upper) + return NULL; + for (c = name_upper, d = name; *d; c++, d++) { *c = toupper(*d); } @@ -1185,9 +1189,11 @@ retry: if (!strcmp(name_upper, cur->ec->name)) { if (try_module_get(cur->ec->owner)) { read_unlock(&ecfactory_list_lock); + kfree(name_upper); return cur->ec; } else { read_unlock(&ecfactory_list_lock); + kfree(name_upper); return NULL; } } @@ -1196,6 +1202,7 @@ retry: read_unlock(&ecfactory_list_lock); if (tried_once) { + kfree(name_upper); return NULL; } @@ -1565,15 +1572,13 @@ static int dahdi_chan_reg(struct dahdi_chan *chan) if (maxchans < x + 1) maxchans = x + 1; chan->channo = x; - write_unlock_irqrestore(&chan_lock, flags); /* set this AFTER running close_channel() so that HDLC channels wont cause hangage */ set_bit(DAHDI_FLAGBIT_REGISTERED, &chan->flags); break; } - + write_unlock_irqrestore(&chan_lock, flags); if (DAHDI_MAX_CHANNELS == x) { - write_unlock_irqrestore(&chan_lock, flags); module_printk(KERN_ERR, "No more channels available\n"); return -ENOMEM; } @@ -2964,18 +2969,18 @@ static int ioctl_load_zone(unsigned long data) void *slab, *ptr; struct dahdi_zone *z; struct dahdi_tone *t; + void __user * user_data = (void __user *)data; work = kzalloc(sizeof(*work), GFP_KERNEL); if (!work) return -ENOMEM; - if (copy_from_user(&work->th, (struct dahdi_tone_def_header *)data, - sizeof(work->th))) { + if (copy_from_user(&work->th, user_data, sizeof(work->th))) { kfree(work); return -EFAULT; } - data += sizeof(work->th); + user_data += sizeof(work->th); if ((work->th.count < 0) || (work->th.count > MAX_TONES)) { module_printk(KERN_NOTICE, "Too many tones included\n"); @@ -3022,7 +3027,7 @@ static int ioctl_load_zone(unsigned long data) return -EINVAL; } - res = copy_from_user(&work->td, (struct dahdi_tone_def *)data, + res = copy_from_user(&work->td, user_data, sizeof(work->td)); if (res) { kfree(slab); @@ -3030,7 +3035,7 @@ static int ioctl_load_zone(unsigned long data) return -EFAULT; } - data += sizeof(work->td); + user_data += sizeof(work->td); if ((work->td.tone >= 0) && (work->td.tone < DAHDI_TONE_MAX)) { tone_type = REGULAR_TONE; @@ -3486,7 +3491,7 @@ void dahdi_alarm_notify(struct dahdi_span *span) #define CHECK_VALID_SPAN(j) do { \ /* Start a given span */ \ - if (get_user(j, (int *)data)) \ + if (get_user(j, (int __user *)data)) \ return -EFAULT; \ VALID_SPAN(j); \ } while(0) @@ -3504,7 +3509,7 @@ static int dahdi_timer_ioctl(struct file *file, unsigned int cmd, unsigned long unsigned long flags; switch(cmd) { case DAHDI_TIMERCONFIG: - get_user(j, (int *)data); + get_user(j, (int __user *)data); if (j < 0) j = 0; spin_lock_irqsave(&zaptimerlock, flags); @@ -3512,7 +3517,7 @@ static int dahdi_timer_ioctl(struct file *file, unsigned int cmd, unsigned long spin_unlock_irqrestore(&zaptimerlock, flags); break; case DAHDI_TIMERACK: - get_user(j, (int *)data); + get_user(j, (int __user *)data); spin_lock_irqsave(&zaptimerlock, flags); if ((j < 1) || (j > timer->tripped)) j = timer->tripped; @@ -3528,7 +3533,7 @@ static int dahdi_timer_ioctl(struct file *file, unsigned int cmd, unsigned long if (timer->ping) j = DAHDI_EVENT_TIMER_PING; spin_unlock_irqrestore(&zaptimerlock, flags); - put_user(j,(int *)data); + put_user(j, (int __user *)data); break; case DAHDI_TIMERPING: spin_lock_irqsave(&zaptimerlock, flags); @@ -3553,12 +3558,13 @@ static int dahdi_ioctl_getgains(struct file *file, int res = 0; struct dahdi_gains *gain; int i, j; + void __user * const user_data = (void __user *)data; gain = kzalloc(sizeof(*gain), GFP_KERNEL); if (!gain) return -ENOMEM; - if (copy_from_user(gain, (struct dahdi_gains *)data, sizeof(*gain))) { + if (copy_from_user(gain, user_data, sizeof(*gain))) { res = -EFAULT; goto cleanup; } @@ -3582,7 +3588,7 @@ static int dahdi_ioctl_getgains(struct file *file, gain->txgain[j] = chans[i]->txgain[j]; gain->rxgain[j] = chans[i]->rxgain[j]; } - if (copy_to_user((struct dahdi_gains *)data, gain, sizeof(*gain))) { + if (copy_to_user(user_data, gain, sizeof(*gain))) { res = -EFAULT; goto cleanup; } @@ -3601,12 +3607,13 @@ static int dahdi_ioctl_setgains(struct file *file, int i, j; unsigned long flags; const int GAIN_TABLE_SIZE = sizeof(defgain); + void __user * const user_data = (void __user *)data; gain = kzalloc(sizeof(*gain), GFP_KERNEL); if (!gain) return -ENOMEM; - if (copy_from_user(gain, (struct dahdi_gains *)data, sizeof(*gain))) { + if (copy_from_user(gain, user_data, sizeof(*gain))) { res = -EFAULT; goto cleanup; } @@ -3659,7 +3666,7 @@ static int dahdi_ioctl_setgains(struct file *file, spin_unlock_irqrestore(&chans[i]->lock, flags); } - if (copy_to_user((struct dahdi_gains *)data, gain, sizeof(*gain))) { + if (copy_to_user(user_data, gain, sizeof(*gain))) { res = -EFAULT; goto cleanup; } @@ -3680,13 +3687,14 @@ static int dahdi_common_ioctl(struct file *file, unsigned int cmd, unsigned long int i,j; int return_master = 0; size_t size_to_copy; + void __user * const user_data = (void __user *)data; switch(cmd) { /* get channel parameters */ case DAHDI_GET_PARAMS_V1: /* Intentional drop through. */ case DAHDI_GET_PARAMS: size_to_copy = sizeof(struct dahdi_params); - if (copy_from_user(&stack.param, (struct dahdi_params *) data, size_to_copy)) + if (copy_from_user(&stack.param, user_data, size_to_copy)) return -EFAULT; /* check to see if the caller wants to receive our master channel number */ @@ -3764,13 +3772,14 @@ static int dahdi_common_ioctl(struct file *file, unsigned int cmd, unsigned long else stack.param.curlaw = DAHDI_LAW_MULAW; - if (copy_to_user((struct dahdi_params *) data, &stack.param, size_to_copy)) + if (copy_to_user(user_data, &stack.param, size_to_copy)) return -EFAULT; break; /* set channel parameters */ case DAHDI_SET_PARAMS: - if (copy_from_user(&stack.param, (struct dahdi_params *) data, sizeof(struct dahdi_params))) + if (copy_from_user(&stack.param, user_data, + sizeof(struct dahdi_params))) return -EFAULT; stack.param.chan_alarms = 0; /* be explicit about the above */ @@ -3807,7 +3816,7 @@ static int dahdi_common_ioctl(struct file *file, unsigned int cmd, unsigned long return dahdi_ioctl_setgains(file, cmd, data, unit); case DAHDI_SPANSTAT: size_to_copy = sizeof(struct dahdi_spaninfo); - if (copy_from_user(&stack.spaninfo, (struct dahdi_spaninfo *) data, size_to_copy)) + if (copy_from_user(&stack.spaninfo, user_data, size_to_copy)) return -EFAULT; i = stack.spaninfo.spanno; /* get specified span number */ if ((i < 0) || (i >= maxspans)) return(-EINVAL); /* if bad span no */ @@ -3853,7 +3862,7 @@ static int dahdi_common_ioctl(struct file *file, unsigned int cmd, unsigned long if (spans[i]->spantype) dahdi_copy_string(stack.spaninfo.spantype, spans[i]->spantype, sizeof(stack.spaninfo.spantype)); - if (copy_to_user((struct dahdi_spaninfo *) data, &stack.spaninfo, size_to_copy)) + if (copy_to_user(user_data, &stack.spaninfo, size_to_copy)) return -EFAULT; break; case DAHDI_CHANDIAG_V1: /* Intentional drop through. */ @@ -3865,7 +3874,8 @@ static int dahdi_common_ioctl(struct file *file, unsigned int cmd, unsigned long */ struct dahdi_echocan_state ec_state = { .ops = NULL, }; - get_user(j, (int *) data); /* get channel number from user */ + /* get channel number from user */ + get_user(j, (int __user *)data); /* make sure its a valid channel number */ if ((j < 1) || (j >= maxchans)) return -EINVAL; @@ -3978,13 +3988,14 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da int x,y; struct dahdi_chan *newmaster; unsigned long flags; + void __user * const user_data = (void __user *)data; int rv; switch(cmd) { case DAHDI_INDIRECT: { struct dahdi_indirect_data ind; - if (copy_from_user(&ind, (struct dahdi_indirect_data *)data, sizeof(ind))) + if (copy_from_user(&ind, user_data, sizeof(ind))) return -EFAULT; VALID_CHANNEL(ind.chan); return dahdi_chan_ioctl(file, ind.op, (unsigned long) ind.data, ind.chan); @@ -3993,7 +4004,7 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da { struct dahdi_lineconfig lc; - if (copy_from_user(&lc, (struct dahdi_lineconfig *)data, sizeof(lc))) + if (copy_from_user(&lc, user_data, sizeof(lc))) return -EFAULT; VALID_SPAN(lc.span); if ((lc.lineconfig & 0x07f0 & spans[lc.span]->linecompat) != (lc.lineconfig & 0x07f0)) @@ -4047,9 +4058,8 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da struct dahdi_attach_echocan ae; const struct dahdi_echocan_factory *new = NULL, *old; - if (copy_from_user(&ae, (struct dahdi_attach_echocan *) data, sizeof(ae))) { + if (copy_from_user(&ae, user_data, sizeof(ae))) return -EFAULT; - } VALID_CHANNEL(ae.chan); @@ -4075,7 +4085,7 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da { struct dahdi_chanconfig ch; - if (copy_from_user(&ch, (struct dahdi_chanconfig *)data, sizeof(ch))) + if (copy_from_user(&ch, user_data, sizeof(ch))) return -EFAULT; VALID_CHANNEL(ch.chan); if (ch.sigtype == DAHDI_SIG_SLAVE) { @@ -4250,7 +4260,7 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da chans[ch.chan]->deflaw = ch.deflaw; /* Copy back any modified settings */ spin_unlock_irqrestore(&chans[ch.chan]->lock, flags); - if (copy_to_user((struct dahdi_chanconfig *)data, &ch, sizeof(ch))) + if (copy_to_user(user_data, &ch, sizeof(ch))) return -EFAULT; spin_lock_irqsave(&chans[ch.chan]->lock, flags); /* And hangup */ @@ -4271,7 +4281,7 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da { struct dahdi_sfconfig sf; - if (copy_from_user(&sf, (struct dahdi_chanconfig *)data, sizeof(sf))) + if (copy_from_user(&sf, user_data, sizeof(sf))) return -EFAULT; VALID_CHANNEL(sf.chan); if (chans[sf.chan]->sig != DAHDI_SIG_SF) return -EINVAL; @@ -4299,19 +4309,19 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da return res; } case DAHDI_DEFAULTZONE: - if (get_user(j,(int *)data)) + if (get_user(j, (int __user *)data)) return -EFAULT; return dahdi_set_default_zone(j); case DAHDI_LOADZONE: return ioctl_load_zone(data); case DAHDI_FREEZONE: - get_user(j, (int *) data); + get_user(j, (int __user *) data); return free_tone_zone(j); case DAHDI_SET_DIALPARAMS: { struct dahdi_dialparams tdp; - if (copy_from_user(&tdp, (struct dahdi_dialparams *) data, sizeof(tdp))) + if (copy_from_user(&tdp, user_data, sizeof(tdp))) return -EFAULT; if ((tdp.dtmf_tonelen >= 10) && (tdp.dtmf_tonelen <= 4000)) { @@ -4362,7 +4372,7 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da struct dahdi_dialparams tdp; tdp = global_dialparams; - if (copy_to_user((struct dahdi_dialparams *) data, &tdp, sizeof(tdp))) + if (copy_to_user(user_data, &tdp, sizeof(tdp))) return -EFAULT; break; } @@ -4390,7 +4400,7 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da } } read_unlock(&ecfactory_list_lock); - if (copy_to_user((struct dahdi_versioninfo *) data, &vi, sizeof(vi))) + if (copy_to_user(user_data, &vi, sizeof(vi))) return -EFAULT; break; } @@ -4398,7 +4408,7 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da { struct dahdi_maintinfo maint; /* get struct from user */ - if (copy_from_user(&maint,(struct dahdi_maintinfo *) data, sizeof(maint))) + if (copy_from_user(&maint, user_data, sizeof(maint))) return -EFAULT; /* must be valid span number */ if ((maint.spanno < 1) || (maint.spanno > DAHDI_MAX_SPANS) || (!spans[maint.spanno])) @@ -4474,13 +4484,14 @@ static int ioctl_dahdi_dial(struct dahdi_chan *chan, unsigned long data) unsigned long flags; char *s; int rv; + void __user * const user_data = (void __user *)data; tdo = kmalloc(sizeof(*tdo), GFP_KERNEL); if (!tdo) return -ENOMEM; - if (copy_from_user(tdo, (struct dahdi_dialoperation *)data, sizeof(*tdo))) + if (copy_from_user(tdo, user_data, sizeof(*tdo))) return -EFAULT; rv = 0; /* Force proper NULL termination and uppercase entry */ @@ -4525,7 +4536,9 @@ static int ioctl_dahdi_dial(struct dahdi_chan *chan, unsigned long data) return rv; } -static int dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd, unsigned long data, int unit) +static int +dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd, + unsigned long data, int unit) { struct dahdi_chan *chan = chans[unit]; union { @@ -4536,6 +4549,7 @@ static int dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd, unsign unsigned long flags; int i, j, k, rv; int ret, c; + void __user * const user_data = (void __user *)data; if (!chan) return -EINVAL; @@ -4544,7 +4558,7 @@ static int dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd, unsign spin_lock_irqsave(&chan->lock, flags); j = chan->dialing; spin_unlock_irqrestore(&chan->lock, flags); - if (copy_to_user((int *)data,&j,sizeof(int))) + if (copy_to_user(user_data, &j, sizeof(int))) return -EFAULT; return 0; case DAHDI_DIAL: @@ -4558,11 +4572,11 @@ static int dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd, unsign /* XXX FIXME! XXX */ stack.bi.readbufs = -1; stack.bi.writebufs = -1; - if (copy_to_user((struct dahdi_bufferinfo *)data, &stack.bi, sizeof(stack.bi))) + if (copy_to_user(user_data, &stack.bi, sizeof(stack.bi))) return -EFAULT; break; case DAHDI_SET_BUFINFO: - if (copy_from_user(&stack.bi, (struct dahdi_bufferinfo *)data, sizeof(stack.bi))) + if (copy_from_user(&stack.bi, user_data, sizeof(stack.bi))) return -EFAULT; if (stack.bi.bufsize > DAHDI_MAX_BLOCKSIZE) return -EINVAL; @@ -4581,21 +4595,22 @@ static int dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd, unsign return (rv); break; case DAHDI_GET_BLOCKSIZE: /* get blocksize */ - put_user(chan->blocksize,(int *)data); /* return block size */ + /* return block size */ + put_user(chan->blocksize, (int __user *)data); break; case DAHDI_SET_BLOCKSIZE: /* set blocksize */ - get_user(j,(int *)data); - /* cannot be larger than max amount */ + get_user(j, (int __user *)data); + /* cannot be larger than max amount */ if (j > DAHDI_MAX_BLOCKSIZE) return(-EINVAL); - /* cannot be less then 16 */ + /* cannot be less then 16 */ if (j < 16) return(-EINVAL); - /* allocate a single kernel buffer which we then - sub divide into four pieces */ + /* allocate a single kernel buffer which we then + sub divide into four pieces */ if ((rv = dahdi_reallocbufs(chan, j, chan->numbufs))) return (rv); break; case DAHDI_FLUSH: /* flush input buffer, output buffer, and/or event queue */ - get_user(i,(int *)data); /* get param */ + get_user(i, (int __user *)data); /* get param */ spin_lock_irqsave(&chan->lock, flags); if (i & DAHDI_FLUSH_READ) /* if for read (input) */ { @@ -4647,7 +4662,7 @@ static int dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd, unsign } break; case DAHDI_IOMUX: /* wait for something to happen */ - get_user(chan->iomask,(int*)data); /* save mask */ + get_user(chan->iomask, (int __user *)data); /* save mask */ if (!chan->iomask) return(-EINVAL); /* cant wait for nothing */ for(;;) /* loop forever */ { @@ -4687,7 +4702,7 @@ static int dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd, unsign if (ret || (chan->iomask & DAHDI_IOMUX_NOWAIT)) { /* set return value */ - put_user(ret,(int *)data); + put_user(ret, (int __user *)data); break; /* get out of loop */ } rv = schluffen(&chan->eventbufq); @@ -4710,10 +4725,10 @@ static int dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd, unsign chan->eventoutidx = 0; } spin_unlock_irqrestore(&chan->lock, flags); - put_user(j,(int *)data); + put_user(j, (int __user *)data); break; case DAHDI_CONFMUTE: /* set confmute flag */ - get_user(j,(int *)data); /* get conf # */ + get_user(j, (int __user *)data); /* get conf # */ if (!(chan->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL); spin_lock_irqsave(&bigzaplock, flags); chan->confmute = j; @@ -4722,11 +4737,11 @@ static int dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd, unsign case DAHDI_GETCONFMUTE: /* get confmute flag */ if (!(chan->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL); j = chan->confmute; - put_user(j,(int *)data); /* get conf # */ + put_user(j, (int __user *)data); /* get conf # */ rv = 0; break; case DAHDI_SETTONEZONE: - get_user(j, (int *) data); + get_user(j, (int __user *) data); rv = set_tone_zone(chan, j); return rv; case DAHDI_GETTONEZONE: @@ -4734,17 +4749,17 @@ static int dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd, unsign if (chan->curzone) j = chan->tonezone; spin_unlock_irqrestore(&chan->lock, flags); - put_user(j, (int *) data); + put_user(j, (int __user *) data); break; case DAHDI_SENDTONE: - get_user(j,(int *)data); + get_user(j, (int __user *)data); spin_lock_irqsave(&chan->lock, flags); rv = start_tone(chan, j); spin_unlock_irqrestore(&chan->lock, flags); return rv; case DAHDI_GETCONF_V1: /* intentional drop through */ case DAHDI_GETCONF: /* get conf stuff */ - if (copy_from_user(&stack.conf,(struct dahdi_confinfo *) data,sizeof(stack.conf))) + if (copy_from_user(&stack.conf, user_data, sizeof(stack.conf))) return -EFAULT; i = stack.conf.chan; /* get channel no */ /* if zero, use current channel no */ @@ -4755,12 +4770,12 @@ static int dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd, 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 */ - if (copy_to_user((struct dahdi_confinfo *) data,&stack.conf,sizeof(stack.conf))) + if (copy_to_user(user_data, &stack.conf, sizeof(stack.conf))) return -EFAULT; break; case DAHDI_SETCONF_V1: /* Intentional fall through. */ case DAHDI_SETCONF: /* set conf stuff */ - if (copy_from_user(&stack.conf,(struct dahdi_confinfo *) data,sizeof(stack.conf))) + if (copy_from_user(&stack.conf, user_data, sizeof(stack.conf))) return -EFAULT; i = stack.conf.chan; /* get channel no */ /* if zero, use current channel no */ @@ -4847,12 +4862,12 @@ static int dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd, unsign spin_unlock(&chan->lock); spin_unlock_irqrestore(&bigzaplock, flags); - if (copy_to_user((struct dahdi_confinfo *) data,&stack.conf,sizeof(stack.conf))) + if (copy_to_user(user_data, &stack.conf, sizeof(stack.conf))) return -EFAULT; break; case DAHDI_CONFLINK: /* do conf link stuff */ if (!(chan->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL); - if (copy_from_user(&stack.conf,(struct dahdi_confinfo *) data,sizeof(stack.conf))) + if (copy_from_user(&stack.conf, user_data, sizeof(stack.conf))) return -EFAULT; /* check sanity of arguments */ if ((stack.conf.chan < 0) || (stack.conf.chan > DAHDI_MAX_CONF)) return(-EINVAL); @@ -4924,7 +4939,7 @@ static int dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd, unsign case DAHDI_CONFDIAG_V1: /* Intention fall-through */ case DAHDI_CONFDIAG: /* output diagnostic info to console */ if (!(chan->flags & DAHDI_FLAG_AUDIO)) return (-EINVAL); - get_user(j,(int *)data); /* get conf # */ + get_user(j, (int __user *)data); /* get conf # */ /* loop thru the interesting ones */ for(i = ((j) ? j : 1); i <= ((j) ? j : DAHDI_MAX_CONF); i++) { @@ -4955,16 +4970,17 @@ static int dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd, unsign } break; case DAHDI_CHANNO: /* get channel number of stream */ - put_user(unit,(int *)data); /* return unit/channel number */ + /* return unit/channel number */ + put_user(unit, (int __user *)data); break; case DAHDI_SETLAW: - get_user(j, (int *)data); + get_user(j, (int __user *)data); if ((j < 0) || (j > DAHDI_LAW_ALAW)) return -EINVAL; dahdi_set_law(chan, j); break; case DAHDI_SETLINEAR: - get_user(j, (int *)data); + get_user(j, (int __user *)data); /* Makes no sense on non-audio channels */ if (!(chan->flags & DAHDI_FLAG_AUDIO)) return -EINVAL; @@ -4977,8 +4993,10 @@ static int dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd, unsign case DAHDI_SETCADENCE: if (data) { /* Use specific ring cadence */ - if (copy_from_user(&stack.cad, (struct dahdi_ring_cadence *)data, sizeof(stack.cad))) + if (copy_from_user(&stack.cad, user_data, + sizeof(stack.cad))) { 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 */ @@ -5049,7 +5067,9 @@ static void do_ppp_calls(unsigned long data) } #endif -static int ioctl_echocancel(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, void *data) +static int +ioctl_echocancel(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp, + const void __user *data) { struct dahdi_echocan_state *ec = NULL, *ec_state; const struct dahdi_echocan_factory *ec_current; @@ -5083,7 +5103,8 @@ static int ioctl_echocancel(struct dahdi_chan *chan, struct dahdi_echocanparams /* enable mode, need the params */ - if (copy_from_user(params, (struct dahdi_echocanparam *) data, sizeof(params[0]) * ecp->param_count)) { + if (copy_from_user(params, data, + sizeof(params[0]) * ecp->param_count)) { ret = -EFAULT; goto exit_with_free; } @@ -5232,7 +5253,7 @@ static int dahdi_chan_ioctl(struct file *file, unsigned int cmd, unsigned long d switch(cmd) { case DAHDI_SETSIGFREEZE: - get_user(j, (int *)data); + get_user(j, (int __user *)data); spin_lock_irqsave(&chan->lock, flags); if (j) { chan->flags |= DAHDI_FLAG_SIGFREEZE; @@ -5248,12 +5269,12 @@ static int dahdi_chan_ioctl(struct file *file, unsigned int cmd, unsigned long d else j = 0; spin_unlock_irqrestore(&chan->lock, flags); - put_user(j, (int *)data); + put_user(j, (int __user *)data); break; case DAHDI_AUDIOMODE: /* Only literal clear channels can be put in */ if (chan->sig != DAHDI_SIG_CLEAR) return (-EINVAL); - get_user(j, (int *)data); + get_user(j, (int __user *)data); if (j) { spin_lock_irqsave(&chan->lock, flags); chan->flags |= DAHDI_FLAG_AUDIO; @@ -5313,7 +5334,7 @@ static int dahdi_chan_ioctl(struct file *file, unsigned int cmd, unsigned long d case DAHDI_HDLCPPP: #ifdef CONFIG_DAHDI_PPP if (chan->sig != DAHDI_SIG_CLEAR) return (-EINVAL); - get_user(j, (int *)data); + get_user(j, (int __user *)data); if (j) { if (!chan->ppp) { chan->ppp = kzalloc(sizeof(struct ppp_channel), GFP_KERNEL); @@ -5378,7 +5399,7 @@ static int dahdi_chan_ioctl(struct file *file, unsigned int cmd, unsigned long d break; case DAHDI_HDLCRAWMODE: if (chan->sig != DAHDI_SIG_CLEAR) return (-EINVAL); - get_user(j, (int *)data); + get_user(j, (int __user *)data); chan->flags &= ~(DAHDI_FLAG_AUDIO | DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS); if (j) { chan->flags |= DAHDI_FLAG_HDLC; @@ -5388,7 +5409,7 @@ static int dahdi_chan_ioctl(struct file *file, unsigned int cmd, unsigned long d break; case DAHDI_HDLCFCSMODE: if (chan->sig != DAHDI_SIG_CLEAR) return (-EINVAL); - get_user(j, (int *)data); + get_user(j, (int __user *)data); chan->flags &= ~(DAHDI_FLAG_AUDIO | DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS); if (j) { chan->flags |= DAHDI_FLAG_HDLC | DAHDI_FLAG_FCS; @@ -5397,7 +5418,7 @@ static int dahdi_chan_ioctl(struct file *file, unsigned int cmd, unsigned long d } break; case DAHDI_HDLC_RATE: - get_user(j, (int *) data); + get_user(j, (int __user *)data); if (j == 56) { chan->flags |= DAHDI_FLAG_HDLC56; } else { @@ -5413,10 +5434,14 @@ static int dahdi_chan_ioctl(struct file *file, unsigned int cmd, unsigned long d if (!(chan->flags & DAHDI_FLAG_AUDIO)) return -EINVAL; - if (copy_from_user(&ecp, (struct dahdi_echocanparams *) data, sizeof(ecp))) + ret = copy_from_user(&ecp, + (struct dahdi_echocanparams __user *)data, + sizeof(ecp)); + if (ret) return -EFAULT; data += sizeof(ecp); - if ((ret = ioctl_echocancel(chan, &ecp, (void *) data))) + ret = ioctl_echocancel(chan, &ecp, (void __user *)data); + if (ret) return ret; break; } @@ -5426,7 +5451,7 @@ static int dahdi_chan_ioctl(struct file *file, unsigned int cmd, unsigned long d if (!(chan->flags & DAHDI_FLAG_AUDIO)) return -EINVAL; - get_user(j, (int *) data); + get_user(j, (int __user *) data); ecp.tap_length = j; ecp.param_count = 0; if ((ret = ioctl_echocancel(chan, &ecp, NULL))) @@ -5434,7 +5459,8 @@ static int dahdi_chan_ioctl(struct file *file, unsigned int cmd, unsigned long d break; } case DAHDI_ECHOTRAIN: - get_user(j, (int *)data); /* get pre-training time from user */ + /* get pre-training time from user */ + get_user(j, (int __user *)data); if ((j < 0) || (j >= DAHDI_MAX_PRETRAINING)) return -EINVAL; j <<= 3; @@ -5455,7 +5481,7 @@ static int dahdi_chan_ioctl(struct file *file, unsigned int cmd, unsigned long d if (!chan->ec_state) { return -EINVAL; } else { - get_user(j, (int *) data); + get_user(j, (int __user *) data); spin_lock_irqsave(&chan->lock, flags); set_echocan_fax_mode(chan, chan->channo, "ioctl", j ? 1 : 0); spin_unlock_irqrestore(&chan->lock, flags); @@ -5464,14 +5490,14 @@ static int dahdi_chan_ioctl(struct file *file, unsigned int cmd, unsigned long d case DAHDI_SETTXBITS: if (chan->sig != DAHDI_SIG_CAS) return -EINVAL; - get_user(j,(int *)data); + get_user(j, (int __user *)data); dahdi_cas_setbits(chan, j); break; case DAHDI_GETRXBITS: - put_user(chan->rxsig, (int *)data); + put_user(chan->rxsig, (int __user *)data); break; case DAHDI_LOOPBACK: - get_user(j, (int *)data); + get_user(j, (int __user *)data); spin_lock_irqsave(&chan->lock, flags); if (j) chan->flags |= DAHDI_FLAG_LOOPED; @@ -5480,7 +5506,7 @@ static int dahdi_chan_ioctl(struct file *file, unsigned int cmd, unsigned long d spin_unlock_irqrestore(&chan->lock, flags); break; case DAHDI_HOOK: - get_user(j,(int *)data); + get_user(j, (int __user *)data); if (chan->flags & DAHDI_FLAG_CLEAR) return -EINVAL; if (chan->sig == DAHDI_SIG_CAS) @@ -5583,16 +5609,20 @@ static int dahdi_chan_ioctl(struct file *file, unsigned int cmd, unsigned long d break; #ifdef CONFIG_DAHDI_PPP case PPPIOCGCHAN: - if (chan->flags & DAHDI_FLAG_PPP) - return put_user(ppp_channel_index(chan->ppp), (int *)data) ? -EFAULT : 0; - else + if (chan->flags & DAHDI_FLAG_PPP) { + return put_user(ppp_channel_index(chan->ppp), + (int __user *)data) ? -EFAULT : 0; + } else { return -EINVAL; + } break; case PPPIOCGUNIT: - if (chan->flags & DAHDI_FLAG_PPP) - return put_user(ppp_unit_number(chan->ppp), (int *)data) ? -EFAULT : 0; - else + if (chan->flags & DAHDI_FLAG_PPP) { + return put_user(ppp_unit_number(chan->ppp), + (int __user *)data) ? -EFAULT : 0; + } else { return -EINVAL; + } break; #endif default: @@ -5612,7 +5642,7 @@ static int dahdi_prechan_ioctl(struct file *file, unsigned int cmd, unsigned lon } switch(cmd) { case DAHDI_SPECIFY: - get_user(channo,(int *)data); + get_user(channo, (int __user *)data); if (channo < 1) return -EINVAL; if (channo > DAHDI_MAX_CHANNELS) @@ -8459,12 +8489,18 @@ static void __exit watchdog_cleanup(void) int dahdi_register_chardev(struct dahdi_chardev *dev) { - char udevname[strlen(dev->name) + sizeof("dahdi!")]; + static const char *DAHDI_STRING = "dahdi!"; + char *udevname; - strcpy(udevname, "dahdi!"); + udevname = kzalloc(strlen(dev->name) + sizeof(DAHDI_STRING) + 1, + GFP_KERNEL); + if (!udevname) + return -ENOMEM; + + strcpy(udevname, DAHDI_STRING); strcat(udevname, dev->name); CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, dev->minor), NULL, udevname); - + kfree(udevname); return 0; } -- cgit v1.2.3