part_test_mac(), part_print_mac() and part_get_info_mac() each declare a
single-block buffer sized after the descriptor struct:

        ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
        ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1);

Both structs are 512 bytes, but every blk_dread() below them asks for one
block, which transfers desc->blksz bytes. On a device with 4096-byte
logical blocks that writes 4096 bytes into a 512-byte on-stack buffer and
corrupts the stack.

part_test_mac() runs on every block device during partition probing, so on
sandbox with CONFIG_MAC_PARTITION=y this crashes on any access at all to a
device with large blocks, for instance:

        host bind 0 disk.img 4096
        part list host 0

Pad the buffers out to the block size with ALLOC_CACHE_ALIGN_BUFFER_PAD(),
which is what part_efi.c already does for its own block buffers.

Signed-off-by: Alexey Charkov <[email protected]>
---
 disk/part_mac.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/disk/part_mac.c b/disk/part_mac.c
index dd3ce0be832b..f0afab65d755 100644
--- a/disk/part_mac.c
+++ b/disk/part_mac.c
@@ -37,8 +37,8 @@ static int part_mac_read_pdb(struct blk_desc *desc, int part,
  */
 static int part_test_mac(struct blk_desc *desc)
 {
-       ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
-       ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1);
+       ALLOC_CACHE_ALIGN_BUFFER_PAD(mac_driver_desc_t, ddesc, 1, desc->blksz);
+       ALLOC_CACHE_ALIGN_BUFFER_PAD(mac_partition_t, mpart, 1, desc->blksz);
        ulong i, n;
 
        if (part_mac_read_ddb(desc, ddesc)) {
@@ -64,8 +64,8 @@ static int part_test_mac(struct blk_desc *desc)
 static void part_print_mac(struct blk_desc *desc)
 {
        ulong i, n;
-       ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
-       ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1);
+       ALLOC_CACHE_ALIGN_BUFFER_PAD(mac_driver_desc_t, ddesc, 1, desc->blksz);
+       ALLOC_CACHE_ALIGN_BUFFER_PAD(mac_partition_t, mpart, 1, desc->blksz);
        ldiv_t mb, gb;
 
        if (part_mac_read_ddb(desc, ddesc)) {
@@ -208,8 +208,8 @@ static int part_mac_read_pdb(struct blk_desc *desc, int 
part,
 static int part_get_info_mac(struct blk_desc *desc, int part,
                             struct disk_partition *info)
 {
-       ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1);
-       ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1);
+       ALLOC_CACHE_ALIGN_BUFFER_PAD(mac_driver_desc_t, ddesc, 1, desc->blksz);
+       ALLOC_CACHE_ALIGN_BUFFER_PAD(mac_partition_t, mpart, 1, desc->blksz);
 
        if (part_mac_read_ddb(desc, ddesc))
                return -1;

-- 
2.54.0

Reply via email to