bcachefs: fix stack corruption
authorYuxuan Shui <yshuiv7@gmail.com>
Fri, 22 May 2020 14:50:05 +0000 (15:50 +0100)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:39 +0000 (17:08 -0400)
When a bkey_on_stack is passed to bch_read_indirect_extent, there is no
guarantee that it will be big enough to hold the bkey. And
bch_read_indirect_extent is not aware of bkey_on_stack to call realloc
on it. This cause a stack corruption.

This commit makes bch_read_indirect_extent aware of bkey_on_stack so it
can call realloc when appropriate.

Tested-by: Yuxuan Shui <yshuiv7@gmail.com>
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/fs-io.c
fs/bcachefs/fs.c
fs/bcachefs/io.c
fs/bcachefs/io.h

index 9644d4624f803bd150ec2a3496a9d14cd736a55f..7ce6d71aca29c5a55e47c420458ddf423e62564f 100644 (file)
@@ -788,7 +788,7 @@ retry:
                sectors = k.k->size - offset_into_extent;
 
                ret = bch2_read_indirect_extent(trans,
-                                       &offset_into_extent, sk.k);
+                                       &offset_into_extent, &sk);
                if (ret)
                        break;
 
index 4458a98b78eed073075d15292b923c98a7428ebd..6aff3203b4e101ec142c0133b02bf88aa5a14576 100644 (file)
@@ -918,7 +918,7 @@ retry:
                sectors                 = k.k->size - offset_into_extent;
 
                ret = bch2_read_indirect_extent(&trans,
-                                       &offset_into_extent, cur.k);
+                                       &offset_into_extent, &cur);
                if (ret)
                        break;
 
index 7df2b6c3f1680181ae25e15562abef31be0b0f82..39a23c6570eb89831db0fa5cc26729d3cc5ac83d 100644 (file)
@@ -1642,7 +1642,7 @@ retry:
                sectors = k.k->size - offset_into_extent;
 
                ret = bch2_read_indirect_extent(&trans,
-                                       &offset_into_extent, sk.k);
+                                       &offset_into_extent, &sk);
                if (ret)
                        break;
 
@@ -1944,14 +1944,14 @@ static void bch2_read_endio(struct bio *bio)
 
 int __bch2_read_indirect_extent(struct btree_trans *trans,
                                unsigned *offset_into_extent,
-                               struct bkey_i *orig_k)
+                               struct bkey_on_stack *orig_k)
 {
        struct btree_iter *iter;
        struct bkey_s_c k;
        u64 reflink_offset;
        int ret;
 
-       reflink_offset = le64_to_cpu(bkey_i_to_reflink_p(orig_k)->v.idx) +
+       reflink_offset = le64_to_cpu(bkey_i_to_reflink_p(orig_k->k)->v.idx) +
                *offset_into_extent;
 
        iter = bch2_trans_get_iter(trans, BTREE_ID_REFLINK,
@@ -1974,7 +1974,7 @@ int __bch2_read_indirect_extent(struct btree_trans *trans,
        }
 
        *offset_into_extent = iter->pos.offset - bkey_start_offset(k.k);
-       bkey_reassemble(orig_k, k);
+       bkey_on_stack_reassemble(orig_k, trans->c, k);
 err:
        bch2_trans_iter_put(trans, iter);
        return ret;
@@ -2281,7 +2281,7 @@ retry:
                k = bkey_i_to_s_c(sk.k);
 
                ret = bch2_read_indirect_extent(&trans,
-                                       &offset_into_extent, sk.k);
+                                       &offset_into_extent, &sk);
                if (ret)
                        goto err;
 
index 0a049cc14e42da6852daf2fab9f4c134b61d2648..f0fe0bf906d3c54334eefc7fb2eb29610a16065d 100644 (file)
@@ -3,6 +3,7 @@
 #define _BCACHEFS_IO_H
 
 #include "checksum.h"
+#include "bkey_on_stack.h"
 #include "io_types.h"
 
 #define to_wbio(_bio)                  \
@@ -114,13 +115,13 @@ struct cache_promote_op;
 struct extent_ptr_decoded;
 
 int __bch2_read_indirect_extent(struct btree_trans *, unsigned *,
-                               struct bkey_i *);
+                               struct bkey_on_stack *);
 
 static inline int bch2_read_indirect_extent(struct btree_trans *trans,
                                            unsigned *offset_into_extent,
-                                           struct bkey_i *k)
+                                           struct bkey_on_stack *k)
 {
-       return k->k.type == KEY_TYPE_reflink_p
+       return k->k->k.type == KEY_TYPE_reflink_p
                ? __bch2_read_indirect_extent(trans, offset_into_extent, k)
                : 0;
 }