logger: fix corner case in stdout mode 80/291680/1 accepted/tizen_7.0_unified tizen_7.0 accepted/tizen/7.0/unified/20230426.045629
authorMarek Szyprowski <m.szyprowski@samsung.com>
Wed, 19 Apr 2023 16:21:28 +0000 (18:21 +0200)
committerMarek Szyprowski <m.szyprowski@samsung.com>
Thu, 20 Apr 2023 07:27:16 +0000 (09:27 +0200)
Writing large messages via stdout API might trigger the following kernel
BUG:

usercopy: Kernel memory overwrite attempt detected to SLUB object 'kmalloc-4k' (offset 161, size 4062)!
------------[ cut here ]------------
kernel BUG at mm/usercopy.c:103!
Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
Modules linked in: r8168(O) pgdrv(O) machine_dlkm(O) wcd938x_slave_dlkm(O) wcd938x_dlkm(O) wcd9xxx_dlkm(O) tx_ma)
Process ros2 (pid: 10140, stack limit = 0xffffff80103e0000)
CPU: 7 PID: 10140 Comm: ros2 Tainted: G S         O      4.19.157-arm64-rb5 #1
Hardware name: Qualcomm Technologies, Inc. qrb5165 IOT RB5 (DT)
pstate: 40400005 (nZcv daif +PAN -UAO)
pc : usercopy_abort+0xac/0xb0
lr : usercopy_abort+0xac/0xb0
..
Call trace:
 usercopy_abort+0xac/0xb0
 __check_heap_object+0x14c/0x168
 __check_object_size.part.0+0x22c/0x410
 __check_object_size+0x48/0x58
 logger_write_iter+0x26c/0x5b8 [logger]
 __vfs_write+0x124/0x178
 vfs_write+0xb8/0x1d0
 ksys_write+0x74/0xe8
 __arm64_sys_write+0x24/0x30
 el0_svc_common.constprop.0+0x78/0x170
 el0_svc_handler+0x70/0x90
 el0_svc+0x8/0xc
Code: aa1403e3 9000e3a0 910c2000 97fa0b2f (d4210000)
---[ end trace 7bfe613c5072c5df ]---

Fix this by properly adjusting the size of the data-to-be-copied for the
next loop iteration.

[backport of the commit bde6525 ("logger: fix corner case in stdout mode")
 from the tizen branch]
Change-Id: I4d9cb223eb294159a0a858701a09f6547c4dd7c2
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
kernel/logger.c

index 62b1d32..e8bfe49 100644 (file)
@@ -773,7 +773,7 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
                                iov_offset = 0;
                        }
 
-               } while (nr_segs && (c = min_t(size_t, iov->iov_len - iov_offset, max_payload - 1)));
+               } while (nr_segs && (c = min_t(size_t, iov->iov_len - iov_offset, max_payload - writer->b_off - 1)));
 
                /* save for remaining unfinished line */
                writer->b_header = header;
@@ -949,7 +949,7 @@ static ssize_t logger_write_iter(struct kiocb *iocb, struct iov_iter *from)
                        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)));
+               } while ((c = min_t(size_t, iov_iter_count(from), max_payload - writer->b_off - 1)));
 
                /* save for remaining unfinished line */
                writer->b_header = header;