Messages in this thread Patch in this message | | | From | Bart Van Assche <> | Subject | Re: [PATCH 2/4] configfs: Fix writing at a non-zero offset | Date | Tue, 27 Jul 2021 09:47:24 -0700 |
| |
On 7/27/21 12:27 AM, Bodo Stroesser wrote: > What I meant is, that changing the source code in such a way, that > writing a buffer in multiple writes works in general, could cause > trouble in case userspace uses this. > > But for special syscall sequences your changes still change the result > on existing configfs files. Example: > > 1) userspace program opens qfull_time_out > 2) userspace program writes "90", count=2 to set timeout to 90 sec > 3) userspace again wants to change timeout, so it writes "55", count=2 > > Before the changes we end up with timeout being 55 seconds. After the > change - due to data gathering - we finally have timeout 9055 seconds.
Hi Bodo,
How about replacing patches 1 and 2 from this series with the patch below? Do you agree that this patch is sufficient to restore the behavior from kernel v5.13 and before?
Thanks,
Bart.
Subject: [PATCH 1/3] configfs: Restore the kernel v5.13 text attribute write behavior
Instead of writing at the offset specified by the write() system call, always write at offset zero.
Cc: Bodo Stroesser <bostroesser@gmail.com> Cc: Martin K. Petersen <martin.petersen@oracle.com> Cc: Yanko Kaneti <yaneti@declera.com> Cc: Brendan Higgins <brendanhiggins@google.com> Reported-by: Bodo Stroesser <bostroesser@gmail.com> Signed-off-by: Bart Van Assche <bvanassche@acm.org> --- fs/configfs/file.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/fs/configfs/file.c b/fs/configfs/file.c index 5a0be9985bae..8adf6250b207 100644 --- a/fs/configfs/file.c +++ b/fs/configfs/file.c @@ -177,12 +177,11 @@ static ssize_t configfs_bin_read_iter(struct kiocb *iocb, struct iov_iter *to) return retval; }
-/* Fill [buffer, buffer + pos) with data coming from @from. */ -static int fill_write_buffer(struct configfs_buffer *buffer, loff_t pos, +/* Fill @buffer with data coming from @from. */ +static int fill_write_buffer(struct configfs_buffer *buffer, struct iov_iter *from) { - loff_t to_copy; - int copied; + int to_copy, copied; u8 *to;
if (!buffer->page) @@ -190,11 +189,8 @@ static int fill_write_buffer(struct configfs_buffer *buffer, loff_t pos, if (!buffer->page) return -ENOMEM;
- to_copy = SIMPLE_ATTR_SIZE - 1 - pos; - if (to_copy <= 0) - return 0; - to = buffer->page + pos; - copied = copy_from_iter(to, to_copy, from); + to = buffer->page; + copied = copy_from_iter(to, SIMPLE_ATTR_SIZE - 1, from); buffer->needs_read_fill = 1; /* if buf is assumed to contain a string, terminate it by \0, * so e.g. sscanf() can scan the string easily */ @@ -227,14 +223,14 @@ static ssize_t configfs_write_iter(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb->ki_filp; struct configfs_buffer *buffer = file->private_data; - ssize_t len; + int len;
mutex_lock(&buffer->mutex); - len = fill_write_buffer(buffer, iocb->ki_pos, from); + len = fill_write_buffer(buffer, from); if (len > 0) len = flush_write_buffer(file, buffer, len); if (len > 0) - iocb->ki_pos += len; + iocb->ki_pos = len; mutex_unlock(&buffer->mutex); return len; }
| |