Replace copy_from_iter() with copy_from_user() 34/268734/4
authorŁukasz Stelmach <l.stelmach@samsung.com>
Thu, 16 Dec 2021 19:03:53 +0000 (20:03 +0100)
committerŁukasz Stelmach <l.stelmach@samsung.com>
Tue, 4 Jan 2022 21:14:36 +0000 (22:14 +0100)
iov_iter structure and associated function have been introduced in
v3.18. Logger needs use copy_from_user() and iterate over IO vectores
manualy.

Change-Id: Ifa46c67da65195611adc50b1dc6f0be66daac517
Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
kernel/logger.c

index 9dbe22a..4eb7103 100644 (file)
@@ -623,7 +623,6 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
        struct logger_entry header;
        struct timespec now;
        ssize_t ret = 0;
-       size_t count;
        bool from_stdio = false;
 
        if (writer->tag && writer->prio >= 2)
@@ -651,6 +650,8 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
                size_t chunk_len = 0, c = 0;
                /* -2 : priority byte and tag terminating '\0' */
                size_t max_payload = LOGGER_ENTRY_MAX_PAYLOAD - writer->tag_len - 2;
+               /* offset in the *current* iov */
+               size_t iov_offset = 0;
 
                if (writer->owner != current->group_leader) {
                        struct file *nfile;
@@ -680,19 +681,21 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
                if (writer->b_owner != current && writer->b_off)
                        flush_thread_data(file);
 
-               count = 0;
                /* -1 : leave space for message terminating '\0' */
-               c = min_t(size_t, iov_iter_count(from),
+               c = min_t(size_t, iov->iov_len,
                          max_payload - writer->b_off - 1);
 
                do {
                        size_t i;
 
-                       if (copy_from_iter(writer->buffer + writer->b_off, c, from) != c) {
+                       if (copy_from_user(writer->buffer + writer->b_off, iov->iov_base + iov_offset, c)) {
                                mutex_unlock(&log->mutex);
                                return -EFAULT;
                        }
-                       count += c;
+
+                       ret += c;
+                       iov_offset += c;
+
                        p = NULL;
                        for (i = 0; i < c; ++i) {
                                char *t = &writer->buffer[writer->b_off + i];
@@ -729,7 +732,14 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
                        writer->b_off = writer->b_off + c - chunk_len;
                        writer->buffer[writer->b_off] = '\0';
 
-               } while ((c = min_t(size_t, iov_iter_count(from), max_payload - 1)));
+                       if (iov_offset >= iov->iov_len) {
+                               WARN_ON(iov_offset > iov->iov_len);
+                               nr_segs--;
+                               iov++;
+                               iov_offset = 0;
+                       }
+
+               } while (nr_segs && (c = min_t(size_t, iov->iov_len - iov_offset, max_payload - 1)));
 
                /* save for remaining unfinished line */
                writer->b_header = header;