static long msm_buspm_dev_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { return msm_buspm_dev_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); }
static inline void compat_nfs_string(struct nfs_string *dst, struct compat_nfs_string *src) { dst->data = compat_ptr(src->data); dst->len = src->len; }
int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) { int ret = 0; char *command = NULL; int cmd_num; int bytes_written = 0; android_wifi_priv_cmd priv_cmd; rtw_lock_suspend(); if (!ifr->ifr_data) { ret = -EINVAL; goto exit; } if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(android_wifi_priv_cmd))) { ret = -EFAULT; goto exit; } //DBG_871X("%s priv_cmd.buf=%p priv_cmd.total_len=%d priv_cmd.used_len=%d\n",__func__,priv_cmd.buf,priv_cmd.total_len,priv_cmd.used_len); command = rtw_zmalloc(priv_cmd.total_len); if (!command) { DBG_871X("%s: failed to allocate memory\n", __FUNCTION__); ret = -ENOMEM; goto exit; } if (!access_ok(VERIFY_READ, priv_cmd.buf, priv_cmd.total_len)){ DBG_871X("%s: failed to access memory\n", __FUNCTION__); ret = -EFAULT; goto exit; } /* compat makes it a u32 instead of char * */ #ifdef CONFIG_COMPAT if (copy_from_user(command, (void *)&priv_cmd.buf, priv_cmd.total_len)) { #else if (copy_from_user(command, (void *)priv_cmd.buf, priv_cmd.total_len)) { #endif ret = -EFAULT; goto exit; } DBG_871X("%s: Android private cmd \"%s\" on %s\n" , __FUNCTION__, command, ifr->ifr_name); cmd_num = rtw_android_cmdstr_to_num(command); switch(cmd_num) { case ANDROID_WIFI_CMD_START: //bytes_written = wl_android_wifi_on(net); goto response; case ANDROID_WIFI_CMD_SETFWPATH: goto response; } if (!g_wifi_on) { DBG_871X("%s: Ignore private cmd \"%s\" - iface %s is down\n" ,__FUNCTION__, command, ifr->ifr_name); ret = 0; goto exit; } switch(cmd_num) { case ANDROID_WIFI_CMD_STOP: //bytes_written = wl_android_wifi_off(net); break; case ANDROID_WIFI_CMD_SCAN_ACTIVE: //rtw_set_scan_mode((_adapter *)rtw_netdev_priv(net), SCAN_ACTIVE); #ifdef CONFIG_PLATFORM_MSTAR_TITANIA12 #ifdef CONFIG_IOCTL_CFG80211 (wdev_to_priv(net->ieee80211_ptr))->bandroid_scan = _TRUE; #endif //CONFIG_IOCTL_CFG80211 #endif //CONFIG_PLATFORM_MSTAR_TITANIA12 break; case ANDROID_WIFI_CMD_SCAN_PASSIVE: //rtw_set_scan_mode((_adapter *)rtw_netdev_priv(net), SCAN_PASSIVE); break; case ANDROID_WIFI_CMD_RSSI: bytes_written = rtw_android_get_rssi(net, command, priv_cmd.total_len); break; case ANDROID_WIFI_CMD_LINKSPEED: bytes_written = rtw_android_get_link_speed(net, command, priv_cmd.total_len); break; case ANDROID_WIFI_CMD_MACADDR: bytes_written = rtw_android_get_macaddr(net, command, priv_cmd.total_len); break; case ANDROID_WIFI_CMD_BLOCK: bytes_written = rtw_android_set_block(net, command, priv_cmd.total_len); break; case ANDROID_WIFI_CMD_RXFILTER_START: //bytes_written = net_os_set_packet_filter(net, 1); break; case ANDROID_WIFI_CMD_RXFILTER_STOP: //bytes_written = net_os_set_packet_filter(net, 0); break; case ANDROID_WIFI_CMD_RXFILTER_ADD: //int filter_num = *(command + strlen(CMD_RXFILTER_ADD) + 1) - '0'; //bytes_written = net_os_rxfilter_add_remove(net, TRUE, filter_num); break; case ANDROID_WIFI_CMD_RXFILTER_REMOVE: //int filter_num = *(command + strlen(CMD_RXFILTER_REMOVE) + 1) - '0'; //bytes_written = net_os_rxfilter_add_remove(net, FALSE, filter_num); break; case ANDROID_WIFI_CMD_BTCOEXSCAN_START: /* TBD: BTCOEXSCAN-START */ break; case ANDROID_WIFI_CMD_BTCOEXSCAN_STOP: /* TBD: BTCOEXSCAN-STOP */ break; case ANDROID_WIFI_CMD_BTCOEXMODE: #if 0 uint mode = *(command + strlen(CMD_BTCOEXMODE) + 1) - '0'; if (mode == 1) net_os_set_packet_filter(net, 0); /* DHCP starts */ else net_os_set_packet_filter(net, 1); /* DHCP ends */ #ifdef WL_CFG80211 bytes_written = wl_cfg80211_set_btcoex_dhcp(net, command); #endif #endif break; case ANDROID_WIFI_CMD_SETSUSPENDOPT: //bytes_written = wl_android_set_suspendopt(net, command, priv_cmd.total_len); break; case ANDROID_WIFI_CMD_SETBAND: { uint band = *(command + strlen("SETBAND") + 1) - '0'; _adapter* padapter = ( _adapter * ) rtw_netdev_priv(net); if (padapter->chip_type == RTL8192D) padapter->setband = band; break; } case ANDROID_WIFI_CMD_GETBAND: //bytes_written = wl_android_get_band(net, command, priv_cmd.total_len); break; case ANDROID_WIFI_CMD_COUNTRY: bytes_written = rtw_android_set_country(net, command, priv_cmd.total_len); break; #ifdef PNO_SUPPORT case ANDROID_WIFI_CMD_PNOSSIDCLR_SET: //bytes_written = dhd_dev_pno_reset(net); break; case ANDROID_WIFI_CMD_PNOSETUP_SET: //bytes_written = wl_android_set_pno_setup(net, command, priv_cmd.total_len); break; case ANDROID_WIFI_CMD_PNOENABLE_SET: //uint pfn_enabled = *(command + strlen(CMD_PNOENABLE_SET) + 1) - '0'; //bytes_written = dhd_dev_pno_enable(net, pfn_enabled); break; #endif case ANDROID_WIFI_CMD_P2P_DEV_ADDR: bytes_written = rtw_android_get_p2p_dev_addr(net, command, priv_cmd.total_len); break; case ANDROID_WIFI_CMD_P2P_SET_NOA: //int skip = strlen(CMD_P2P_SET_NOA) + 1; //bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip, priv_cmd.total_len - skip); break; case ANDROID_WIFI_CMD_P2P_GET_NOA: //bytes_written = wl_cfg80211_get_p2p_noa(net, command, priv_cmd.total_len); break; case ANDROID_WIFI_CMD_P2P_SET_PS: //int skip = strlen(CMD_P2P_SET_PS) + 1; //bytes_written = wl_cfg80211_set_p2p_ps(net, command + skip, priv_cmd.total_len - skip); break; #ifdef CONFIG_IOCTL_CFG80211 case ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE: { int skip = strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE]) + 3; bytes_written = rtw_cfg80211_set_mgnt_wpsp2pie(net, command + skip, priv_cmd.total_len - skip, *(command + skip - 2) - '0'); break; } #endif //CONFIG_IOCTL_CFG80211 #ifdef CONFIG_WFD case ANDROID_WIFI_CMD_WFD_ENABLE: { // Commented by Albert 2012/07/24 // We can enable the WFD function by using the following command: // wpa_cli driver wfd-enable struct wifi_display_info *pwfd_info; _adapter* padapter = ( _adapter * ) rtw_netdev_priv(net); pwfd_info = &padapter->wfd_info; if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 ) pwfd_info->wfd_enable = _TRUE; break; } case ANDROID_WIFI_CMD_WFD_DISABLE: { // Commented by Albert 2012/07/24 // We can disable the WFD function by using the following command: // wpa_cli driver wfd-disable struct wifi_display_info *pwfd_info; _adapter* padapter = ( _adapter * ) rtw_netdev_priv(net); pwfd_info = &padapter->wfd_info; if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 ) pwfd_info->wfd_enable = _FALSE; break; } case ANDROID_WIFI_CMD_WFD_SET_TCPPORT: { // Commented by Albert 2012/07/24 // We can set the tcp port number by using the following command: // wpa_cli driver wfd-set-tcpport = 554 struct wifi_display_info *pwfd_info; _adapter* padapter = ( _adapter * ) rtw_netdev_priv(net); pwfd_info = &padapter->wfd_info; if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 ) #ifdef CONFIG_COMPAT pwfd_info->rtsp_ctrlport = ( u16 ) get_int_from_command( compat_ptr(priv_cmd.buf) ); #else pwfd_info->rtsp_ctrlport = ( u16 ) get_int_from_command( priv_cmd.buf ); #endif break; } case ANDROID_WIFI_CMD_WFD_SET_MAX_TPUT: { break; } case ANDROID_WIFI_CMD_WFD_SET_DEVTYPE: { // Commented by Albert 2012/08/28 // Specify the WFD device type ( WFD source/primary sink ) struct wifi_display_info *pwfd_info; _adapter* padapter = ( _adapter * ) rtw_netdev_priv(net); pwfd_info = &padapter->wfd_info; if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 ) { #ifdef CONFIG_COMPAT pwfd_info->wfd_device_type = ( u8 ) get_int_from_command( compat_ptr(priv_cmd.buf) ); #else pwfd_info->wfd_device_type = ( u8 ) get_int_from_command( priv_cmd.buf ); #endif pwfd_info->wfd_device_type &= WFD_DEVINFO_DUAL; } break; } #endif default: DBG_871X("Unknown PRIVATE command %s - ignored\n", command); snprintf(command, 3, "OK"); bytes_written = strlen("OK"); } response: if (bytes_written >= 0) { if ((bytes_written == 0) && (priv_cmd.total_len > 0)) command[0] = '\0'; if (bytes_written >= priv_cmd.total_len) { DBG_871X("%s: bytes_written = %d\n", __FUNCTION__, bytes_written); bytes_written = priv_cmd.total_len; } else { bytes_written++; } priv_cmd.used_len = bytes_written; #ifdef CONFIG_COMPAT if (copy_to_user(compat_ptr(priv_cmd.buf), command, bytes_written)) { #else if (copy_to_user((void *)priv_cmd.buf, command, bytes_written)) { #endif DBG_871X("%s: failed to copy data to user buffer\n", __FUNCTION__); ret = -EFAULT; } } else { ret = bytes_written; } exit: rtw_unlock_suspend(); if (command) { kfree(command); } return ret; } /** * Functions for Android WiFi card detection */ #if defined(RTW_ENABLE_WIFI_CONTROL_FUNC) static int g_wifidev_registered = 0; static struct semaphore wifi_control_sem; static struct wifi_platform_data *wifi_control_data = NULL; static struct resource *wifi_irqres = NULL; static int wifi_add_dev(void); static void wifi_del_dev(void); int rtw_android_wifictrl_func_add(void) { int ret = 0; sema_init(&wifi_control_sem, 0); ret = wifi_add_dev(); if (ret) { DBG_871X("%s: platform_driver_register failed\n", __FUNCTION__); return ret; } g_wifidev_registered = 1; /* Waiting callback after platform_driver_register is done or exit with error */ if (down_timeout(&wifi_control_sem, msecs_to_jiffies(1000)) != 0) { ret = -EINVAL; DBG_871X("%s: platform_driver_register timeout\n", __FUNCTION__); } return ret; } void rtw_android_wifictrl_func_del(void) { if (g_wifidev_registered) { wifi_del_dev(); g_wifidev_registered = 0; } } void *wl_android_prealloc(int section, unsigned long size) { void *alloc_ptr = NULL; if (wifi_control_data && wifi_control_data->mem_prealloc) { alloc_ptr = wifi_control_data->mem_prealloc(section, size); if (alloc_ptr) { DBG_871X("success alloc section %d\n", section); if (size != 0L) memset(alloc_ptr, 0, size); return alloc_ptr; } } DBG_871X("can't alloc section %d\n", section); return NULL; }
long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { /* These are just misnamed, they actually get/put from/to user an int */ switch (cmd) { case EXT4_IOC32_GETFLAGS: cmd = EXT4_IOC_GETFLAGS; break; case EXT4_IOC32_SETFLAGS: cmd = EXT4_IOC_SETFLAGS; break; case EXT4_IOC32_GETVERSION: cmd = EXT4_IOC_GETVERSION; break; case EXT4_IOC32_SETVERSION: cmd = EXT4_IOC_SETVERSION; break; case EXT4_IOC32_GROUP_EXTEND: cmd = EXT4_IOC_GROUP_EXTEND; break; case EXT4_IOC32_GETVERSION_OLD: cmd = EXT4_IOC_GETVERSION_OLD; break; case EXT4_IOC32_SETVERSION_OLD: cmd = EXT4_IOC_SETVERSION_OLD; break; case EXT4_IOC32_GETRSVSZ: cmd = EXT4_IOC_GETRSVSZ; break; case EXT4_IOC32_SETRSVSZ: cmd = EXT4_IOC_SETRSVSZ; break; case EXT4_IOC32_GROUP_ADD: { struct compat_ext4_new_group_input __user *uinput; struct ext4_new_group_input input; mm_segment_t old_fs; int err; uinput = compat_ptr(arg); err = get_user(input.group, &uinput->group); err |= get_user(input.block_bitmap, &uinput->block_bitmap); err |= get_user(input.inode_bitmap, &uinput->inode_bitmap); err |= get_user(input.inode_table, &uinput->inode_table); err |= get_user(input.blocks_count, &uinput->blocks_count); err |= get_user(input.reserved_blocks, &uinput->reserved_blocks); if (err) return -EFAULT; old_fs = get_fs(); set_fs(KERNEL_DS); err = ext4_ioctl(file, EXT4_IOC_GROUP_ADD, (unsigned long) &input); set_fs(old_fs); return err; } case EXT4_IOC_MOVE_EXT: case EXT4_IOC_RESIZE_FS: case EXT4_IOC_PRECACHE_EXTENTS: case EXT4_IOC_SET_ENCRYPTION_POLICY: case EXT4_IOC_GET_ENCRYPTION_PWSALT: case EXT4_IOC_GET_ENCRYPTION_POLICY: break; default: return -ENOIOCTLCMD; } return ext4_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); }
COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, compat_ulong_t, arg) { mm_segment_t old_fs; struct flock f; long ret; unsigned int conv_cmd; switch (cmd) { case F_GETLK: case F_SETLK: case F_SETLKW: ret = get_compat_flock(&f, compat_ptr(arg)); if (ret != 0) break; old_fs = get_fs(); set_fs(KERNEL_DS); ret = sys_fcntl(fd, cmd, (unsigned long)&f); set_fs(old_fs); if (cmd == F_GETLK && ret == 0) { /* GETLK was successful and we need to return the data... * but it needs to fit in the compat structure. * l_start shouldn't be too big, unless the original * start + end is greater than COMPAT_OFF_T_MAX, in which * case the app was asking for trouble, so we return * -EOVERFLOW in that case. * l_len could be too big, in which case we just truncate it, * and only allow the app to see that part of the conflicting * lock that might make sense to it anyway */ if (f.l_start > COMPAT_OFF_T_MAX) ret = -EOVERFLOW; if (f.l_len > COMPAT_OFF_T_MAX) f.l_len = COMPAT_OFF_T_MAX; if (ret == 0) ret = put_compat_flock(&f, compat_ptr(arg)); } break; case F_GETLK64: case F_SETLK64: case F_SETLKW64: case F_OFD_GETLK: case F_OFD_SETLK: case F_OFD_SETLKW: ret = get_compat_flock64(&f, compat_ptr(arg)); if (ret != 0) break; old_fs = get_fs(); set_fs(KERNEL_DS); conv_cmd = convert_fcntl_cmd(cmd); ret = sys_fcntl(fd, conv_cmd, (unsigned long)&f); set_fs(old_fs); if ((conv_cmd == F_GETLK || conv_cmd == F_OFD_GETLK) && ret == 0) { /* need to return lock information - see above for commentary */ if (f.l_start > COMPAT_LOFF_T_MAX) ret = -EOVERFLOW; if (f.l_len > COMPAT_LOFF_T_MAX) f.l_len = COMPAT_LOFF_T_MAX; if (ret == 0) ret = put_compat_flock64(&f, compat_ptr(arg)); } break; default: ret = sys_fcntl(fd, cmd, arg); break; } return ret; }
asmlinkage long compat_sys_socketcall(int call, u32 __user *args) { int ret; u32 a[6]; u32 a0, a1; if (call < SYS_SOCKET || call > SYS_SENDMMSG) return -EINVAL; if (copy_from_user(a, args, nas[call])) return -EFAULT; a0 = a[0]; a1 = a[1]; switch (call) { case SYS_SOCKET: ret = sys_socket(a0, a1, a[2]); break; case SYS_BIND: ret = sys_bind(a0, compat_ptr(a1), a[2]); break; case SYS_CONNECT: ret = sys_connect(a0, compat_ptr(a1), a[2]); break; case SYS_LISTEN: ret = sys_listen(a0, a1); break; case SYS_ACCEPT: ret = sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), 0); break; case SYS_GETSOCKNAME: ret = sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2])); break; case SYS_GETPEERNAME: ret = sys_getpeername(a0, compat_ptr(a1), compat_ptr(a[2])); break; case SYS_SOCKETPAIR: ret = sys_socketpair(a0, a1, a[2], compat_ptr(a[3])); break; case SYS_SEND: ret = sys_send(a0, compat_ptr(a1), a[2], a[3]); break; case SYS_SENDTO: ret = sys_sendto(a0, compat_ptr(a1), a[2], a[3], compat_ptr(a[4]), a[5]); break; case SYS_RECV: ret = compat_sys_recv(a0, compat_ptr(a1), a[2], a[3]); break; case SYS_RECVFROM: ret = compat_sys_recvfrom(a0, compat_ptr(a1), a[2], a[3], compat_ptr(a[4]), compat_ptr(a[5])); break; case SYS_SHUTDOWN: ret = sys_shutdown(a0, a1); break; case SYS_SETSOCKOPT: ret = compat_sys_setsockopt(a0, a1, a[2], compat_ptr(a[3]), a[4]); break; case SYS_GETSOCKOPT: ret = compat_sys_getsockopt(a0, a1, a[2], compat_ptr(a[3]), compat_ptr(a[4])); break; case SYS_SENDMSG: ret = compat_sys_sendmsg(a0, compat_ptr(a1), a[2]); break; case SYS_SENDMMSG: ret = compat_sys_sendmmsg(a0, compat_ptr(a1), a[2], a[3]); break; case SYS_RECVMSG: ret = compat_sys_recvmsg(a0, compat_ptr(a1), a[2]); break; case SYS_RECVMMSG: ret = compat_sys_recvmmsg(a0, compat_ptr(a1), a[2], a[3], compat_ptr(a[4])); break; case SYS_ACCEPT4: ret = sys_accept4(a0, compat_ptr(a1), compat_ptr(a[2]), a[3]); break; default: ret = -EINVAL; break; } return ret; }
static long vhost_net_compat_ioctl(struct file *f, unsigned int ioctl, unsigned long arg) { return vhost_net_ioctl(f, ioctl, (unsigned long)compat_ptr(arg)); }
/* do not call the lower */ AuDbg("0x%x\n", cmd); err = -ENOTTY; } AuTraceErr(err); return err; } #ifdef CONFIG_COMPAT long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg) { long err; switch (cmd) { case AUFS_CTL_RDU: case AUFS_CTL_RDU_INO: err = au_rdu_compat_ioctl(file, cmd, arg); break; default: err = aufs_ioctl_dir(file, cmd, arg); } AuTraceErr(err); return err; } #if 0 /* unused yet */ long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg) { return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg)); }
static long vsock_dev_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { return vsock_dev_do_ioctl(filp, cmd, compat_ptr(arg)); }
static int compat_fd_ioctl(struct inode *inode, struct file *file, struct gendisk *disk, unsigned int cmd, unsigned long arg) { mm_segment_t old_fs = get_fs(); void *karg = NULL; unsigned int kcmd = 0; int i, err; for (i = 0; i < NR_FD_IOCTL_TRANS; i++) if (cmd == fd_ioctl_trans_table[i].cmd32) { kcmd = fd_ioctl_trans_table[i].cmd; break; } if (!kcmd) return -EINVAL; switch (cmd) { case FDSETPRM32: case FDDEFPRM32: case FDGETPRM32: { compat_uptr_t name; struct compat_floppy_struct __user *uf; struct floppy_struct *f; uf = compat_ptr(arg); f = karg = kmalloc(sizeof(struct floppy_struct), GFP_KERNEL); if (!karg) return -ENOMEM; if (cmd == FDGETPRM32) break; err = __get_user(f->size, &uf->size); err |= __get_user(f->sect, &uf->sect); err |= __get_user(f->head, &uf->head); err |= __get_user(f->track, &uf->track); err |= __get_user(f->stretch, &uf->stretch); err |= __get_user(f->gap, &uf->gap); err |= __get_user(f->rate, &uf->rate); err |= __get_user(f->spec1, &uf->spec1); err |= __get_user(f->fmt_gap, &uf->fmt_gap); err |= __get_user(name, &uf->name); f->name = compat_ptr(name); if (err) { err = -EFAULT; goto out; } break; } case FDSETDRVPRM32: case FDGETDRVPRM32: { struct compat_floppy_drive_params __user *uf; struct floppy_drive_params *f; uf = compat_ptr(arg); f = karg = kmalloc(sizeof(struct floppy_drive_params), GFP_KERNEL); if (!karg) return -ENOMEM; if (cmd == FDGETDRVPRM32) break; err = __get_user(f->cmos, &uf->cmos); err |= __get_user(f->max_dtr, &uf->max_dtr); err |= __get_user(f->hlt, &uf->hlt); err |= __get_user(f->hut, &uf->hut); err |= __get_user(f->srt, &uf->srt); err |= __get_user(f->spinup, &uf->spinup); err |= __get_user(f->spindown, &uf->spindown); err |= __get_user(f->spindown_offset, &uf->spindown_offset); err |= __get_user(f->select_delay, &uf->select_delay); err |= __get_user(f->rps, &uf->rps); err |= __get_user(f->tracks, &uf->tracks); err |= __get_user(f->timeout, &uf->timeout); err |= __get_user(f->interleave_sect, &uf->interleave_sect); err |= __copy_from_user(&f->max_errors, &uf->max_errors, sizeof(f->max_errors)); err |= __get_user(f->flags, &uf->flags); err |= __get_user(f->read_track, &uf->read_track); err |= __copy_from_user(f->autodetect, uf->autodetect, sizeof(f->autodetect)); err |= __get_user(f->checkfreq, &uf->checkfreq); err |= __get_user(f->native_format, &uf->native_format); if (err) { err = -EFAULT; goto out; } break; } case FDGETDRVSTAT32: case FDPOLLDRVSTAT32: karg = kmalloc(sizeof(struct floppy_drive_struct), GFP_KERNEL); if (!karg) return -ENOMEM; break; case FDGETFDCSTAT32: karg = kmalloc(sizeof(struct floppy_fdc_state), GFP_KERNEL); if (!karg) return -ENOMEM; break; case FDWERRORGET32: karg = kmalloc(sizeof(struct floppy_write_errors), GFP_KERNEL); if (!karg) return -ENOMEM; break; default: return -EINVAL; } set_fs(KERNEL_DS); err = blkdev_driver_ioctl(inode, file, disk, kcmd, (unsigned long)karg); set_fs(old_fs); if (err) goto out; switch (cmd) { case FDGETPRM32: { struct floppy_struct *f = karg; struct compat_floppy_struct __user *uf = compat_ptr(arg); err = __put_user(f->size, &uf->size); err |= __put_user(f->sect, &uf->sect); err |= __put_user(f->head, &uf->head); err |= __put_user(f->track, &uf->track); err |= __put_user(f->stretch, &uf->stretch); err |= __put_user(f->gap, &uf->gap); err |= __put_user(f->rate, &uf->rate); err |= __put_user(f->spec1, &uf->spec1); err |= __put_user(f->fmt_gap, &uf->fmt_gap); err |= __put_user((u64)f->name, (compat_caddr_t __user *)&uf->name); break; } case FDGETDRVPRM32: { struct compat_floppy_drive_params __user *uf; struct floppy_drive_params *f = karg; uf = compat_ptr(arg); err = __put_user(f->cmos, &uf->cmos); err |= __put_user(f->max_dtr, &uf->max_dtr); err |= __put_user(f->hlt, &uf->hlt); err |= __put_user(f->hut, &uf->hut); err |= __put_user(f->srt, &uf->srt); err |= __put_user(f->spinup, &uf->spinup); err |= __put_user(f->spindown, &uf->spindown); err |= __put_user(f->spindown_offset, &uf->spindown_offset); err |= __put_user(f->select_delay, &uf->select_delay); err |= __put_user(f->rps, &uf->rps); err |= __put_user(f->tracks, &uf->tracks); err |= __put_user(f->timeout, &uf->timeout); err |= __put_user(f->interleave_sect, &uf->interleave_sect); err |= __copy_to_user(&uf->max_errors, &f->max_errors, sizeof(f->max_errors)); err |= __put_user(f->flags, &uf->flags); err |= __put_user(f->read_track, &uf->read_track); err |= __copy_to_user(uf->autodetect, f->autodetect, sizeof(f->autodetect)); err |= __put_user(f->checkfreq, &uf->checkfreq); err |= __put_user(f->native_format, &uf->native_format); break; } case FDGETDRVSTAT32: case FDPOLLDRVSTAT32: { struct compat_floppy_drive_struct __user *uf; struct floppy_drive_struct *f = karg; uf = compat_ptr(arg); err = __put_user(f->flags, &uf->flags); err |= __put_user(f->spinup_date, &uf->spinup_date); err |= __put_user(f->select_date, &uf->select_date); err |= __put_user(f->first_read_date, &uf->first_read_date); err |= __put_user(f->probed_format, &uf->probed_format); err |= __put_user(f->track, &uf->track); err |= __put_user(f->maxblock, &uf->maxblock); err |= __put_user(f->maxtrack, &uf->maxtrack); err |= __put_user(f->generation, &uf->generation); err |= __put_user(f->keep_data, &uf->keep_data); err |= __put_user(f->fd_ref, &uf->fd_ref); err |= __put_user(f->fd_device, &uf->fd_device); err |= __put_user(f->last_checked, &uf->last_checked); err |= __put_user((u64)f->dmabuf, &uf->dmabuf); err |= __put_user((u64)f->bufblocks, &uf->bufblocks); break; } case FDGETFDCSTAT32: { struct compat_floppy_fdc_state __user *uf; struct floppy_fdc_state *f = karg; uf = compat_ptr(arg); err = __put_user(f->spec1, &uf->spec1); err |= __put_user(f->spec2, &uf->spec2); err |= __put_user(f->dtr, &uf->dtr); err |= __put_user(f->version, &uf->version); err |= __put_user(f->dor, &uf->dor); err |= __put_user(f->address, &uf->address); err |= __copy_to_user((char __user *)&uf->address + sizeof(uf->address), (char *)&f->address + sizeof(f->address), sizeof(int)); err |= __put_user(f->driver_version, &uf->driver_version); err |= __copy_to_user(uf->track, f->track, sizeof(f->track)); break; } case FDWERRORGET32: { struct compat_floppy_write_errors __user *uf; struct floppy_write_errors *f = karg; uf = compat_ptr(arg); err = __put_user(f->write_errors, &uf->write_errors); err |= __put_user(f->first_error_sector, &uf->first_error_sector); err |= __put_user(f->first_error_generation, &uf->first_error_generation); err |= __put_user(f->last_error_sector, &uf->last_error_sector); err |= __put_user(f->last_error_generation, &uf->last_error_generation); err |= __put_user(f->badness, &uf->badness); break; } default: break; } if (err) err = -EFAULT; out: kfree(karg); return err; }
static int compat_put_u64(unsigned long arg, u64 val) { return put_user(val, (compat_u64 __user *)compat_ptr(arg)); }
static int compat_put_long(unsigned long arg, long val) { return put_user(val, (compat_long_t __user *)compat_ptr(arg)); }
static int compat_put_int(unsigned long arg, int val) { return put_user(val, (compat_int_t __user *)compat_ptr(arg)); }
static int compat_put_ushort(unsigned long arg, unsigned short val) { return put_user(val, (unsigned short __user *)compat_ptr(arg)); }
static long broadcast_tdmb_compat_ioctl_control(struct file *flip, unsigned int cmd, unsigned long arg) { return broadcast_tdmb_ioctl_control(flip, cmd, (unsigned long)compat_ptr(arg)); }
/* * The key control system call, 32-bit compatibility version for 64-bit archs * * This should only be called if the 64-bit arch uses weird pointers in 32-bit * mode or doesn't guarantee that the top 32-bits of the argument registers on * taking a 32-bit syscall are zero. If you can, you should call sys_keyctl() * directly. */ asmlinkage long compat_sys_keyctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5) { switch (option) { case KEYCTL_GET_KEYRING_ID: return keyctl_get_keyring_ID(arg2, arg3); case KEYCTL_JOIN_SESSION_KEYRING: return keyctl_join_session_keyring(compat_ptr(arg2)); case KEYCTL_UPDATE: return keyctl_update_key(arg2, compat_ptr(arg3), arg4); case KEYCTL_REVOKE: return keyctl_revoke_key(arg2); case KEYCTL_DESCRIBE: return keyctl_describe_key(arg2, compat_ptr(arg3), arg4); case KEYCTL_CLEAR: return keyctl_keyring_clear(arg2); case KEYCTL_LINK: return keyctl_keyring_link(arg2, arg3); case KEYCTL_UNLINK: return keyctl_keyring_unlink(arg2, arg3); case KEYCTL_SEARCH: return keyctl_keyring_search(arg2, compat_ptr(arg3), compat_ptr(arg4), arg5); case KEYCTL_READ: return keyctl_read_key(arg2, compat_ptr(arg3), arg4); case KEYCTL_CHOWN: return keyctl_chown_key(arg2, arg3, arg4); case KEYCTL_SETPERM: return keyctl_setperm_key(arg2, arg3); case KEYCTL_INSTANTIATE: return keyctl_instantiate_key(arg2, compat_ptr(arg3), arg4, arg5); case KEYCTL_NEGATE: return keyctl_negate_key(arg2, arg3, arg4); case KEYCTL_SET_REQKEY_KEYRING: return keyctl_set_reqkey_keyring(arg2); case KEYCTL_SET_TIMEOUT: return keyctl_set_timeout(arg2, arg3); case KEYCTL_ASSUME_AUTHORITY: return keyctl_assume_authority(arg2); case KEYCTL_GET_SECURITY: return keyctl_get_security(arg2, compat_ptr(arg3), arg4); case KEYCTL_SESSION_TO_PARENT: return keyctl_session_to_parent(); case KEYCTL_REJECT: return keyctl_reject_key(arg2, arg3, arg4, arg5); case KEYCTL_INSTANTIATE_IOV: return compat_keyctl_instantiate_key_iov( arg2, compat_ptr(arg3), arg4, arg5); default: return -EOPNOTSUPP; } }
static long mei_compat_ioctl(struct file *file, unsigned int cmd, unsigned long data) { return mei_ioctl(file, cmd, (unsigned long)compat_ptr(data)); }
long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, u32 fifth) { int version; version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; switch (call) { case SEMTIMEDOP: if (fifth) /* sign extend semid */ return compat_sys_semtimedop((int)first, compat_ptr(ptr), second, compat_ptr(fifth)); /* else fall through for normal semop() */ case SEMOP: /* struct sembuf is the same on 32 and 64bit :)) */ /* sign extend semid */ return sys_semtimedop((int)first, compat_ptr(ptr), second, NULL); case SEMGET: /* sign extend key, nsems */ return sys_semget((int)first, (int)second, third); case SEMCTL: /* sign extend semid, semnum */ return compat_sys_semctl((int)first, (int)second, third, compat_ptr(ptr)); case MSGSND: /* sign extend msqid */ return compat_sys_msgsnd((int)first, (int)second, third, compat_ptr(ptr)); case MSGRCV: /* sign extend msqid, msgtyp */ return compat_sys_msgrcv((int)first, second, (int)fifth, third, version, compat_ptr(ptr)); case MSGGET: /* sign extend key */ return sys_msgget((int)first, second); case MSGCTL: /* sign extend msqid */ return compat_sys_msgctl((int)first, second, compat_ptr(ptr)); case SHMAT: /* sign extend shmid */ return compat_sys_shmat((int)first, second, third, version, compat_ptr(ptr)); case SHMDT: return sys_shmdt(compat_ptr(ptr)); case SHMGET: /* sign extend key_t */ return sys_shmget((int)first, second, third); case SHMCTL: /* sign extend shmid */ return compat_sys_shmctl((int)first, second, compat_ptr(ptr)); default: return -ENOSYS; } return -ENOSYS; }
static int compat_put_ulong(compat_ulong_t val, unsigned long arg) { return put_user(val, (compat_ulong_t __user *)compat_ptr(arg)); }
long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { long ret; if (!filp->f_op || !filp->f_op->unlocked_ioctl) return -ENOTTY; switch (cmd) { case COMPAT_ION_IOC_ALLOC: { struct compat_ion_allocation_data __user *data32; struct ion_allocation_data __user *data; int err; data32 = compat_ptr(arg); data = compat_alloc_user_space(sizeof(*data)); if (data == NULL) return -EFAULT; err = compat_get_ion_allocation_data(data32, data); if (err) return err; ret = filp->f_op->unlocked_ioctl(filp, ION_IOC_ALLOC, (unsigned long)data); err = compat_put_ion_allocation_data(data32, data); return ret ? ret : err; } case COMPAT_ION_IOC_FREE: { struct compat_ion_allocation_data __user *data32; struct ion_allocation_data __user *data; int err; data32 = compat_ptr(arg); data = compat_alloc_user_space(sizeof(*data)); if (data == NULL) return -EFAULT; err = compat_get_ion_allocation_data(data32, data); if (err) return err; return filp->f_op->unlocked_ioctl(filp, ION_IOC_FREE, (unsigned long)data); } case COMPAT_ION_IOC_CUSTOM: { struct compat_ion_custom_data __user *data32; struct ion_custom_data __user *data; int err; data32 = compat_ptr(arg); data = compat_alloc_user_space(sizeof(*data)); if (data == NULL) return -EFAULT; err = compat_get_ion_custom_data(data32, data); if (err) return err; return filp->f_op->unlocked_ioctl(filp, ION_IOC_CUSTOM, (unsigned long)data); } case ION_IOC_SHARE: case ION_IOC_MAP: case ION_IOC_IMPORT: case ION_IOC_SYNC: return filp->f_op->unlocked_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); default: return -ENOIOCTLCMD; } }
static long autofs_dev_ioctl_compat(struct file *file, uint command, ulong u) { return (long) autofs_dev_ioctl(file, command, (ulong) compat_ptr(u)); }
static int do_netfilter_replace(int fd, int level, int optname, char __user *optval, int optlen) { struct compat_ipt_replace __user *urepl; struct ipt_replace __user *repl_nat; char name[IPT_TABLE_MAXNAMELEN]; u32 origsize, tmp32, num_counters; unsigned int repl_nat_size; int ret; int i; compat_uptr_t ucntrs; urepl = (struct compat_ipt_replace __user *)optval; if (get_user(origsize, &urepl->size)) return -EFAULT; /* Hack: Causes ipchains to give correct error msg --RR */ if (optlen != sizeof(*urepl) + origsize) return -ENOPROTOOPT; /* XXX Assumes that size of ipt_entry is the same both in * native and compat environments. */ repl_nat_size = sizeof(*repl_nat) + origsize; repl_nat = compat_alloc_user_space(repl_nat_size); ret = -EFAULT; if (put_user(origsize, &repl_nat->size)) goto out; if (!access_ok(VERIFY_READ, urepl, optlen) || !access_ok(VERIFY_WRITE, repl_nat, optlen)) goto out; if (__copy_from_user(name, urepl->name, sizeof(urepl->name)) || __copy_to_user(repl_nat->name, name, sizeof(repl_nat->name))) goto out; if (__get_user(tmp32, &urepl->valid_hooks) || __put_user(tmp32, &repl_nat->valid_hooks)) goto out; if (__get_user(tmp32, &urepl->num_entries) || __put_user(tmp32, &repl_nat->num_entries)) goto out; if (__get_user(num_counters, &urepl->num_counters) || __put_user(num_counters, &repl_nat->num_counters)) goto out; if (__get_user(ucntrs, &urepl->counters) || __put_user(compat_ptr(ucntrs), &repl_nat->counters)) goto out; if (__copy_in_user(&repl_nat->entries[0], &urepl->entries[0], origsize)) goto out; for (i = 0; i < NF_IP_NUMHOOKS; i++) { if (__get_user(tmp32, &urepl->hook_entry[i]) || __put_user(tmp32, &repl_nat->hook_entry[i]) || __get_user(tmp32, &urepl->underflow[i]) || __put_user(tmp32, &repl_nat->underflow[i])) goto out; } /* * Since struct ipt_counters just contains two u_int64_t members * we can just do the access_ok check here and pass the (converted) * pointer into the standard syscall. We hope that the pointer is * not misaligned ... */ if (!access_ok(VERIFY_WRITE, compat_ptr(ucntrs), num_counters * sizeof(struct ipt_counters))) goto out; ret = sys_setsockopt(fd, level, optname, (char __user *)repl_nat, repl_nat_size); out: return ret; }
static long compat_fimg2d_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) { switch (cmd) { case COMPAT_FIMG2D_BITBLT_BLIT: { struct compat_fimg2d_blit __user *data32; struct fimg2d_blit __user *data; struct mm_struct *mm; enum blit_op op; enum blit_sync sync; enum fimg2d_qos_level qos_lv; compat_uint_t seq_no; unsigned long stack_cursor = 0; int err; mm = get_task_mm(current); if (!mm) { fimg2d_err("no mm for ctx\n"); return -ENXIO; } data32 = compat_ptr(arg); data = compat_alloc_user_space(sizeof(*data)); if (!data) { fimg2d_err("failed to allocate user compat space\n"); mmput(mm); return -ENOMEM; } stack_cursor += sizeof(*data); memset(data, 0, sizeof(*data)); err = get_user(op, &data32->op); err |= put_user(op, &data->op); if (err) { fimg2d_err("failed to get compat data\n"); mmput(mm); return err; } err = compat_get_fimg2d_param(&data->param, &data32->param); if (err) { fimg2d_err("failed to get compat data\n"); mmput(mm); return err; } if (data32->src) { data->src = compat_alloc_user_space(sizeof(*data->src) + stack_cursor); if (!data->src) { fimg2d_err("failed to allocate user compat space\n"); mmput(mm); return -ENOMEM; } stack_cursor += sizeof(*data->src); err = compat_get_fimg2d_image(data->src, data32->src); if (err) { fimg2d_err("failed to get compat data\n"); mmput(mm); return err; } } if (data32->msk) { data->msk = compat_alloc_user_space(sizeof(*data->msk) + stack_cursor); if (!data->msk) { fimg2d_err("failed to allocate user compat space\n"); mmput(mm); return -ENOMEM; } stack_cursor += sizeof(*data->msk); err = compat_get_fimg2d_image(data->msk, data32->msk); if (err) { fimg2d_err("failed to get compat data\n"); mmput(mm); return err; } } if (data32->tmp) { data->tmp = compat_alloc_user_space(sizeof(*data->tmp) + stack_cursor); if (!data->tmp) { fimg2d_err("failed to allocate user compat space\n"); mmput(mm); return -ENOMEM; } stack_cursor += sizeof(*data->tmp); err = compat_get_fimg2d_image(data->tmp, data32->tmp); if (err) { fimg2d_err("failed to get compat data\n"); mmput(mm); return err; } } if (data32->dst) { data->dst = compat_alloc_user_space(sizeof(*data->dst) + stack_cursor); if (!data->dst) { fimg2d_err("failed to allocate user compat space\n"); mmput(mm); return -ENOMEM; } stack_cursor += sizeof(*data->dst); err = compat_get_fimg2d_image(data->dst, data32->dst); if (err) { fimg2d_err("failed to get compat data\n"); mmput(mm); return err; } } err = get_user(sync, &data32->sync); err |= put_user(sync, &data->sync); if (err) { fimg2d_err("failed to get compat data\n"); mmput(mm); return err; } err = get_user(seq_no, &data32->seq_no); err |= put_user(seq_no, &data->seq_no); if (err) { fimg2d_err("failed to get compat data\n"); mmput(mm); return err; } err = get_user(qos_lv, &data32->qos_lv); err |= put_user(qos_lv, &data->qos_lv); if (err) { fimg2d_err("failed to get compat data\n"); mmput(mm); return err; } err = file->f_op->unlocked_ioctl(file, FIMG2D_BITBLT_BLIT, (unsigned long)data); mmput(mm); return err; } case COMPAT_FIMG2D_BITBLT_VERSION: { struct compat_fimg2d_version __user *data32; struct fimg2d_version __user *data; compat_uint_t i; int err; data32 = compat_ptr(arg); data = compat_alloc_user_space(sizeof(*data)); if (!data) { fimg2d_err("failed to allocate user compat space\n"); return -ENOMEM; } err = get_user(i, &data32->hw); err |= put_user(i, &data->hw); err |= get_user(i, &data32->sw); err |= put_user(i, &data->sw); if (err) return err; return file->f_op->unlocked_ioctl(file, FIMG2D_BITBLT_VERSION, (unsigned long)data); } case FIMG2D_BITBLT_ACTIVATE: { return file->f_op->unlocked_ioctl(file, FIMG2D_BITBLT_ACTIVATE, arg); } default: fimg2d_err("unknown ioctl\n"); return -EINVAL; } }
static int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp) { struct sensorb_cfg_data32 *cdata = (struct sensorb_cfg_data32 *)argp; int32_t rc = 0; int32_t i = 0; mutex_lock(s_ctrl->msm_sensor_mutex); CDBG("%s:%d %s cfgtype = %d\n", __func__, __LINE__, s_ctrl->sensordata->sensor_name, cdata->cfgtype); switch (cdata->cfgtype) { case CFG_GET_SENSOR_INFO: memcpy(cdata->cfg.sensor_info.sensor_name, s_ctrl->sensordata->sensor_name, sizeof(cdata->cfg.sensor_info.sensor_name)); cdata->cfg.sensor_info.session_id = s_ctrl->sensordata->sensor_info->session_id; for (i = 0; i < SUB_MODULE_MAX; i++) cdata->cfg.sensor_info.subdev_id[i] = s_ctrl->sensordata->sensor_info->subdev_id[i]; cdata->cfg.sensor_info.is_mount_angle_valid = s_ctrl->sensordata->sensor_info->is_mount_angle_valid; cdata->cfg.sensor_info.sensor_mount_angle = s_ctrl->sensordata->sensor_info->sensor_mount_angle; cdata->cfg.sensor_info.position = s_ctrl->sensordata->sensor_info->position; cdata->cfg.sensor_info.modes_supported = s_ctrl->sensordata->sensor_info->modes_supported; CDBG("%s:%d sensor name %s\n", __func__, __LINE__, cdata->cfg.sensor_info.sensor_name); CDBG("%s:%d session id %d\n", __func__, __LINE__, cdata->cfg.sensor_info.session_id); for (i = 0; i < SUB_MODULE_MAX; i++) CDBG("%s:%d subdev_id[%d] %d\n", __func__, __LINE__, i, cdata->cfg.sensor_info.subdev_id[i]); CDBG("%s:%d mount angle valid %d value %d\n", __func__, __LINE__, cdata->cfg.sensor_info.is_mount_angle_valid, cdata->cfg.sensor_info.sensor_mount_angle); break; case CFG_GET_SENSOR_INIT_PARAMS: cdata->cfg.sensor_init_params.modes_supported = s_ctrl->sensordata->sensor_info->modes_supported; cdata->cfg.sensor_init_params.position = s_ctrl->sensordata->sensor_info->position; cdata->cfg.sensor_init_params.sensor_mount_angle = s_ctrl->sensordata->sensor_info->sensor_mount_angle; CDBG("%s:%d init params mode %d pos %d mount %d\n", __func__, __LINE__, cdata->cfg.sensor_init_params.modes_supported, cdata->cfg.sensor_init_params.position, cdata->cfg.sensor_init_params.sensor_mount_angle); break; case CFG_WRITE_I2C_ARRAY: { struct msm_camera_i2c_reg_setting32 conf_array32; struct msm_camera_i2c_reg_setting conf_array; struct msm_camera_i2c_reg_array *reg_setting = NULL; if (s_ctrl->sensor_state != MSM_SENSOR_POWER_UP) { pr_err("%s:%d failed: invalid state %d\n", __func__, __LINE__, s_ctrl->sensor_state); rc = -EFAULT; break; } if (copy_from_user(&conf_array32, (void *)compat_ptr(cdata->cfg.setting), sizeof(struct msm_camera_i2c_reg_setting32))) { pr_err("%s:%d failed\n", __func__, __LINE__); rc = -EFAULT; break; } conf_array.addr_type = conf_array32.addr_type; conf_array.data_type = conf_array32.data_type; conf_array.delay = conf_array32.delay; conf_array.size = conf_array32.size; conf_array.reg_setting = compat_ptr(conf_array32.reg_setting); if (!conf_array.size || conf_array.size > I2C_SEQ_REG_DATA_MAX) { pr_err("%s:%d failed\n", __func__, __LINE__); rc = -EFAULT; break; } reg_setting = kzalloc(conf_array.size * (sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL); if (!reg_setting) { pr_err("%s:%d failed\n", __func__, __LINE__); rc = -ENOMEM; break; } if (copy_from_user(reg_setting, (void *)(conf_array.reg_setting), conf_array.size * sizeof(struct msm_camera_i2c_reg_array))) { pr_err("%s:%d failed\n", __func__, __LINE__); kfree(reg_setting); rc = -EFAULT; break; } conf_array.reg_setting = reg_setting; rc = s_ctrl->sensor_i2c_client->i2c_func_tbl-> i2c_write_table(s_ctrl->sensor_i2c_client, &conf_array); kfree(reg_setting); break; } case CFG_POWER_UP: if (s_ctrl->sensor_state != MSM_SENSOR_POWER_DOWN) { pr_err("%s:%d failed: invalid state %d\n", __func__, __LINE__, s_ctrl->sensor_state); rc = -EFAULT; break; } if (s_ctrl->func_tbl->sensor_power_up) { if (s_ctrl->sensordata->misc_regulator) msm_sensor_misc_regulator(s_ctrl, 1); rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl); if (rc < 0) { pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc); break; } s_ctrl->sensor_state = MSM_SENSOR_POWER_UP; CDBG("%s:%d sensor state %d\n", __func__, __LINE__, s_ctrl->sensor_state); } else { rc = -EFAULT; } break; case CFG_POWER_DOWN: kfree(s_ctrl->stop_setting.reg_setting); s_ctrl->stop_setting.reg_setting = NULL; if (s_ctrl->sensor_state != MSM_SENSOR_POWER_UP) { pr_err("%s:%d failed: invalid state %d\n", __func__, __LINE__, s_ctrl->sensor_state); rc = -EFAULT; break; } if (s_ctrl->func_tbl->sensor_power_down) { if (s_ctrl->sensordata->misc_regulator) msm_sensor_misc_regulator(s_ctrl, 0); rc = s_ctrl->func_tbl->sensor_power_down(s_ctrl); if (rc < 0) { pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc); break; } s_ctrl->sensor_state = MSM_SENSOR_POWER_DOWN; CDBG("%s:%d sensor state %d\n", __func__, __LINE__, s_ctrl->sensor_state); } else { rc = -EFAULT; } break; case CFG_SET_STOP_STREAM_SETTING: { struct msm_camera_i2c_reg_setting32 stop_setting32; struct msm_camera_i2c_reg_setting *stop_setting = &s_ctrl->stop_setting; struct msm_camera_i2c_reg_array *reg_setting = NULL; if (copy_from_user(&stop_setting32, (void *)compat_ptr((cdata->cfg.setting)), sizeof(struct msm_camera_i2c_reg_setting32))) { pr_err("%s:%d failed\n", __func__, __LINE__); rc = -EFAULT; break; } stop_setting->addr_type = stop_setting32.addr_type; stop_setting->data_type = stop_setting32.data_type; stop_setting->delay = stop_setting32.delay; stop_setting->size = stop_setting32.size; reg_setting = compat_ptr(stop_setting32.reg_setting); if (!stop_setting->size) { pr_err("%s:%d failed\n", __func__, __LINE__); rc = -EFAULT; break; } stop_setting->reg_setting = kzalloc(stop_setting->size * (sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL); if (!stop_setting->reg_setting) { pr_err("%s:%d failed\n", __func__, __LINE__); rc = -ENOMEM; break; } if (copy_from_user(stop_setting->reg_setting, (void *)reg_setting, stop_setting->size * sizeof(struct msm_camera_i2c_reg_array))) { pr_err("%s:%d failed\n", __func__, __LINE__); kfree(stop_setting->reg_setting); stop_setting->reg_setting = NULL; stop_setting->size = 0; rc = -EFAULT; break; } break; } default: rc = -EFAULT; break; } mutex_unlock(s_ctrl->msm_sensor_mutex); return rc; }
ssize_t compat_rw_copy_check_uvector(int type, const struct compat_iovec __user *uvector, unsigned long nr_segs, unsigned long fast_segs, struct iovec *fast_pointer, struct iovec **ret_pointer) { compat_ssize_t tot_len; struct iovec *iov = *ret_pointer = fast_pointer; ssize_t ret = 0; int seg; /* * SuS says "The readv() function *may* fail if the iovcnt argument * was less than or equal to 0, or greater than {IOV_MAX}. Linux has * traditionally returned zero for zero segments, so... */ if (nr_segs == 0) goto out; ret = -EINVAL; if (nr_segs > UIO_MAXIOV) goto out; if (nr_segs > fast_segs) { ret = -ENOMEM; iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL); if (iov == NULL) goto out; } *ret_pointer = iov; ret = -EFAULT; if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector))) goto out; /* * Single unix specification: * We should -EINVAL if an element length is not >= 0 and fitting an * ssize_t. * * In Linux, the total length is limited to MAX_RW_COUNT, there is * no overflow possibility. */ tot_len = 0; ret = -EINVAL; for (seg = 0; seg < nr_segs; seg++) { compat_uptr_t buf; compat_ssize_t len; if (__get_user(len, &uvector->iov_len) || __get_user(buf, &uvector->iov_base)) { ret = -EFAULT; goto out; } if (len < 0) /* size_t not fitting in compat_ssize_t .. */ goto out; if (type >= 0 && !access_ok(vrfy_dir(type), compat_ptr(buf), len)) { ret = -EFAULT; goto out; } if (len > MAX_RW_COUNT - tot_len) len = MAX_RW_COUNT - tot_len; tot_len += len; iov->iov_base = compat_ptr(buf); iov->iov_len = (compat_size_t) len; uvector++; iov++; } ret = tot_len; out: return ret; }
long compat_arch_ptrace(struct task_struct *child, compat_long_t request, compat_ulong_t caddr, compat_ulong_t cdata) { unsigned long addr = caddr; unsigned long data = cdata; void __user *datap = compat_ptr(data); int ret; switch (request) { case PTRACE_PEEKUSR: ret = compat_ptrace_read_user(child, addr, datap); break; case PTRACE_POKEUSR: ret = compat_ptrace_write_user(child, addr, data); break; case COMPAT_PTRACE_GETREGS: ret = copy_regset_to_user(child, &user_aarch32_view, REGSET_COMPAT_GPR, 0, sizeof(compat_elf_gregset_t), datap); break; case COMPAT_PTRACE_SETREGS: ret = copy_regset_from_user(child, &user_aarch32_view, REGSET_COMPAT_GPR, 0, sizeof(compat_elf_gregset_t), datap); break; case COMPAT_PTRACE_GET_THREAD_AREA: ret = put_user((compat_ulong_t)child->thread.tp_value, (compat_ulong_t __user *)datap); break; case COMPAT_PTRACE_SET_SYSCALL: task_pt_regs(child)->syscallno = data; ret = 0; break; case COMPAT_PTRACE_GETVFPREGS: ret = copy_regset_to_user(child, &user_aarch32_view, REGSET_COMPAT_VFP, 0, VFP_STATE_SIZE, datap); break; case COMPAT_PTRACE_SETVFPREGS: ret = copy_regset_from_user(child, &user_aarch32_view, REGSET_COMPAT_VFP, 0, VFP_STATE_SIZE, datap); break; #ifdef CONFIG_HAVE_HW_BREAKPOINT case COMPAT_PTRACE_GETHBPREGS: ret = compat_ptrace_gethbpregs(child, addr, datap); break; case COMPAT_PTRACE_SETHBPREGS: ret = compat_ptrace_sethbpregs(child, addr, datap); break; #endif default: ret = compat_ptrace_request(child, request, addr, data); break; } return ret; }
static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) { struct snd_pcm_file *pcm_file; struct snd_pcm_substream *substream; void __user *argp = compat_ptr(arg); pcm_file = file->private_data; if (! pcm_file) return -ENOTTY; substream = pcm_file->substream; if (! substream) return -ENOTTY; /* * When PCM is used on 32bit mode, we need to disable * mmap of PCM status/control records because of the size * incompatibility. */ pcm_file->no_compat_mmap = 1; switch (cmd) { case SNDRV_PCM_IOCTL_PVERSION: case SNDRV_PCM_IOCTL_INFO: case SNDRV_PCM_IOCTL_TSTAMP: case SNDRV_PCM_IOCTL_TTSTAMP: case SNDRV_PCM_IOCTL_HWSYNC: case SNDRV_PCM_IOCTL_PREPARE: case SNDRV_PCM_IOCTL_RESET: case SNDRV_PCM_IOCTL_START: case SNDRV_PCM_IOCTL_DROP: case SNDRV_PCM_IOCTL_DRAIN: case SNDRV_PCM_IOCTL_PAUSE: case SNDRV_PCM_IOCTL_HW_FREE: case SNDRV_PCM_IOCTL_RESUME: case SNDRV_PCM_IOCTL_XRUN: case SNDRV_PCM_IOCTL_LINK: case SNDRV_PCM_IOCTL_UNLINK: if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) return snd_pcm_playback_ioctl1(file, substream, cmd, argp); else return snd_pcm_capture_ioctl1(file, substream, cmd, argp); case SNDRV_PCM_IOCTL_HW_REFINE32: return snd_pcm_ioctl_hw_params_compat(substream, 1, argp); case SNDRV_PCM_IOCTL_HW_PARAMS32: return snd_pcm_ioctl_hw_params_compat(substream, 0, argp); case SNDRV_PCM_IOCTL_SW_PARAMS32: return snd_pcm_ioctl_sw_params_compat(substream, argp); case SNDRV_PCM_IOCTL_STATUS32: return snd_pcm_status_user_compat(substream, argp); case SNDRV_PCM_IOCTL_SYNC_PTR32: return snd_pcm_ioctl_sync_ptr_compat(substream, argp); case SNDRV_PCM_IOCTL_CHANNEL_INFO32: return snd_pcm_ioctl_channel_info_compat(substream, argp); case SNDRV_PCM_IOCTL_WRITEI_FRAMES32: return snd_pcm_ioctl_xferi_compat(substream, SNDRV_PCM_STREAM_PLAYBACK, argp); case SNDRV_PCM_IOCTL_READI_FRAMES32: return snd_pcm_ioctl_xferi_compat(substream, SNDRV_PCM_STREAM_CAPTURE, argp); case SNDRV_PCM_IOCTL_WRITEN_FRAMES32: return snd_pcm_ioctl_xfern_compat(substream, SNDRV_PCM_STREAM_PLAYBACK, argp); case SNDRV_PCM_IOCTL_READN_FRAMES32: return snd_pcm_ioctl_xfern_compat(substream, SNDRV_PCM_STREAM_CAPTURE, argp); case SNDRV_PCM_IOCTL_DELAY32: return snd_pcm_ioctl_delay_compat(substream, argp); case SNDRV_PCM_IOCTL_REWIND32: return snd_pcm_ioctl_rewind_compat(substream, argp); case SNDRV_PCM_IOCTL_FORWARD32: return snd_pcm_ioctl_forward_compat(substream, argp); default: if (_IOC_TYPE(cmd) == 'C') return snd_compressed_ioctl32(substream, cmd, argp); else if (_IOC_TYPE(cmd) == 'U') return snd_user_ioctl32(substream, cmd, argp); } return -ENOIOCTLCMD; }
static inline int _snd_ioctl32_ctl_elem_value(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl) { struct snd_ctl_elem_value *data; struct snd_ctl_elem_value32 *data32; int err, i; int type; mm_segment_t oldseg; /* FIXME: check the sane ioctl.. */ data = kmalloc(sizeof(*data), GFP_KERNEL); data32 = kmalloc(sizeof(*data32), GFP_KERNEL); if (data == NULL || data32 == NULL) { err = -ENOMEM; goto __end; } if (copy_from_user(data32, (void __user *)arg, sizeof(*data32))) { err = -EFAULT; goto __end; } memset(data, 0, sizeof(*data)); data->id = data32->id; data->indirect = data32->indirect; if (data->indirect) /* FIXME: this is not correct for long arrays */ data->value.integer.value_ptr = compat_ptr(data32->value.integer.value_ptr); type = get_ctl_type(file, &data->id); if (type < 0) { err = type; goto __end; } if (! data->indirect) { switch (type) { case SNDRV_CTL_ELEM_TYPE_BOOLEAN: case SNDRV_CTL_ELEM_TYPE_INTEGER: for (i = 0; i < 128; i++) data->value.integer.value[i] = data32->value.integer.value[i]; break; case SNDRV_CTL_ELEM_TYPE_INTEGER64: for (i = 0; i < 64; i++) data->value.integer64.value[i] = data32->value.integer64.value[i]; break; case SNDRV_CTL_ELEM_TYPE_ENUMERATED: for (i = 0; i < 128; i++) data->value.enumerated.item[i] = data32->value.enumerated.item[i]; break; case SNDRV_CTL_ELEM_TYPE_BYTES: memcpy(data->value.bytes.data, data32->value.bytes.data, sizeof(data->value.bytes.data)); break; case SNDRV_CTL_ELEM_TYPE_IEC958: data->value.iec958 = data32->value.iec958; break; default: printk("unknown type %d\n", type); break; } } oldseg = get_fs(); set_fs(KERNEL_DS); err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data); set_fs(oldseg); if (err < 0) goto __end; /* restore info to 32bit */ if (! data->indirect) { switch (type) { case SNDRV_CTL_ELEM_TYPE_BOOLEAN: case SNDRV_CTL_ELEM_TYPE_INTEGER: for (i = 0; i < 128; i++) data32->value.integer.value[i] = data->value.integer.value[i]; break; case SNDRV_CTL_ELEM_TYPE_INTEGER64: for (i = 0; i < 64; i++) data32->value.integer64.value[i] = data->value.integer64.value[i]; break; case SNDRV_CTL_ELEM_TYPE_ENUMERATED: for (i = 0; i < 128; i++) data32->value.enumerated.item[i] = data->value.enumerated.item[i]; break; case SNDRV_CTL_ELEM_TYPE_BYTES: memcpy(data32->value.bytes.data, data->value.bytes.data, sizeof(data->value.bytes.data)); break; case SNDRV_CTL_ELEM_TYPE_IEC958: data32->value.iec958 = data->value.iec958; break; default: break; } } err = 0; if (copy_to_user((void __user *)arg, data32, sizeof(*data32))) err = -EFAULT; __end: if (data32) kfree(data32); if (data) kfree(data); return err; }
int compat_ptrace_request(struct task_struct *child, compat_long_t request, compat_ulong_t addr, compat_ulong_t data) { compat_ulong_t __user *datap = compat_ptr(data); compat_ulong_t word; siginfo_t siginfo; int ret; switch (request) { case PTRACE_PEEKTEXT: case PTRACE_PEEKDATA: ret = access_process_vm(child, addr, &word, sizeof(word), 0); if (ret != sizeof(word)) ret = -EIO; else ret = put_user(word, datap); break; case PTRACE_POKETEXT: case PTRACE_POKEDATA: ret = access_process_vm(child, addr, &data, sizeof(data), 1); ret = (ret != sizeof(data) ? -EIO : 0); break; case PTRACE_GETEVENTMSG: ret = put_user((compat_ulong_t) child->ptrace_message, datap); break; case PTRACE_GETSIGINFO: ret = ptrace_getsiginfo(child, &siginfo); if (!ret) ret = copy_siginfo_to_user32( (struct compat_siginfo __user *) datap, &siginfo); break; case PTRACE_SETSIGINFO: memset(&siginfo, 0, sizeof siginfo); if (copy_siginfo_from_user32( &siginfo, (struct compat_siginfo __user *) datap)) ret = -EFAULT; else ret = ptrace_setsiginfo(child, &siginfo); break; #ifdef CONFIG_HAVE_ARCH_TRACEHOOK case PTRACE_GETREGSET: case PTRACE_SETREGSET: { struct iovec kiov; struct compat_iovec __user *uiov = (struct compat_iovec __user *) datap; compat_uptr_t ptr; compat_size_t len; if (!access_ok(VERIFY_WRITE, uiov, sizeof(*uiov))) return -EFAULT; if (__get_user(ptr, &uiov->iov_base) || __get_user(len, &uiov->iov_len)) return -EFAULT; kiov.iov_base = compat_ptr(ptr); kiov.iov_len = len; ret = ptrace_regset(child, request, addr, &kiov); if (!ret) ret = __put_user(kiov.iov_len, &uiov->iov_len); break; } #endif default: ret = ptrace_request(child, request, addr, data); } return ret; }
long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) { long ret = -ENOIOCTLCMD; if (!file->f_op->ioctl && !file->f_op->unlocked_ioctl) return ret; switch (cmd) { #ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCGCAP: case VIDIOCGCHAN: case VIDIOCSCHAN: case VIDIOCGTUNER32: case VIDIOCSTUNER32: case VIDIOCGPICT: case VIDIOCSPICT: case VIDIOCCAPTURE32: case VIDIOCGWIN32: case VIDIOCSWIN32: case VIDIOCGFBUF32: case VIDIOCSFBUF32: case VIDIOCKEY: case VIDIOCGFREQ32: case VIDIOCSFREQ32: case VIDIOCGAUDIO: case VIDIOCSAUDIO: case VIDIOCSYNC32: case VIDIOCMCAPTURE: case VIDIOCGMBUF: case VIDIOCGUNIT: case VIDIOCGCAPTURE: case VIDIOCSCAPTURE: case VIDIOCSPLAYMODE: case VIDIOCSWRITEMODE32: case VIDIOCGPLAYINFO: case VIDIOCSMICROCODE32: case VIDIOCGVBIFMT: case VIDIOCSVBIFMT: #endif #ifdef __OLD_VIDIOC_ case VIDIOC_OVERLAY32_OLD: case VIDIOC_S_PARM_OLD: case VIDIOC_S_CTRL_OLD: case VIDIOC_G_AUDIO_OLD: case VIDIOC_G_AUDOUT_OLD: case VIDIOC_CROPCAP_OLD: #endif case VIDIOC_QUERYCAP: case VIDIOC_RESERVED: case VIDIOC_ENUM_FMT: case VIDIOC_G_FMT32: case VIDIOC_S_FMT32: case VIDIOC_REQBUFS: case VIDIOC_QUERYBUF32: case VIDIOC_G_FBUF32: case VIDIOC_S_FBUF32: case VIDIOC_OVERLAY32: case VIDIOC_QBUF32: case VIDIOC_DQBUF32: case VIDIOC_STREAMON32: case VIDIOC_STREAMOFF32: case VIDIOC_G_PARM: case VIDIOC_S_PARM: case VIDIOC_G_STD: case VIDIOC_S_STD: case VIDIOC_ENUMSTD32: case VIDIOC_ENUMINPUT32: case VIDIOC_G_CTRL: case VIDIOC_S_CTRL: case VIDIOC_G_TUNER: case VIDIOC_S_TUNER: case VIDIOC_G_AUDIO: case VIDIOC_S_AUDIO: case VIDIOC_QUERYCTRL: case VIDIOC_QUERYMENU: case VIDIOC_G_INPUT32: case VIDIOC_S_INPUT32: case VIDIOC_G_OUTPUT32: case VIDIOC_S_OUTPUT32: case VIDIOC_ENUMOUTPUT: case VIDIOC_G_AUDOUT: case VIDIOC_S_AUDOUT: case VIDIOC_G_MODULATOR: case VIDIOC_S_MODULATOR: case VIDIOC_S_FREQUENCY: case VIDIOC_G_FREQUENCY: case VIDIOC_CROPCAP: case VIDIOC_G_CROP: case VIDIOC_S_CROP: case VIDIOC_G_JPEGCOMP: case VIDIOC_S_JPEGCOMP: case VIDIOC_QUERYSTD: case VIDIOC_TRY_FMT32: case VIDIOC_ENUMAUDIO: case VIDIOC_ENUMAUDOUT: case VIDIOC_G_PRIORITY: case VIDIOC_S_PRIORITY: case VIDIOC_G_SLICED_VBI_CAP: case VIDIOC_LOG_STATUS: case VIDIOC_G_EXT_CTRLS32: case VIDIOC_S_EXT_CTRLS32: case VIDIOC_TRY_EXT_CTRLS32: case VIDIOC_ENUM_FRAMESIZES: case VIDIOC_ENUM_FRAMEINTERVALS: case VIDIOC_G_ENC_INDEX: case VIDIOC_ENCODER_CMD: case VIDIOC_TRY_ENCODER_CMD: case VIDIOC_DBG_S_REGISTER: case VIDIOC_DBG_G_REGISTER: case VIDIOC_DBG_G_CHIP_IDENT: case VIDIOC_S_HW_FREQ_SEEK: ret = do_video_ioctl(file, cmd, arg); break; #ifdef CONFIG_VIDEO_V4L1_COMPAT /* BTTV specific... */ case _IOW('v', BASE_VIDIOCPRIVATE+0, char [256]): case _IOR('v', BASE_VIDIOCPRIVATE+1, char [256]): case _IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int): case _IOW('v' , BASE_VIDIOCPRIVATE+3, char [16]): /* struct bttv_pll_info */ case _IOR('v' , BASE_VIDIOCPRIVATE+4, int): case _IOR('v' , BASE_VIDIOCPRIVATE+5, int): case _IOR('v' , BASE_VIDIOCPRIVATE+6, int): case _IOR('v' , BASE_VIDIOCPRIVATE+7, int): ret = native_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); break; #endif default: printk(KERN_WARNING "compat_ioctl32: " "unknown ioctl '%c', dir=%d, #%d (0x%08x)\n", _IOC_TYPE(cmd), _IOC_DIR(cmd), _IOC_NR(cmd), cmd); break; } return ret; }