On Wed, May 16, 2012 at 03:33:45PM -0700, Anton Vorontsov wrote:
On Wed, May 16, 2012 at 09:49:11AM -0700, Kees Cook wrote: [...]
+#ifdef CONFIG_PSTORE_CONSOLE +static void pstore_console_write(struct console *con, const char *s, unsigned c) +{
- strncpy(psinfo->buf, s, c);
The size of psinfo->buf needs to be the length argument to strncpy, not the size of "s". If "s" isn't NULL terminated, then the min of c and buf's size should be used. And if this should be NULL terminated in buf, that needs to be added manually since strncpy won't do it if it hits the max length argument.
Whoops. Will fix it, thanks!
Actually, we shouldn't bother with NUL-termination at all. We should do, is just carefully copy all 'c' elements of 's' into pstore in 'pstore->bufsize' chunks.
So, the code should be something along these lines:
static void pstore_console_write(struct console *con, const char *s, unsigned c) { const char *e = s + c;
while (s < e) { if (c > psinfo->bufsize) c = psinfo->bufsize; memcpy(psinfo->buf, s, c); psinfo->write(PSTORE_TYPE_CONSOLE, 0, NULL, 0, c, psinfo); s += c; c = e - s; } }
Here, in case of c > bufsize, we can't just copy bufsize bytes once and exit, since 'bufsize' doesn't tell anything about TYPE_CONSOLE's internal storage size (today console's persistent ram zone size and pstore's bufsize are equal, but this is something we may change soon, i.e. make TYPE_DMESG and TYPE_CONSOLE record sizes configurable).
Thanks,