* improve the uswsusp ioctl handling to avoid set_fs @ 2020-04-06 11:58 Christoph Hellwig 2020-04-06 11:58 ` [PATCH 1/2] PM / sleep: move SNAPSHOT_SET_SWAP_AREA handling into a helper Christoph Hellwig 2020-04-06 11:58 ` [PATCH 2/2] PM / sleep: handle the compat case in snapshot_set_swap_area Christoph Hellwig 0 siblings, 2 replies; 4+ messages in thread From: Christoph Hellwig @ 2020-04-06 11:58 UTC (permalink / raw) To: Rafael J. Wysocki, Len Brown, Pavel Machek; +Cc: linux-pm, linux-kernel Hi all, this series refactors the uswsusp ioctl so that no rewriting of the ioctl structure for the compat case, and thus messing with the address limit is required. ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] PM / sleep: move SNAPSHOT_SET_SWAP_AREA handling into a helper 2020-04-06 11:58 improve the uswsusp ioctl handling to avoid set_fs Christoph Hellwig @ 2020-04-06 11:58 ` Christoph Hellwig 2020-04-06 11:58 ` [PATCH 2/2] PM / sleep: handle the compat case in snapshot_set_swap_area Christoph Hellwig 1 sibling, 0 replies; 4+ messages in thread From: Christoph Hellwig @ 2020-04-06 11:58 UTC (permalink / raw) To: Rafael J. Wysocki, Len Brown, Pavel Machek; +Cc: linux-pm, linux-kernel Move the handling of the SNAPSHOT_SET_SWAP_AREA ioctl from the main ioctl helper into a helper function. Signed-off-by: Christoph Hellwig <hch@lst.de> --- kernel/power/user.c | 57 +++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/kernel/power/user.c b/kernel/power/user.c index ef90eb1fb86e..0cb555f526e4 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -196,6 +196,34 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf, return res; } +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 (copy_from_user(&swap_area, argp, sizeof(swap_area))) + return -EFAULT; + + /* + * 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; + return 0; +} + static long snapshot_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -351,34 +379,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, break; case SNAPSHOT_SET_SWAP_AREA: - if (swsusp_swap_in_use()) { - error = -EPERM; - } else { - struct resume_swap_area swap_area; - dev_t swdev; - - error = copy_from_user(&swap_area, (void __user *)arg, - sizeof(struct resume_swap_area)); - if (error) { - error = -EFAULT; - break; - } - - /* - * User space encodes device types as two-byte values, - * so we need to recode them - */ - swdev = new_decode_dev(swap_area.dev); - if (swdev) { - offset = swap_area.offset; - data->swap = swap_type_of(swdev, offset, NULL); - if (data->swap < 0) - error = -ENODEV; - } else { - data->swap = -1; - error = -EINVAL; - } - } + error = snapshot_set_swap_area(data, (void __user *)arg); break; default: -- 2.25.1 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 2/2] PM / sleep: handle the compat case in snapshot_set_swap_area 2020-04-06 11:58 improve the uswsusp ioctl handling to avoid set_fs Christoph Hellwig 2020-04-06 11:58 ` [PATCH 1/2] PM / sleep: move SNAPSHOT_SET_SWAP_AREA handling into a helper Christoph Hellwig @ 2020-04-06 11:58 ` Christoph Hellwig 2020-04-06 19:45 ` Rafael J. Wysocki 1 sibling, 1 reply; 4+ messages in thread From: Christoph Hellwig @ 2020-04-06 11:58 UTC (permalink / raw) To: Rafael J. Wysocki, Len Brown, Pavel Machek; +Cc: linux-pm, linux-kernel Use in_compat_syscall to copy directly from the 32-bit ABI structure. Signed-off-by: Christoph Hellwig <hch@lst.de> --- kernel/power/user.c | 54 ++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/kernel/power/user.c b/kernel/power/user.c index 0cb555f526e4..7959449765d9 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -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 (copy_from_user(&swap_area, argp, sizeof(swap_area))) - return -EFAULT; + + 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; @@ -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) { @@ -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 = { -- 2.25.1 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 2/2] PM / sleep: handle the compat case in snapshot_set_swap_area 2020-04-06 11:58 ` [PATCH 2/2] PM / sleep: handle the compat case in snapshot_set_swap_area Christoph Hellwig @ 2020-04-06 19:45 ` Rafael J. Wysocki 0 siblings, 0 replies; 4+ messages in thread From: Rafael J. Wysocki @ 2020-04-06 19:45 UTC (permalink / raw) To: Christoph Hellwig Cc: Rafael J. Wysocki, Len Brown, Pavel Machek, Linux PM, Linux Kernel Mailing List On Mon, Apr 6, 2020 at 1:58 PM Christoph Hellwig <hch@lst.de> wrote: > > Use in_compat_syscall to copy directly from the 32-bit ABI structure. > > Signed-off-by: Christoph Hellwig <hch@lst.de> > --- > kernel/power/user.c | 54 ++++++++++++++++++--------------------------- > 1 file changed, 22 insertions(+), 32 deletions(-) > > diff --git a/kernel/power/user.c b/kernel/power/user.c > index 0cb555f526e4..7959449765d9 100644 > --- a/kernel/power/user.c > +++ b/kernel/power/user.c > @@ -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 (copy_from_user(&swap_area, argp, sizeof(swap_area))) > - return -EFAULT; > + > + 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; > @@ -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) > { > @@ -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 = { > -- Applied along with the [1/2] as 5.7-rc material, thanks! ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-04-06 19:45 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-04-06 11:58 improve the uswsusp ioctl handling to avoid set_fs Christoph Hellwig 2020-04-06 11:58 ` [PATCH 1/2] PM / sleep: move SNAPSHOT_SET_SWAP_AREA handling into a helper Christoph Hellwig 2020-04-06 11:58 ` [PATCH 2/2] PM / sleep: handle the compat case in snapshot_set_swap_area Christoph Hellwig 2020-04-06 19:45 ` Rafael J. Wysocki
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®