On 01/17/2019 07:32 PM, Martin Lau wrote:
> On Thu, Jan 17, 2019 at 04:34:45PM +0100, Daniel Borkmann wrote:
>> During review I noticed that inner meta map setup for map in
>> map is buggy in that it does not propagate all needed data
>> from the reference map which the verifier is later accessing.
>>
>> In particular one such case is index masking to prevent out of
>> bounds access under speculative execution due to missing the
>> map's unpriv_array/index_mask field propagation. Fix this such
>> that the verifier is generating the correct code for inlined
>> lookups in case of unpriviledged use.
>>
>> Before patch (test_verifier's 'map in map access' dump):
>>
>>   # bpftool prog dump xla id 3
>>      0: (62) *(u32 *)(r10 -4) = 0
>>      1: (bf) r2 = r10
>>      2: (07) r2 += -4
>>      3: (18) r1 = map[id:4]
>>      5: (07) r1 += 272                |
>>      6: (61) r0 = *(u32 *)(r2 +0)     |
>>      7: (35) if r0 >= 0x1 goto pc+6   | Inlined map in map lookup
>>      8: (54) (u32) r0 &= (u32) 0      | with index masking for
>>      9: (67) r0 <<= 3                 | map->unpriv_array.
>>     10: (0f) r0 += r1                 |
>>     11: (79) r0 = *(u64 *)(r0 +0)     |
>>     12: (15) if r0 == 0x0 goto pc+1   |
>>     13: (05) goto pc+1                |
>>     14: (b7) r0 = 0                   |
>>     15: (15) if r0 == 0x0 goto pc+11
>>     16: (62) *(u32 *)(r10 -4) = 0
>>     17: (bf) r2 = r10
>>     18: (07) r2 += -4
>>     19: (bf) r1 = r0
>>     20: (07) r1 += 272                |
>>     21: (61) r0 = *(u32 *)(r2 +0)     | Index masking missing (!)
>>     22: (35) if r0 >= 0x1 goto pc+3   | for inner map despite
>>     23: (67) r0 <<= 3                 | map->unpriv_array set.
>>     24: (0f) r0 += r1                 |
>>     25: (05) goto pc+1                |
>>     26: (b7) r0 = 0                   |
>>     27: (b7) r0 = 0
>>     28: (95) exit
>>
>> After patch:
>>
>>   # bpftool prog dump xla id 1
>>      0: (62) *(u32 *)(r10 -4) = 0
>>      1: (bf) r2 = r10
>>      2: (07) r2 += -4
>>      3: (18) r1 = map[id:2]
>>      5: (07) r1 += 272                |
>>      6: (61) r0 = *(u32 *)(r2 +0)     |
>>      7: (35) if r0 >= 0x1 goto pc+6   | Same inlined map in map lookup
>>      8: (54) (u32) r0 &= (u32) 0      | with index masking due to
>>      9: (67) r0 <<= 3                 | map->unpriv_array.
>>     10: (0f) r0 += r1                 |
>>     11: (79) r0 = *(u64 *)(r0 +0)     |
>>     12: (15) if r0 == 0x0 goto pc+1   |
>>     13: (05) goto pc+1                |
>>     14: (b7) r0 = 0                   |
>>     15: (15) if r0 == 0x0 goto pc+12
>>     16: (62) *(u32 *)(r10 -4) = 0
>>     17: (bf) r2 = r10
>>     18: (07) r2 += -4
>>     19: (bf) r1 = r0
>>     20: (07) r1 += 272                |
>>     21: (61) r0 = *(u32 *)(r2 +0)     |
>>     22: (35) if r0 >= 0x1 goto pc+4   | Now fixed inlined inner map
>>     23: (54) (u32) r0 &= (u32) 0      | lookup with proper index masking
>>     24: (67) r0 <<= 3                 | for map->unpriv_array.
>>     25: (0f) r0 += r1                 |
>>     26: (05) goto pc+1                |
>>     27: (b7) r0 = 0                   |
>>     28: (b7) r0 = 0
>>     29: (95) exit
>>
>> Fixes: b2157399cc98 ("bpf: prevent out-of-bounds speculation")
>> Signed-off-by: Daniel Borkmann <dan...@iogearbox.net>
> The fix looks great.  Thanks for the fix!
> In the future if there is another exception other than
> array_map, a inner_map->ops->map_meta_alloc() can be introduced?

Yeah, probably makes sense if there will be more users in future.

> Acked-by: Martin KaFai Lau <ka...@fb.com>

Reply via email to