diff options
author | Ahmad Fatoum <a.fatoum@pengutronix.de> | 2019-08-23 11:25:31 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-09-02 09:12:30 +0200 |
commit | 75a74b5c107b3bc30f9c3836208f4c17f9309eed (patch) | |
tree | 7e26a790234943bf84c46a1bd37ce4c84f84ed3c /fs | |
parent | d421771bcea063b9bce551e06552067b9074d015 (diff) | |
download | barebox-75a74b5c107b3bc30f9c3836208f4c17f9309eed.tar.gz barebox-75a74b5c107b3bc30f9c3836208f4c17f9309eed.tar.xz |
console: fix out-of-bounds read in dputc(/dev/*, ...)
Trying to output a single character via
echo -a /dev/serial0-1
currently results in garbage output after the newline, because console.c's
fops_write discards the buffer length and passes the buffer to
(struct cdev)::puts which only handles NUL-terminated strings.
Fix this by amending (struct cdev)::puts with a new nbytes parameter,
which is correctly propagated. All this functions now return at most the
nbytes parameter they were passed in. This fixes __console_puts, which
used to count new lines twice in its return value.
Fixes: b4f55fcf35 ("console: expose consoles in devfs")
Cc: Bastian Krause <bst@pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/pstore/platform.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 0a6fa38edc..15c0174b1f 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -46,6 +46,35 @@ void pstore_set_kmsg_bytes(int bytes) static int pstore_ready; +static void pstore_console_write(const char *s, unsigned c) +{ + const char *e = s + c; + + while (s < e) { + struct pstore_record record = { + .type = PSTORE_TYPE_CONSOLE, + .psi = psinfo, + }; + + if (c > psinfo->bufsize) + c = psinfo->bufsize; + + record.buf = (char *)s; + record.size = c; + psinfo->write_buf(PSTORE_TYPE_CONSOLE, 0, &record.id, 0, + record.buf, 0, record.size, psinfo); + s += c; + c = e - s; + } +} + +static int pstore_console_puts(struct console_device *cdev, const char *s, + size_t nbytes) +{ + pstore_console_write(s, nbytes); + return nbytes; +} + void pstore_log(const char *str) { uint64_t id; |