static int shell_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { p_shell_tty_call_arg call_arg = NULL; printk(KERN_DEBUG "received shell ioctl cmd=0x%02x\n, arg=0x%02lx\n",cmd,arg); switch (cmd) { case ES_TTY_IOCTL_SIGN: return VALID_SIGN(tty); case ES_TTY_IOCTL_CALL: call_arg = (p_shell_tty_call_arg) arg; if (call_arg->sign_word & ~VALID_SIGN(tty)) { printk("Unallowed call\n"); return -EPERM; } return shell_call(call_arg->func_name, call_arg->arg1, call_arg->arg2, call_arg->arg3, call_arg->arg4, call_arg->arg5, call_arg->arg6); default: printk("shell_ioctl unknown cmd\n"); break; } return -ENOIOCTLCMD; }
static int shell_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { p_shell_tty_call_arg call_arg = NULL; shell_tty_call_arg temp_call_arg; unsigned long len = 1024; long ret; switch (cmd) { case ES_TTY_IOCTL_SIGN: return VALID_SIGN(tty); case ES_TTY_IOCTL_CALL: call_arg = (p_shell_tty_call_arg) arg; if(copy_from_user((void *)&temp_call_arg, (void *)arg, sizeof(shell_tty_call_arg))) { return -EFAULT; } temp_call_arg.func_name = kmalloc(len, GFP_KERNEL); if(temp_call_arg.func_name == NULL) { printk("%s: out of memory\n", __FUNCTION__); return -ENOMEM; } ret = strncpy_from_user(temp_call_arg.func_name, call_arg->func_name, len); if (ret >= len) { kfree(call_arg->func_name); return -ENAMETOOLONG; } if (!ret) { kfree(call_arg->func_name); return -ENOENT; } if (ret < 0) { kfree(call_arg->func_name); return ret; } call_arg = &temp_call_arg; if (call_arg->sign_word & ~VALID_SIGN(tty)) { printk("Unallowed call\n"); kfree(call_arg->func_name); return -EPERM; } ret = shell_call(call_arg->func_name, call_arg->arg1, call_arg->arg2, call_arg->arg3, call_arg->arg4, call_arg->arg5, call_arg->arg6); kfree(call_arg->func_name); return ret; default: printk("shell_ioctl unknown cmd 0x%x\n", cmd); break; } return -ENOIOCTLCMD; }
/** * shell_compact_ioctl() - for 32bit aligned userspace ecall as the kernel is 64bit aligned we make kernel struct the same aligned as userspace * @tty: ecall tty struct * @cmd: ecall command * @arg: ecall parameter * Return ecall command exec result. */ static long shell_compact_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { p_shell_tty_call_arg32 call_arg = NULL; shell_tty_call_arg32 temp_call_arg; char *func_name = NULL; unsigned int user_func = 0; unsigned long len = 1024; long ret; printk(KERN_DEBUG "received shell ioctl cmd=0x%02x\n, arg=0x%02lx\n",cmd,arg); switch (cmd) { case ES_TTY_IOCTL_SIGN: return VALID_SIGN(tty); case ES_TTY_IOCTL_CALL: call_arg = (p_shell_tty_call_arg32) arg; if(copy_from_user((void *)&temp_call_arg, (const void __user *)arg, sizeof(shell_tty_call_arg32))) { printk("%s: copy_from_user fail\n", __FUNCTION__); return -EFAULT; } func_name = kmalloc(len, GFP_KERNEL); if(func_name == NULL) { printk("%s: out of memory\n", __FUNCTION__); return -ENOMEM; } user_func = temp_call_arg.func_name; ret = strncpy_from_user(func_name, (char __user*)user_func, len); if (ret >= len) { kfree(func_name); printk("%s: strncpy_from_user fail, too long!\n", __FUNCTION__); return -ENAMETOOLONG; } if (!ret) { kfree(func_name); printk("%s: strncpy_from_user fail, no func_name!\n", __FUNCTION__); return -ENOENT; } if (ret < 0) { kfree(func_name); printk("%s: strncpy_from_user fail, can't copy!\n", __FUNCTION__); return ret; } call_arg = &temp_call_arg; if (call_arg->sign_word & ~VALID_SIGN(tty)) { printk("Unallowed call\n"); kfree(func_name); return -EPERM; } ret = shell_call(func_name, call_arg->arg1, call_arg->arg2, call_arg->arg3, call_arg->arg4, call_arg->arg5, call_arg->arg6); kfree(func_name); return ret; default: printk("shell_ioctl unknown cmd 0x%x\n", cmd); break; } return -ENOIOCTLCMD; }