static k_handler_fn *k_handler[16] = { K_HANDLERS };
/* maximum values each key_handler can handle */
-static const int max_vals[] = {
+static const int kbd_max_vals[] = {
255, ARRAY_SIZE(func_table) - 1, NR_FN_HANDLER - 1, 0,
NR_DEAD - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
-static const int NR_TYPES = ARRAY_SIZE(max_vals);
+static const int KBD_NR_TYPES = ARRAY_SIZE(kbd_max_vals);
static unsigned char ret_diacr[NR_DEAD] = {
'`', '\'', '^', '~', '"', ','
kfree(kbd->fn_handler);
out_func:
for (i = 0; i < ARRAY_SIZE(func_table); i++)
- if (kbd->func_table[i])
- kfree(kbd->func_table[i]);
+ kfree(kbd->func_table[i]);
kfree(kbd->func_table);
out_maps:
for (i = 0; i < ARRAY_SIZE(key_maps); i++)
- if (kbd->key_maps[i])
- kfree(kbd->key_maps[i]);
+ kfree(kbd->key_maps[i]);
kfree(kbd->key_maps);
out_kbd:
kfree(kbd);
kfree(kbd->accent_table);
kfree(kbd->fn_handler);
for (i = 0; i < ARRAY_SIZE(func_table); i++)
- if (kbd->func_table[i])
- kfree(kbd->func_table[i]);
+ kfree(kbd->func_table[i]);
kfree(kbd->func_table);
for (i = 0; i < ARRAY_SIZE(key_maps); i++)
- if (kbd->key_maps[i])
- kfree(kbd->key_maps[i]);
+ kfree(kbd->key_maps[i]);
kfree(kbd->key_maps);
kfree(kbd);
}
* Ioctl stuff.
*/
static int
-do_kdsk_ioctl(struct kbd_data *kbd, struct kbentry *user_kbe,
+do_kdsk_ioctl(struct kbd_data *kbd, struct kbentry __user *user_kbe,
int cmd, int perm)
{
struct kbentry tmp;
key_map = kbd->key_maps[tmp.kb_table];
if (key_map) {
val = U(key_map[tmp.kb_index]);
- if (KTYP(val) >= NR_TYPES)
+ if (KTYP(val) >= KBD_NR_TYPES)
val = K_HOLE;
} else
val = (tmp.kb_index ? K_HOLE : K_NOSUCHMAP);
break;
}
- if (KTYP(tmp.kb_value) >= NR_TYPES)
+ if (KTYP(tmp.kb_value) >= KBD_NR_TYPES)
return -EINVAL;
- if (KVAL(tmp.kb_value) > max_vals[KTYP(tmp.kb_value)])
+ if (KVAL(tmp.kb_value) > kbd_max_vals[KTYP(tmp.kb_value)])
return -EINVAL;
if (!(key_map = kbd->key_maps[tmp.kb_table])) {
}
static int
-do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry *u_kbs,
+do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry __user *u_kbs,
int cmd, int perm)
{
unsigned char kb_func;
return -EPERM;
len = strnlen_user(u_kbs->kb_string,
sizeof(u_kbs->kb_string) - 1);
- p = kmalloc(len, GFP_KERNEL);
+ if (!len)
+ return -EFAULT;
+ if (len > sizeof(u_kbs->kb_string) - 1)
+ return -EINVAL;
+ p = kmalloc(len + 1, GFP_KERNEL);
if (!p)
return -ENOMEM;
if (copy_from_user(p, u_kbs->kb_string, len)) {
return -EFAULT;
}
p[len] = 0;
- if (kbd->func_table[kb_func])
- kfree(kbd->func_table[kb_func]);
+ kfree(kbd->func_table[kb_func]);
kbd->func_table[kb_func] = p;
break;
}
kbd_ioctl(struct kbd_data *kbd, struct file *file,
unsigned int cmd, unsigned long arg)
{
- struct kbdiacrs *a;
+ struct kbdiacrs __user *a;
+ void __user *argp;
int ct, perm;
+ argp = (void __user *)arg;
+
/*
* To have permissions to do most of the vt ioctls, we either have
* to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
perm = current->signal->tty == kbd->tty || capable(CAP_SYS_TTY_CONFIG);
switch (cmd) {
case KDGKBTYPE:
- return put_user(KB_101, (char*) arg);
+ return put_user(KB_101, (char __user *)argp);
case KDGKBENT:
case KDSKBENT:
- return do_kdsk_ioctl(kbd, (struct kbentry *)arg, cmd, perm);
+ return do_kdsk_ioctl(kbd, argp, cmd, perm);
case KDGKBSENT:
case KDSKBSENT:
- return do_kdgkb_ioctl(kbd, (struct kbsentry *)arg, cmd, perm);
+ return do_kdgkb_ioctl(kbd, argp, cmd, perm);
case KDGKBDIACR:
- a = (struct kbdiacrs *) arg;
+ a = argp;
if (put_user(kbd->accent_table_size, &a->kb_cnt))
return -EFAULT;
return -EFAULT;
return 0;
case KDSKBDIACR:
- a = (struct kbdiacrs *) arg;
+ a = argp;
if (!perm)
return -EPERM;
if (get_user(ct, &a->kb_cnt))