📄 ioctl32.c
字号:
u_char addr_format; int nframes; __kernel_caddr_t32 buf;};struct cdrom_generic_command32 { unsigned char cmd[CDROM_PACKET_SIZE]; __kernel_caddr_t32 buffer; unsigned int buflen; int stat; __kernel_caddr_t32 sense; unsigned char data_direction; int quiet; int timeout; __kernel_caddr_t32 reserved[1];};static int cdrom_do_read_audio(unsigned int fd, unsigned int cmd, unsigned long arg){ struct cdrom_read_audio *cdread_audio; struct cdrom_read_audio32 *cdread_audio32; __u32 data; void *datap; cdread_audio = alloc_user_space(sizeof(*cdread_audio)); cdread_audio32 = (struct cdrom_read_audio32 *) arg; if (copy_in_user(&cdread_audio->addr, &cdread_audio32->addr, (sizeof(*cdread_audio32) - sizeof(__kernel_caddr_t32)))) return -EFAULT; if (get_user(data, &cdread_audio32->buf)) return -EFAULT; datap = (void *) (unsigned long) data; if (put_user(datap, &cdread_audio->buf)) return -EFAULT; return sys_ioctl(fd, cmd, (unsigned long) cdread_audio);}static int __cgc_do_ptr(void **ptr64, __u32 *ptr32){ u32 data; void *datap; if (get_user(data, ptr32)) return -EFAULT; datap = (void *) (unsigned long) data; if (put_user(datap, ptr64)) return -EFAULT; return 0;}static int cdrom_do_generic_command(unsigned int fd, unsigned int cmd, unsigned long arg){ struct cdrom_generic_command *cgc; struct cdrom_generic_command32 *cgc32; unsigned char dir; cgc = alloc_user_space(sizeof(*cgc)); cgc32 = (struct cdrom_generic_command32 *) arg; if (copy_in_user(&cgc->cmd, &cgc32->cmd, sizeof(cgc->cmd)) || __cgc_do_ptr((void **) &cgc->buffer, &cgc32->buffer) || copy_in_user(&cgc->buflen, &cgc32->buflen, (sizeof(unsigned int) + sizeof(int))) || __cgc_do_ptr((void **) &cgc->sense, &cgc32->sense)) return -EFAULT; if (get_user(dir, &cgc32->data_direction) || put_user(dir, &cgc->data_direction)) return -EFAULT; if (copy_in_user(&cgc->quiet, &cgc32->quiet, 2 * sizeof(int))) return -EFAULT; if (__cgc_do_ptr(&cgc->reserved[0], &cgc32->reserved[0])) return -EFAULT; return sys_ioctl(fd, cmd, (unsigned long) cgc);}static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg){ int err; switch(cmd) { case CDROMREADAUDIO: err = cdrom_do_read_audio(fd, cmd, arg); break; case CDROM_SEND_PACKET: err = cdrom_do_generic_command(fd, cmd, arg); break; default: do { static int count; if (++count <= 20) printk("cdrom_ioctl: Unknown cmd fd(%d) " "cmd(%08x) arg(%08x)\n", (int)fd, (unsigned int)cmd, (unsigned int)arg); } while(0); err = -EINVAL; break; }; return err;}struct loop_info32 { int lo_number; /* ioctl r/o */ __kernel_dev_t32 lo_device; /* ioctl r/o */ unsigned int lo_inode; /* ioctl r/o */ __kernel_dev_t32 lo_rdevice; /* ioctl r/o */ int lo_offset; int lo_encrypt_type; int lo_encrypt_key_size; /* ioctl w/o */ int lo_flags; /* ioctl r/o */ char lo_name[LO_NAME_SIZE]; unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ unsigned int lo_init[2]; char reserved[4];};static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); struct loop_info l; int err = -EINVAL; switch(cmd) { case LOOP_SET_STATUS: err = get_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number); err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device); err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode); err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice); err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset, 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); if (err) { err = -EFAULT; } else { set_fs (KERNEL_DS); err = sys_ioctl (fd, cmd, (unsigned long)&l); set_fs (old_fs); } break; case LOOP_GET_STATUS: set_fs (KERNEL_DS); err = sys_ioctl (fd, cmd, (unsigned long)&l); set_fs (old_fs); if (!err) { err = put_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number); err |= __put_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device); err |= __put_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode); err |= __put_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice); err |= __copy_to_user((char *)&((struct loop_info32 *)arg)->lo_offset, (char *)&l.lo_offset, (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); if (err) err = -EFAULT; } break; default: { static int count; if (++count <= 20) printk("%s: Unknown loop ioctl cmd, fd(%d) " "cmd(%08x) arg(%08lx)\n", __FUNCTION__, fd, cmd, arg); } } return err;}extern int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg);static int vt_check(struct file *file){ struct tty_struct *tty; struct inode *inode = file->f_dentry->d_inode; if (file->f_op->ioctl != tty_ioctl) return -EINVAL; tty = (struct tty_struct *)file->private_data; if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl")) return -EINVAL; if (tty->driver.ioctl != vt_ioctl) return -EINVAL; /* * To have permissions to do most of the vt ioctls, we either have * to be the owner of the tty, or super-user. */ if (current->tty == tty || suser()) return 1; return 0; }struct consolefontdesc32 { unsigned short charcount; /* characters in font (256 or 512) */ unsigned short charheight; /* scan lines per character (1-32) */ u32 chardata; /* font data in expanded form */};static int do_fontx_ioctl(unsigned int fd, int cmd, struct consolefontdesc32 *user_cfd, struct file *file){ struct consolefontdesc cfdarg; struct console_font_op op; int i, perm; perm = vt_check(file); if (perm < 0) return perm; if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc32))) return -EFAULT; cfdarg.chardata = (unsigned char *)A(((struct consolefontdesc32 *)&cfdarg)->chardata); switch (cmd) { case PIO_FONTX: if (!perm) return -EPERM; op.op = KD_FONT_OP_SET; op.flags = 0; op.width = 8; op.height = cfdarg.charheight; op.charcount = cfdarg.charcount; op.data = cfdarg.chardata; return con_font_op(fg_console, &op); case GIO_FONTX: if (!cfdarg.chardata) return 0; op.op = KD_FONT_OP_GET; op.flags = 0; op.width = 8; op.height = cfdarg.charheight; op.charcount = cfdarg.charcount; op.data = cfdarg.chardata; i = con_font_op(fg_console, &op); if (i) return i; cfdarg.charheight = op.height; cfdarg.charcount = op.charcount; ((struct consolefontdesc32 *)&cfdarg)->chardata = (unsigned long)cfdarg.chardata; if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc32))) return -EFAULT; return 0; } return -EINVAL;}struct console_font_op32 { unsigned int op; /* operation code KD_FONT_OP_* */ unsigned int flags; /* KD_FONT_FLAG_* */ unsigned int width, height; /* font size */ unsigned int charcount; u32 data; /* font data with height fixed to 32 */}; static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, struct console_font_op32 *fontop, struct file *file){ struct console_font_op op; int perm = vt_check(file), i; struct vt_struct *vt; if (perm < 0) return perm; if (copy_from_user(&op, (void *) fontop, sizeof(struct console_font_op32))) return -EFAULT; if (!perm && op.op != KD_FONT_OP_GET) return -EPERM; op.data = (unsigned char *)A(((struct console_font_op32 *)&op)->data); op.flags |= KD_FONT_FLAG_OLD; vt = (struct vt_struct *)((struct tty_struct *)file->private_data)->driver_data; i = con_font_op(vt->vc_num, &op); if (i) return i; ((struct console_font_op32 *)&op)->data = (unsigned long)op.data; if (copy_to_user((void *) fontop, &op, sizeof(struct console_font_op32))) return -EFAULT; return 0;}struct unimapdesc32 { unsigned short entry_ct; u32 entries;};static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, struct unimapdesc32 *user_ud, struct file *file){ struct unimapdesc32 tmp; int perm = vt_check(file); if (perm < 0) return perm; if (copy_from_user(&tmp, user_ud, sizeof tmp)) return -EFAULT; switch (cmd) { case PIO_UNIMAP: if (!perm) return -EPERM; return con_set_unimap(fg_console, tmp.entry_ct, (struct unipair *)A(tmp.entries)); case GIO_UNIMAP: return con_get_unimap(fg_console, tmp.entry_ct, &(user_ud->entry_ct), (struct unipair *)A(tmp.entries)); } return 0;}static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); __kernel_uid_t kuid; int err; cmd = SMB_IOC_GETMOUNTUID; set_fs(KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long)&kuid); set_fs(old_fs); if (err >= 0) err = put_user(kuid, (__kernel_uid_t32 *)arg); return err;}struct ncp_ioctl_request_32 { unsigned int function; unsigned int size; __kernel_caddr_t32 data;};struct ncp_fs_info_v2_32 { int version; unsigned int mounted_uid; unsigned int connection; unsigned int buffer_size; unsigned int volume_number; __u32 directory_id; __u32 dummy1; __u32 dummy2; __u32 dummy3;};struct ncp_objectname_ioctl_32{ int auth_type; unsigned int object_name_len; __kernel_caddr_t32 object_name; /* an userspace data, in most cases user name */};struct ncp_privatedata_ioctl_32{ unsigned int len; __kernel_caddr_t32 data; /* ~1000 for NDS */};#define NCP_IOC_NCPREQUEST_32 _IOR('n', 1, struct ncp_ioctl_request_32)#define NCP_IOC_GETMOUNTUID2_32 _IOW('n', 2, unsigned int)#define NCP_IOC_GET_FS_INFO_V2_32 _IOWR('n', 4, struct ncp_fs_info_v2_32)#define NCP_IOC_GETOBJECTNAME_32 _IOWR('n', 9, struct ncp_objectname_ioctl_32)#define NCP_IOC_SETOBJECTNAME_32 _IOR('n', 9, struct ncp_objectname_ioctl_32)#define NCP_IOC_GETPRIVATEDATA_32 _IOWR('n', 10, struct ncp_privatedata_ioctl_32)#define NCP_IOC_SETPRIVATEDATA_32 _IOR('n', 10, struct ncp_privatedata_ioctl_32)static int do_ncp_ncprequest(unsigned int fd, unsigned int cmd, unsigned long arg){ struct ncp_ioctl_request_32 n32; struct ncp_ioctl_request n; mm_segment_t old_fs; int err; if (copy_from_user(&n32, (struct ncp_ioctl_request_32*)arg, sizeof(n32))) return -EFAULT; n.function = n32.function; n.size = n32.size; if (n.size > 65536) return -EINVAL; n.data = vmalloc(65536); /* 65536 must be same as NCP_PACKET_SIZE_INTERNAL in ncpfs */ if (!n.data) return -ENOMEM; err = -EFAULT; if (copy_from_user(n.data, A(n32.data), n.size)) goto out; old_fs = get_fs(); set_fs (KERNEL_DS); err = sys_ioctl (fd, NCP_IOC_NCPREQUEST, (unsigned long)&n); set_fs (old_fs); if(err <= 0) goto out; if (err > 65536) { err = -EINVAL; goto out; } if (copy_to_user(A(n32.data), n.data, err)) { err = -EFAULT; goto out; } out: vfree(n.data); return err;}static int do_ncp_getmountuid2(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); __kernel_uid_t kuid; int err; cmd = NCP_IOC_GETMOUNTUID2; set_fs(KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long)&kuid); set_fs(old_fs); if (!err) err = put_user(kuid, (unsigned int*)arg); return err;}static int do_ncp_getfsinfo2(unsigned int fd, unsigned int cmd, unsigned long arg){ mm_segment_t old_fs = get_fs(); struct ncp_fs_info_v2_32 n32; struct ncp_fs_info_v2 n; int err; if (copy_from_user(&n32, (struct ncp_fs_info_v2_32*)arg, sizeof(n32))) return -EFAULT; if (n32.version != NCP_GET_FS_INFO_VERSION_V2) return -EINVAL; n.version = NCP_GET_FS_INFO_VERSION_V2; set_fs(KERNEL_DS); err = sys_ioctl(fd, NCP_IOC_GET_FS_INFO_V2, (unsigned long)&n); set_fs(old_fs); if (!err) { n32.version = n.version; n32.mounted_uid = n.mounted_uid; n32.connection = n.connection; n32.buffer_size = n.buffer_size; n32.volume_number = n.volume_number; n32.directory_id = n.directory_id; n32.dummy1 = n.dummy1; n32.dummy2 = n.dummy2; n32.dummy3 = n.dummy3; err = copy_to_user((struct ncp_fs_info_v2_32*)arg, &n32, sizeof(n32)) ? -EFAULT : 0; } return err;}static int do_ncp_getobjectname(unsigned int fd, unsigned int cmd, uns
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -