From: Richard Weinberger <rich...@nod.at>

commit 20f1431160c6b590cdc269a846fc5a448abf5b98 upstream

Write buffers use a kmalloc()'ed buffer, they can leak
up to seven bytes of kernel memory to flash if writes are not
aligned.
So use ubifs_pad() to fill these gaps with padding bytes.
This was never a problem while scanning because the scanner logic
manually aligns node lengths and skips over these gaps.

Cc: <sta...@vger.kernel.org>
Fixes: 1e51764a3c2ac05a2 ("UBIFS: add new flash file system")
Signed-off-by: Richard Weinberger <rich...@nod.at>
Reviewed-by: Zhihao Cheng <chengzhih...@huawei.com>
Signed-off-by: Richard Weinberger <rich...@nod.at>
[sudip: adjust context]
Signed-off-by: Sudip Mukherjee <sudipm.mukher...@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 fs/ubifs/io.c |   13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

--- a/fs/ubifs/io.c
+++ b/fs/ubifs/io.c
@@ -331,7 +331,7 @@ void ubifs_pad(const struct ubifs_info *
 {
        uint32_t crc;
 
-       ubifs_assert(pad >= 0 && !(pad & 7));
+       ubifs_assert(pad >= 0);
 
        if (pad >= UBIFS_PAD_NODE_SZ) {
                struct ubifs_ch *ch = buf;
@@ -727,6 +727,10 @@ int ubifs_wbuf_write_nolock(struct ubifs
                 * write-buffer.
                 */
                memcpy(wbuf->buf + wbuf->used, buf, len);
+               if (aligned_len > len) {
+                       ubifs_assert(aligned_len - len < 8);
+                       ubifs_pad(c, wbuf->buf + wbuf->used + len, aligned_len 
- len);
+               }
 
                if (aligned_len == wbuf->avail) {
                        dbg_io("flush jhead %s wbuf to LEB %d:%d",
@@ -819,13 +823,18 @@ int ubifs_wbuf_write_nolock(struct ubifs
        }
 
        spin_lock(&wbuf->lock);
-       if (aligned_len)
+       if (aligned_len) {
                /*
                 * And now we have what's left and what does not take whole
                 * max. write unit, so write it to the write-buffer and we are
                 * done.
                 */
                memcpy(wbuf->buf, buf + written, len);
+               if (aligned_len > len) {
+                       ubifs_assert(aligned_len - len < 8);
+                       ubifs_pad(c, wbuf->buf + len, aligned_len - len);
+               }
+       }
 
        if (c->leb_size - wbuf->offs >= c->max_write_size)
                wbuf->size = c->max_write_size;


Reply via email to