Loading kernel/power/user.c +22 −32 Original line number Diff line number Diff line Loading @@ -196,28 +196,44 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf, return res; } struct compat_resume_swap_area { compat_loff_t offset; u32 dev; } __packed; static int snapshot_set_swap_area(struct snapshot_data *data, void __user *argp) { struct resume_swap_area swap_area; sector_t offset; dev_t swdev; if (swsusp_swap_in_use()) return -EPERM; if (in_compat_syscall()) { struct compat_resume_swap_area swap_area; if (copy_from_user(&swap_area, argp, sizeof(swap_area))) return -EFAULT; swdev = new_decode_dev(swap_area.dev); offset = swap_area.offset; } else { struct resume_swap_area swap_area; if (copy_from_user(&swap_area, argp, sizeof(swap_area))) return -EFAULT; swdev = new_decode_dev(swap_area.dev); offset = swap_area.offset; } /* * User space encodes device types as two-byte values, * so we need to recode them */ swdev = new_decode_dev(swap_area.dev); if (!swdev) { data->swap = -1; return -EINVAL; } offset = swap_area.offset; data->swap = swap_type_of(swdev, offset, NULL); if (data->swap < 0) return -ENODEV; Loading Loading @@ -394,12 +410,6 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, } #ifdef CONFIG_COMPAT struct compat_resume_swap_area { compat_loff_t offset; u32 dev; } __packed; static long snapshot_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { Loading @@ -410,33 +420,13 @@ snapshot_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case SNAPSHOT_AVAIL_SWAP_SIZE: case SNAPSHOT_ALLOC_SWAP_PAGE: case SNAPSHOT_CREATE_IMAGE: case SNAPSHOT_SET_SWAP_AREA: return snapshot_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); case SNAPSHOT_SET_SWAP_AREA: { struct compat_resume_swap_area __user *u_swap_area = compat_ptr(arg); struct resume_swap_area swap_area; mm_segment_t old_fs; int err; err = get_user(swap_area.offset, &u_swap_area->offset); err |= get_user(swap_area.dev, &u_swap_area->dev); if (err) return -EFAULT; old_fs = get_fs(); set_fs(KERNEL_DS); err = snapshot_ioctl(file, SNAPSHOT_SET_SWAP_AREA, (unsigned long) &swap_area); set_fs(old_fs); return err; } default: return snapshot_ioctl(file, cmd, arg); } } #endif /* CONFIG_COMPAT */ static const struct file_operations snapshot_fops = { Loading Loading
kernel/power/user.c +22 −32 Original line number Diff line number Diff line Loading @@ -196,28 +196,44 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf, return res; } struct compat_resume_swap_area { compat_loff_t offset; u32 dev; } __packed; static int snapshot_set_swap_area(struct snapshot_data *data, void __user *argp) { struct resume_swap_area swap_area; sector_t offset; dev_t swdev; if (swsusp_swap_in_use()) return -EPERM; if (in_compat_syscall()) { struct compat_resume_swap_area swap_area; if (copy_from_user(&swap_area, argp, sizeof(swap_area))) return -EFAULT; swdev = new_decode_dev(swap_area.dev); offset = swap_area.offset; } else { struct resume_swap_area swap_area; if (copy_from_user(&swap_area, argp, sizeof(swap_area))) return -EFAULT; swdev = new_decode_dev(swap_area.dev); offset = swap_area.offset; } /* * User space encodes device types as two-byte values, * so we need to recode them */ swdev = new_decode_dev(swap_area.dev); if (!swdev) { data->swap = -1; return -EINVAL; } offset = swap_area.offset; data->swap = swap_type_of(swdev, offset, NULL); if (data->swap < 0) return -ENODEV; Loading Loading @@ -394,12 +410,6 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, } #ifdef CONFIG_COMPAT struct compat_resume_swap_area { compat_loff_t offset; u32 dev; } __packed; static long snapshot_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { Loading @@ -410,33 +420,13 @@ snapshot_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case SNAPSHOT_AVAIL_SWAP_SIZE: case SNAPSHOT_ALLOC_SWAP_PAGE: case SNAPSHOT_CREATE_IMAGE: case SNAPSHOT_SET_SWAP_AREA: return snapshot_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); case SNAPSHOT_SET_SWAP_AREA: { struct compat_resume_swap_area __user *u_swap_area = compat_ptr(arg); struct resume_swap_area swap_area; mm_segment_t old_fs; int err; err = get_user(swap_area.offset, &u_swap_area->offset); err |= get_user(swap_area.dev, &u_swap_area->dev); if (err) return -EFAULT; old_fs = get_fs(); set_fs(KERNEL_DS); err = snapshot_ioctl(file, SNAPSHOT_SET_SWAP_AREA, (unsigned long) &swap_area); set_fs(old_fs); return err; } default: return snapshot_ioctl(file, cmd, arg); } } #endif /* CONFIG_COMPAT */ static const struct file_operations snapshot_fops = { Loading