/* * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs * Copyright (C) 2003 Pavel Machek (pavel@ucw.cz) * * These routines maintain argument size conversion between 32bit and 64bit * ioctls. */ #include <linux/joystick.h> #include <linux/types.h>#include <linux/compat.h>#include <linux/kernel.h>#include <linux/capability.h>#include <linux/compiler.h>#include <linux/sched.h>#include <linux/smp.h>#include <linux/ioctl.h>#include <linux/if.h>#include <linux/if_bridge.h>#include <linux/raid/md_u.h>#include <linux/kd.h>#include <linux/route.h>#include <linux/in6.h>#include <linux/ipv6_route.h>#include <linux/skbuff.h>#include <linux/netlink.h>#include <linux/vt.h>#include <linux/falloc.h>#include <linux/fs.h>#include <linux/file.h>#include <linux/ppp_defs.h>#include <linux/ppp-ioctl.h>#include <linux/if_pppox.h>#include <linux/mtio.h>#include <linux/auto_fs.h>#include <linux/auto_fs4.h>#include <linux/tty.h>#include <linux/vt_kern.h>#include <linux/fb.h>#include <linux/videodev2.h>#include <linux/netdevice.h>#include <linux/raw.h>#include <linux/blkdev.h>#include <linux/elevator.h>#include <linux/rtc.h>#include <linux/pci.h>#include <linux/serial.h>#include <linux/if_tun.h>#include <linux/ctype.h>#include <linux/syscalls.h>#include <linux/i2c.h>#include <linux/i2c-dev.h>#include <linux/atalk.h>#include <linux/gfp.h> #include <net/bluetooth/bluetooth.h>#include <net/bluetooth/hci.h>#include <net/bluetooth/rfcomm.h> #include <linux/capi.h>#include <linux/gigaset_dev.h> #ifdef CONFIG_BLOCK#include <linux/loop.h>#include <linux/cdrom.h>#include <linux/fd.h>#include <scsi/scsi.h>#include <scsi/scsi_ioctl.h>#include <scsi/sg.h>#endif #include <asm/uaccess.h>#include <linux/ethtool.h>#include <linux/mii.h>#include <linux/if_bonding.h>#include <linux/watchdog.h> #include <linux/soundcard.h>#include <linux/lp.h>#include <linux/ppdev.h> #include <linux/atm.h>#include <linux/atmarp.h>#include <linux/atmclip.h>#include <linux/atmdev.h>#include <linux/atmioc.h>#include <linux/atmlec.h>#include <linux/atmmpc.h>#include <linux/atmsvc.h>#include <linux/atm_tcp.h>#include <linux/sonet.h>#include <linux/atm_suni.h> #include <linux/usb.h>#include <linux/usbdevice_fs.h>#include <linux/nbd.h>#include <linux/random.h>#include <linux/filter.h> #include <linux/hiddev.h> #define __DVB_CORE__#include <linux/dvb/audio.h>#include <linux/dvb/dmx.h>#include <linux/dvb/frontend.h>#include <linux/dvb/video.h> #include <linux/sort.h> #ifdef CONFIG_SPARC#include <asm/fbio.h>#endif static int w_long(unsigned int fd, unsigned int cmd, compat_ulong_t __user *argp){ mm_segment_t old_fs = get_fs(); int err; unsigned long val; set_fs (KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long)&val); set_fs (old_fs); if (!err && put_user(val, argp)) return -EFAULT; return err;} struct compat_video_event { int32_t type; compat_time_t timestamp; union { video_size_t size; unsigned int frame_rate; } u;}; static int do_video_get_event(unsigned int fd, unsigned int cmd, struct compat_video_event __user *up){ struct video_event kevent; mm_segment_t old_fs = get_fs(); int err; set_fs(KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long) &kevent); set_fs(old_fs); if (!err) { err = put_user(kevent.type, &up->type); err |= put_user(kevent.timestamp, &up->timestamp); err |= put_user(kevent.u.size.w, &up->u.size.w); err |= put_user(kevent.u.size.h, &up->u.size.h); err |= put_user(kevent.u.size.aspect_ratio, &up->u.size.aspect_ratio); if (err) err = -EFAULT; } return err;} struct compat_video_still_picture { compat_uptr_t iFrame; int32_t size;}; static int do_video_stillpicture(unsigned int fd, unsigned int cmd, struct compat_video_still_picture __user *up){ struct video_still_picture __user *up_native; compat_uptr_t fp; int32_t size; int err; err = get_user(fp, &up->iFrame); err |= get_user(size, &up->size); if (err) return -EFAULT; up_native = compat_alloc_user_space(sizeof(struct video_still_picture)); err = put_user(compat_ptr(fp), &up_native->iFrame); err |= put_user(size, &up_native->size); if (err) return -EFAULT; err = sys_ioctl(fd, cmd, (unsigned long) up_native); return err;} struct compat_video_spu_palette { int length; compat_uptr_t palette;}; static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, struct compat_video_spu_palette __user *up){ struct video_spu_palette __user *up_native; compat_uptr_t palp; int length, err; err = get_user(palp, &up->palette); err |= get_user(length, &up->length); up_native = compat_alloc_user_space(sizeof(struct video_spu_palette)); err = put_user(compat_ptr(palp), &up_native->palette); err |= put_user(length, &up_native->length); if (err) return -EFAULT; err = sys_ioctl(fd, cmd, (unsigned long) up_native); return err;} #ifdef CONFIG_BLOCKtypedef struct sg_io_hdr32 { compat_int_t interface_id; /* [i] 'S' for SCSI generic (required) */ compat_int_t dxfer_direction; /* [i] data transfer direction */ unsigned char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */ unsigned char mx_sb_len; /* [i] max length to write to sbp */ unsigned short iovec_count; /* [i] 0 implies no scatter gather */ compat_uint_t dxfer_len; /* [i] byte count of data transfer */ compat_uint_t dxferp; /* [i], [*io] points to data transfer memory or scatter gather list */ compat_uptr_t cmdp; /* [i], [*i] points to command to perform */ compat_uptr_t sbp; /* [i], [*o] points to sense_buffer memory */ compat_uint_t timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */ compat_uint_t flags; /* [i] 0 -> default, see SG_FLAG... */ compat_int_t pack_id; /* [i->o] unused internally (normally) */ compat_uptr_t usr_ptr; /* [i->o] unused internally */ unsigned char status; /* [o] scsi status */ unsigned char masked_status; /* [o] shifted, masked scsi status */ unsigned char msg_status; /* [o] messaging level data (optional) */ unsigned char sb_len_wr; /* [o] byte count actually written to sbp */ unsigned short host_status; /* [o] errors from host adapter */ unsigned short driver_status; /* [o] errors from software driver */ compat_int_t resid; /* [o] dxfer_len - actual_transferred */ compat_uint_t duration; /* [o] time taken by cmd (unit: millisec) */ compat_uint_t info; /* [o] auxiliary information */} sg_io_hdr32_t; /* 64 bytes long (on sparc32) */ typedef struct sg_iovec32 { compat_uint_t iov_base; compat_uint_t iov_len;} sg_iovec32_t; static int sg_build_iovec(sg_io_hdr_t __user *sgio, void __user *dxferp, u16 iovec_count){ sg_iovec_t __user *iov = (sg_iovec_t __user *) (sgio + 1); sg_iovec32_t __user *iov32 = dxferp; int i; for (i = 0; i < iovec_count; i++) { u32 base, len; if (get_user(base, &iov32[i].iov_base) || get_user(len, &iov32[i].iov_len) || put_user(compat_ptr(base), &iov[i].iov_base) || put_user(len, &iov[i].iov_len)) return -EFAULT; } if (put_user(iov, &sgio->dxferp)) return -EFAULT; return 0;} static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, sg_io_hdr32_t __user *sgio32){ sg_io_hdr_t __user *sgio; u16 iovec_count; u32 data; void __user *dxferp; int err; int interface_id; if (get_user(interface_id, &sgio32->interface_id)) return -EFAULT; if (interface_id != 'S') return sys_ioctl(fd, cmd, (unsigned long)sgio32); if (get_user(iovec_count, &sgio32->iovec_count)) return -EFAULT; { void __user *top = compat_alloc_user_space(0); void __user *new = compat_alloc_user_space(sizeof(sg_io_hdr_t) + (iovec_count * sizeof(sg_iovec_t))); if (new > top) return -EINVAL; sgio = new; } /* Ok, now construct. */ if (copy_in_user(&sgio->interface_id, &sgio32->interface_id, (2 * sizeof(int)) + (2 * sizeof(unsigned char)) + (1 * sizeof(unsigned short)) + (1 * sizeof(unsigned int)))) return -EFAULT; if (get_user(data, &sgio32->dxferp)) return -EFAULT; dxferp = compat_ptr(data); if (iovec_count) { if (sg_build_iovec(sgio, dxferp, iovec_count)) return -EFAULT; } else { if (put_user(dxferp, &sgio->dxferp)) return -EFAULT; } { unsigned char __user *cmdp; unsigned char __user *sbp; if (get_user(data, &sgio32->cmdp)) return -EFAULT; cmdp = compat_ptr(data); if (get_user(data, &sgio32->sbp)) return -EFAULT; sbp = compat_ptr(data); if (put_user(cmdp, &sgio->cmdp) || put_user(sbp, &sgio->sbp)) return -EFAULT; } if (copy_in_user(&sgio->timeout, &sgio32->timeout, 3 * sizeof(int))) return -EFAULT; if (get_user(data, &sgio32->usr_ptr)) return -EFAULT; if (put_user(compat_ptr(data), &sgio->usr_ptr)) return -EFAULT; err = sys_ioctl(fd, cmd, (unsigned long) sgio); if (err >= 0) { void __user *datap; if (copy_in_user(&sgio32->pack_id, &sgio->pack_id, sizeof(int)) || get_user(datap, &sgio->usr_ptr) || put_user((u32)(unsigned long)datap, &sgio32->usr_ptr) || copy_in_user(&sgio32->status, &sgio->status, (4 * sizeof(unsigned char)) + (2 * sizeof(unsigned short)) + (3 * sizeof(int)))) err = -EFAULT; } return err;} struct compat_sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */ char req_state; char orphan; char sg_io_owned; char problem; int pack_id; compat_uptr_t usr_ptr; unsigned int duration; int unused;}; static int sg_grt_trans(unsigned int fd, unsigned int cmd, struct compat_sg_req_info __user *o){ int err, i; sg_req_info_t __user *r; r = compat_alloc_user_space(sizeof(sg_req_info_t)*SG_MAX_QUEUE); err = sys_ioctl(fd,cmd,(unsigned long)r); if (err < 0) return err; for (i = 0; i < SG_MAX_QUEUE; i++) { void __user *ptr; int d; if (copy_in_user(o + i, r + i, offsetof(sg_req_info_t, usr_ptr)) || get_user(ptr, &r[i].usr_ptr) || get_user(d, &r[i].duration) || put_user((u32)(unsigned long)(ptr), &o[i].usr_ptr) || put_user(d, &o[i].duration)) return -EFAULT; } return err;}#endif /* CONFIG_BLOCK */ struct sock_fprog32 { unsigned short len; compat_caddr_t filter;}; #define PPPIOCSPASS32 _IOW('t', 71, struct sock_fprog32)#define PPPIOCSACTIVE32 _IOW('t', 70, struct sock_fprog32) static int ppp_sock_fprog_ioctl_trans(unsigned int fd, unsigned int cmd, struct sock_fprog32 __user *u_fprog32){ struct sock_fprog __user *u_fprog64 = compat_alloc_user_space(sizeof(struct sock_fprog)); void __user *fptr64; u32 fptr32; u16 flen; if (get_user(flen, &u_fprog32->len) || get_user(fptr32, &u_fprog32->filter)) return -EFAULT; fptr64 = compat_ptr(fptr32); if (put_user(flen, &u_fprog64->len) || put_user(fptr64, &u_fprog64->filter)) return -EFAULT; if (cmd == PPPIOCSPASS32) cmd = PPPIOCSPASS; else cmd = PPPIOCSACTIVE; return sys_ioctl(fd, cmd, (unsigned long) u_fprog64);} struct ppp_option_data32 { compat_caddr_t ptr; u32 length; compat_int_t transmit;};#define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32) struct ppp_idle32 { compat_time_t xmit_idle; compat_time_t recv_idle;};#define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32) static int ppp_gidle(unsigned int fd, unsigned int cmd, struct ppp_idle32 __user *idle32){ struct ppp_idle __user *idle; __kernel_time_t xmit, recv; int err; idle = compat_alloc_user_space(sizeof(*idle)); err = sys_ioctl(fd, PPPIOCGIDLE, (unsigned long) idle); if (!err) { if (get_user(xmit, &idle->xmit_idle) || get_user(recv, &idle->recv_idle) || put_user(xmit, &idle32->xmit_idle) || put_user(recv, &idle32->recv_idle)) err = -EFAULT; } return err;} static int ppp_scompress(unsigned int fd, unsigned int cmd, struct ppp_option_data32 __user *odata32){ struct ppp_option_data __user *odata; __u32 data; void __user *datap; odata = compat_alloc_user_space(sizeof(*odata)); if (get_user(data, &odata32->ptr)) return -EFAULT; datap = compat_ptr(data); if (put_user(datap, &odata->ptr)) return -EFAULT; if (copy_in_user(&odata->length, &odata32->length, sizeof(__u32) + sizeof(int))) return -EFAULT; return sys_ioctl(fd, PPPIOCSCOMPRESS, (unsigned long) odata);} #ifdef CONFIG_BLOCKstruct mtget32 { compat_long_t mt_type; compat_long_t mt_resid;Lines 1–500 of 1628. Load more
/* * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs * Copyright (C) 2003 Pavel Machek (pavel@ucw.cz) * * These routines maintain argument size conversion between 32bit and 64bit * ioctls. */ #include <linux/joystick.h> #include <linux/types.h> #include <linux/compat.h> #include <linux/kernel.h> #include <linux/capability.h> #include <linux/compiler.h> #include <linux/sched.h> #include <linux/smp.h> #include <linux/ioctl.h> #include <linux/if.h> #include <linux/if_bridge.h> #include <linux/raid/md_u.h> #include <linux/kd.h> #include <linux/route.h> #include <linux/in6.h> #include <linux/ipv6_route.h> #include <linux/skbuff.h> #include <linux/netlink.h> #include <linux/vt.h> #include <linux/falloc.h> #include <linux/fs.h> #include <linux/file.h> #include <linux/ppp_defs.h> #include <linux/ppp-ioctl.h> #include <linux/if_pppox.h> #include <linux/mtio.h> #include <linux/auto_fs.h> #include <linux/auto_fs4.h> #include <linux/tty.h> #include <linux/vt_kern.h> #include <linux/fb.h> #include <linux/videodev2.h> #include <linux/netdevice.h> #include <linux/raw.h> #include <linux/blkdev.h> #include <linux/elevator.h> #include <linux/rtc.h> #include <linux/pci.h> #include <linux/serial.h> #include <linux/if_tun.h> #include <linux/ctype.h> #include <linux/syscalls.h> #include <linux/i2c.h> #include <linux/i2c-dev.h> #include <linux/atalk.h> #include <linux/gfp.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci.h> #include <net/bluetooth/rfcomm.h> #include <linux/capi.h> #include <linux/gigaset_dev.h> #ifdef CONFIG_BLOCK #include <linux/loop.h> #include <linux/cdrom.h> #include <linux/fd.h> #include <scsi/scsi.h> #include <scsi/scsi_ioctl.h> #include <scsi/sg.h> #endif #include <asm/uaccess.h> #include <linux/ethtool.h> #include <linux/mii.h> #include <linux/if_bonding.h> #include <linux/watchdog.h> #include <linux/soundcard.h> #include <linux/lp.h> #include <linux/ppdev.h> #include <linux/atm.h> #include <linux/atmarp.h> #include <linux/atmclip.h> #include <linux/atmdev.h> #include <linux/atmioc.h> #include <linux/atmlec.h> #include <linux/atmmpc.h> #include <linux/atmsvc.h> #include <linux/atm_tcp.h> #include <linux/sonet.h> #include <linux/atm_suni.h> #include <linux/usb.h> #include <linux/usbdevice_fs.h> #include <linux/nbd.h> #include <linux/random.h> #include <linux/filter.h> #include <linux/hiddev.h> #define __DVB_CORE__ #include <linux/dvb/audio.h> #include <linux/dvb/dmx.h> #include <linux/dvb/frontend.h> #include <linux/dvb/video.h> #include <linux/sort.h> #ifdef CONFIG_SPARC #include <asm/fbio.h> #endif static int w_long(unsigned int fd, unsigned int cmd, compat_ulong_t __user *argp) { mm_segment_t old_fs = get_fs(); int err; unsigned long val; set_fs (KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long)&val); set_fs (old_fs); if (!err && put_user(val, argp)) return -EFAULT; return err; } struct compat_video_event { int32_t type; compat_time_t timestamp; union { video_size_t size; unsigned int frame_rate; } u; }; static int do_video_get_event(unsigned int fd, unsigned int cmd, struct compat_video_event __user *up) { struct video_event kevent; mm_segment_t old_fs = get_fs(); int err; set_fs(KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long) &kevent); set_fs(old_fs); if (!err) { err = put_user(kevent.type, &up->type); err |= put_user(kevent.timestamp, &up->timestamp); err |= put_user(kevent.u.size.w, &up->u.size.w); err |= put_user(kevent.u.size.h, &up->u.size.h); err |= put_user(kevent.u.size.aspect_ratio, &up->u.size.aspect_ratio); if (err) err = -EFAULT; } return err; } struct compat_video_still_picture { compat_uptr_t iFrame; int32_t size; }; static int do_video_stillpicture(unsigned int fd, unsigned int cmd, struct compat_video_still_picture __user *up) { struct video_still_picture __user *up_native; compat_uptr_t fp; int32_t size; int err; err = get_user(fp, &up->iFrame); err |= get_user(size, &up->size); if (err) return -EFAULT; up_native = compat_alloc_user_space(sizeof(struct video_still_picture)); err = put_user(compat_ptr(fp), &up_native->iFrame); err |= put_user(size, &up_native->size); if (err) return -EFAULT; err = sys_ioctl(fd, cmd, (unsigned long) up_native); return err; } struct compat_video_spu_palette { int length; compat_uptr_t palette; }; static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, struct compat_video_spu_palette __user *up) { struct video_spu_palette __user *up_native; compat_uptr_t palp; int length, err; err = get_user(palp, &up->palette); err |= get_user(length, &up->length); up_native = compat_alloc_user_space(sizeof(struct video_spu_palette)); err = put_user(compat_ptr(palp), &up_native->palette); err |= put_user(length, &up_native->length); if (err) return -EFAULT; err = sys_ioctl(fd, cmd, (unsigned long) up_native); return err; } #ifdef CONFIG_BLOCK typedef struct sg_io_hdr32 { compat_int_t interface_id; /* [i] 'S' for SCSI generic (required) */ compat_int_t dxfer_direction; /* [i] data transfer direction */ unsigned char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */ unsigned char mx_sb_len; /* [i] max length to write to sbp */ unsigned short iovec_count; /* [i] 0 implies no scatter gather */ compat_uint_t dxfer_len; /* [i] byte count of data transfer */ compat_uint_t dxferp; /* [i], [*io] points to data transfer memory or scatter gather list */ compat_uptr_t cmdp; /* [i], [*i] points to command to perform */ compat_uptr_t sbp; /* [i], [*o] points to sense_buffer memory */ compat_uint_t timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */ compat_uint_t flags; /* [i] 0 -> default, see SG_FLAG... */ compat_int_t pack_id; /* [i->o] unused internally (normally) */ compat_uptr_t usr_ptr; /* [i->o] unused internally */ unsigned char status; /* [o] scsi status */ unsigned char masked_status; /* [o] shifted, masked scsi status */ unsigned char msg_status; /* [o] messaging level data (optional) */ unsigned char sb_len_wr; /* [o] byte count actually written to sbp */ unsigned short host_status; /* [o] errors from host adapter */ unsigned short driver_status; /* [o] errors from software driver */ compat_int_t resid; /* [o] dxfer_len - actual_transferred */ compat_uint_t duration; /* [o] time taken by cmd (unit: millisec) */ compat_uint_t info; /* [o] auxiliary information */ } sg_io_hdr32_t; /* 64 bytes long (on sparc32) */ typedef struct sg_iovec32 { compat_uint_t iov_base; compat_uint_t iov_len; } sg_iovec32_t; static int sg_build_iovec(sg_io_hdr_t __user *sgio, void __user *dxferp, u16 iovec_count) { sg_iovec_t __user *iov = (sg_iovec_t __user *) (sgio + 1); sg_iovec32_t __user *iov32 = dxferp; int i; for (i = 0; i < iovec_count; i++) { u32 base, len; if (get_user(base, &iov32[i].iov_base) || get_user(len, &iov32[i].iov_len) || put_user(compat_ptr(base), &iov[i].iov_base) || put_user(len, &iov[i].iov_len)) return -EFAULT; } if (put_user(iov, &sgio->dxferp)) return -EFAULT; return 0; } static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, sg_io_hdr32_t __user *sgio32) { sg_io_hdr_t __user *sgio; u16 iovec_count; u32 data; void __user *dxferp; int err; int interface_id; if (get_user(interface_id, &sgio32->interface_id)) return -EFAULT; if (interface_id != 'S') return sys_ioctl(fd, cmd, (unsigned long)sgio32); if (get_user(iovec_count, &sgio32->iovec_count)) return -EFAULT; { void __user *top = compat_alloc_user_space(0); void __user *new = compat_alloc_user_space(sizeof(sg_io_hdr_t) + (iovec_count * sizeof(sg_iovec_t))); if (new > top) return -EINVAL; sgio = new; } /* Ok, now construct. */ if (copy_in_user(&sgio->interface_id, &sgio32->interface_id, (2 * sizeof(int)) + (2 * sizeof(unsigned char)) + (1 * sizeof(unsigned short)) + (1 * sizeof(unsigned int)))) return -EFAULT; if (get_user(data, &sgio32->dxferp)) return -EFAULT; dxferp = compat_ptr(data); if (iovec_count) { if (sg_build_iovec(sgio, dxferp, iovec_count)) return -EFAULT; } else { if (put_user(dxferp, &sgio->dxferp)) return -EFAULT; } { unsigned char __user *cmdp; unsigned char __user *sbp; if (get_user(data, &sgio32->cmdp)) return -EFAULT; cmdp = compat_ptr(data); if (get_user(data, &sgio32->sbp)) return -EFAULT; sbp = compat_ptr(data); if (put_user(cmdp, &sgio->cmdp) || put_user(sbp, &sgio->sbp)) return -EFAULT; } if (copy_in_user(&sgio->timeout, &sgio32->timeout, 3 * sizeof(int))) return -EFAULT; if (get_user(data, &sgio32->usr_ptr)) return -EFAULT; if (put_user(compat_ptr(data), &sgio->usr_ptr)) return -EFAULT; err = sys_ioctl(fd, cmd, (unsigned long) sgio); if (err >= 0) { void __user *datap; if (copy_in_user(&sgio32->pack_id, &sgio->pack_id, sizeof(int)) || get_user(datap, &sgio->usr_ptr) || put_user((u32)(unsigned long)datap, &sgio32->usr_ptr) || copy_in_user(&sgio32->status, &sgio->status, (4 * sizeof(unsigned char)) + (2 * sizeof(unsigned short)) + (3 * sizeof(int)))) err = -EFAULT; } return err; } struct compat_sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */ char req_state; char orphan; char sg_io_owned; char problem; int pack_id; compat_uptr_t usr_ptr; unsigned int duration; int unused; }; static int sg_grt_trans(unsigned int fd, unsigned int cmd, struct compat_sg_req_info __user *o) { int err, i; sg_req_info_t __user *r; r = compat_alloc_user_space(sizeof(sg_req_info_t)*SG_MAX_QUEUE); err = sys_ioctl(fd,cmd,(unsigned long)r); if (err < 0) return err; for (i = 0; i < SG_MAX_QUEUE; i++) { void __user *ptr; int d; if (copy_in_user(o + i, r + i, offsetof(sg_req_info_t, usr_ptr)) || get_user(ptr, &r[i].usr_ptr) || get_user(d, &r[i].duration) || put_user((u32)(unsigned long)(ptr), &o[i].usr_ptr) || put_user(d, &o[i].duration)) return -EFAULT; } return err; } #endif /* CONFIG_BLOCK */ struct sock_fprog32 { unsigned short len; compat_caddr_t filter; }; #define PPPIOCSPASS32 _IOW('t', 71, struct sock_fprog32) #define PPPIOCSACTIVE32 _IOW('t', 70, struct sock_fprog32) static int ppp_sock_fprog_ioctl_trans(unsigned int fd, unsigned int cmd, struct sock_fprog32 __user *u_fprog32) { struct sock_fprog __user *u_fprog64 = compat_alloc_user_space(sizeof(struct sock_fprog)); void __user *fptr64; u32 fptr32; u16 flen; if (get_user(flen, &u_fprog32->len) || get_user(fptr32, &u_fprog32->filter)) return -EFAULT; fptr64 = compat_ptr(fptr32); if (put_user(flen, &u_fprog64->len) || put_user(fptr64, &u_fprog64->filter)) return -EFAULT; if (cmd == PPPIOCSPASS32) cmd = PPPIOCSPASS; else cmd = PPPIOCSACTIVE; return sys_ioctl(fd, cmd, (unsigned long) u_fprog64); } struct ppp_option_data32 { compat_caddr_t ptr; u32 length; compat_int_t transmit; }; #define PPPIOCSCOMPRESS32 _IOW('t', 77, struct ppp_option_data32) struct ppp_idle32 { compat_time_t xmit_idle; compat_time_t recv_idle; }; #define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32) static int ppp_gidle(unsigned int fd, unsigned int cmd, struct ppp_idle32 __user *idle32) { struct ppp_idle __user *idle; __kernel_time_t xmit, recv; int err; idle = compat_alloc_user_space(sizeof(*idle)); err = sys_ioctl(fd, PPPIOCGIDLE, (unsigned long) idle); if (!err) { if (get_user(xmit, &idle->xmit_idle) || get_user(recv, &idle->recv_idle) || put_user(xmit, &idle32->xmit_idle) || put_user(recv, &idle32->recv_idle)) err = -EFAULT; } return err; } static int ppp_scompress(unsigned int fd, unsigned int cmd, struct ppp_option_data32 __user *odata32) { struct ppp_option_data __user *odata; __u32 data; void __user *datap; odata = compat_alloc_user_space(sizeof(*odata)); if (get_user(data, &odata32->ptr)) return -EFAULT; datap = compat_ptr(data); if (put_user(datap, &odata->ptr)) return -EFAULT; if (copy_in_user(&odata->length, &odata32->length, sizeof(__u32) + sizeof(int))) return -EFAULT; return sys_ioctl(fd, PPPIOCSCOMPRESS, (unsigned long) odata); } #ifdef CONFIG_BLOCK struct mtget32 { compat_long_t mt_type; compat_long_t mt_resid;