summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAhmad Fatoum <a.fatoum@pengutronix.de>2019-08-23 11:25:31 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2019-09-02 09:12:30 +0200
commit75a74b5c107b3bc30f9c3836208f4c17f9309eed (patch)
tree7e26a790234943bf84c46a1bd37ce4c84f84ed3c /fs
parentd421771bcea063b9bce551e06552067b9074d015 (diff)
downloadbarebox-75a74b5c107b3bc30f9c3836208f4c17f9309eed.tar.gz
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.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 0a6fa38..15c0174 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;