From: Kent Overstreet <k...@daterainc.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit b3fa7e77e67e647db3db2166b65083a427d84ed3 upstream.

The real fix is where we check the bytes we need against how much is
remaining - we also need to check for a journal entry bigger than our
buffer, we'll never write those and it would be bad if we tried to read
one.

Also improve the diagnostic messages.

Signed-off-by: Kent Overstreet <k...@daterainc.com>
Signed-off-by: Jiri Slaby <jsl...@suse.cz>
---
 drivers/md/bcache/journal.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
index 8435f81e5d85..c4943793cb86 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -42,11 +42,11 @@ static int journal_read_bucket(struct cache *ca, struct 
list_head *list,
        int ret = 0;
        sector_t bucket = bucket_to_sector(ca->set, ca->sb.d[bucket_index]);
 
-       pr_debug("reading %llu", (uint64_t) bucket);
+       pr_debug("reading %u", bucket_index);
 
        while (offset < ca->sb.bucket_size) {
 reread:                left = ca->sb.bucket_size - offset;
-               len = min_t(unsigned, left, PAGE_SECTORS * 8);
+               len = min_t(unsigned, left, PAGE_SECTORS << JSET_BITS);
 
                bio_reset(bio);
                bio->bi_sector  = bucket + offset;
@@ -72,17 +72,26 @@ reread:             left = ca->sb.bucket_size - offset;
                        struct list_head *where;
                        size_t blocks, bytes = set_bytes(j);
 
-                       if (j->magic != jset_magic(ca->set))
+                       if (j->magic != jset_magic(ca->set)) {
+                               pr_debug("%u: bad magic", bucket_index);
                                return ret;
+                       }
 
-                       if (bytes > left << 9)
+                       if (bytes > left << 9 ||
+                           bytes > PAGE_SIZE << JSET_BITS) {
+                               pr_info("%u: too big, %zu bytes, offset %u",
+                                       bucket_index, bytes, offset);
                                return ret;
+                       }
 
                        if (bytes > len << 9)
                                goto reread;
 
-                       if (j->csum != csum_set(j))
+                       if (j->csum != csum_set(j)) {
+                               pr_info("%u: bad csum, %zu bytes, offset %u",
+                                       bucket_index, bytes, offset);
                                return ret;
+                       }
 
                        blocks = set_blocks(j, ca->set);
 
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to