]>
Commit | Line | Data |
---|---|---|
7be860c4 GKH |
1 | From foo@baz Mon Sep 17 12:15:09 CEST 2018 |
2 | From: Mauricio Faria de Oliveira <mfo@canonical.com> | |
3 | Date: Wed, 25 Jul 2018 22:46:28 -0300 | |
4 | Subject: partitions/aix: fix usage of uninitialized lv_info and lvname structures | |
5 | ||
6 | From: Mauricio Faria de Oliveira <mfo@canonical.com> | |
7 | ||
8 | [ Upstream commit 14cb2c8a6c5dae57ee3e2da10fa3db2b9087e39e ] | |
9 | ||
10 | The if-block that sets a successful return value in aix_partition() | |
11 | uses 'lvip[].pps_per_lv' and 'n[].name' potentially uninitialized. | |
12 | ||
13 | For example, if 'numlvs' is zero or alloc_lvn() fails, neither is | |
14 | initialized, but are used anyway if alloc_pvd() succeeds after it. | |
15 | ||
16 | So, make the alloc_pvd() call conditional on their initialization. | |
17 | ||
18 | This has been hit when attaching an apparently corrupted/stressed | |
19 | AIX LUN, misleading the kernel to pr_warn() invalid data and hang. | |
20 | ||
21 | [...] partition (null) (11 pp's found) is not contiguous | |
22 | [...] partition (null) (2 pp's found) is not contiguous | |
23 | [...] partition (null) (3 pp's found) is not contiguous | |
24 | [...] partition (null) (64 pp's found) is not contiguous | |
25 | ||
26 | Fixes: 6ceea22bbbc8 ("partitions: add aix lvm partition support files") | |
27 | Signed-off-by: Mauricio Faria de Oliveira <mfo@canonical.com> | |
28 | Signed-off-by: Jens Axboe <axboe@kernel.dk> | |
29 | Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> | |
30 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
31 | --- | |
32 | block/partitions/aix.c | 5 +++-- | |
33 | 1 file changed, 3 insertions(+), 2 deletions(-) | |
34 | ||
35 | --- a/block/partitions/aix.c | |
36 | +++ b/block/partitions/aix.c | |
37 | @@ -177,7 +177,7 @@ int aix_partition(struct parsed_partitio | |
38 | u32 vgda_sector = 0; | |
39 | u32 vgda_len = 0; | |
40 | int numlvs = 0; | |
41 | - struct pvd *pvd; | |
42 | + struct pvd *pvd = NULL; | |
43 | struct lv_info { | |
44 | unsigned short pps_per_lv; | |
45 | unsigned short pps_found; | |
46 | @@ -231,10 +231,11 @@ int aix_partition(struct parsed_partitio | |
47 | if (lvip[i].pps_per_lv) | |
48 | foundlvs += 1; | |
49 | } | |
50 | + /* pvd loops depend on n[].name and lvip[].pps_per_lv */ | |
51 | + pvd = alloc_pvd(state, vgda_sector + 17); | |
52 | } | |
53 | put_dev_sector(sect); | |
54 | } | |
55 | - pvd = alloc_pvd(state, vgda_sector + 17); | |
56 | if (pvd) { | |
57 | int numpps = be16_to_cpu(pvd->pp_count); | |
58 | int psn_part1 = be32_to_cpu(pvd->psn_part1); |