summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2010-02-08 22:49:32 +0000
committerShaun Ruffell <sruffell@digium.com>2010-02-08 22:49:32 +0000
commitf67ad3bba13254b84674d0aef55cfa5046f5b347 (patch)
tree27c04e9129f6ccc1eec7c47190ad7d17ebfed436
parent42e275be0f7ce08a9fe2adf4815f7fd926a341bb (diff)
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
-rw-r--r--drivers/dahdi/dahdi-base.c224
1 files changed, 130 insertions, 94 deletions
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;
}