Skip to content

Commit f9e0ce3

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Alexei Starovoitov says: ==================== pull-request: bpf 2020-05-29 The following pull-request contains BPF updates for your *net* tree. We've added 6 non-merge commits during the last 7 day(s) which contain a total of 4 files changed, 55 insertions(+), 34 deletions(-). The main changes are: 1) minor verifier fix for fmod_ret progs, from Alexei. 2) af_xdp overflow check, from Bjorn. 3) minor verifier fix for 32bit assignment, from John. 4) powerpc has non-overlapping addr space, from Petr. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 942110f + cf66c29 commit f9e0ce3

File tree

4 files changed

+55
-34
lines changed

4 files changed

+55
-34
lines changed

arch/powerpc/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ config PPC
126126
select ARCH_HAS_MMIOWB if PPC64
127127
select ARCH_HAS_PHYS_TO_DMA
128128
select ARCH_HAS_PMEM_API
129+
select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
129130
select ARCH_HAS_PTE_DEVMAP if PPC_BOOK3S_64
130131
select ARCH_HAS_PTE_SPECIAL
131132
select ARCH_HAS_MEMBARRIER_CALLBACKS

kernel/bpf/verifier.c

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,14 +1168,14 @@ static void __reg_assign_32_into_64(struct bpf_reg_state *reg)
11681168
* but must be positive otherwise set to worse case bounds
11691169
* and refine later from tnum.
11701170
*/
1171-
if (reg->s32_min_value > 0)
1172-
reg->smin_value = reg->s32_min_value;
1173-
else
1174-
reg->smin_value = 0;
1175-
if (reg->s32_max_value > 0)
1171+
if (reg->s32_min_value >= 0 && reg->s32_max_value >= 0)
11761172
reg->smax_value = reg->s32_max_value;
11771173
else
11781174
reg->smax_value = U32_MAX;
1175+
if (reg->s32_min_value >= 0)
1176+
reg->smin_value = reg->s32_min_value;
1177+
else
1178+
reg->smin_value = 0;
11791179
}
11801180

11811181
static void __reg_combine_32_into_64(struct bpf_reg_state *reg)
@@ -10428,22 +10428,13 @@ static int check_struct_ops_btf_id(struct bpf_verifier_env *env)
1042810428
}
1042910429
#define SECURITY_PREFIX "security_"
1043010430

10431-
static int check_attach_modify_return(struct bpf_verifier_env *env)
10431+
static int check_attach_modify_return(struct bpf_prog *prog, unsigned long addr)
1043210432
{
10433-
struct bpf_prog *prog = env->prog;
10434-
unsigned long addr = (unsigned long) prog->aux->trampoline->func.addr;
10435-
10436-
/* This is expected to be cleaned up in the future with the KRSI effort
10437-
* introducing the LSM_HOOK macro for cleaning up lsm_hooks.h.
10438-
*/
1043910433
if (within_error_injection_list(addr) ||
1044010434
!strncmp(SECURITY_PREFIX, prog->aux->attach_func_name,
1044110435
sizeof(SECURITY_PREFIX) - 1))
1044210436
return 0;
1044310437

10444-
verbose(env, "fmod_ret attach_btf_id %u (%s) is not modifiable\n",
10445-
prog->aux->attach_btf_id, prog->aux->attach_func_name);
10446-
1044710438
return -EINVAL;
1044810439
}
1044910440

@@ -10654,11 +10645,18 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
1065410645
goto out;
1065510646
}
1065610647
}
10648+
10649+
if (prog->expected_attach_type == BPF_MODIFY_RETURN) {
10650+
ret = check_attach_modify_return(prog, addr);
10651+
if (ret)
10652+
verbose(env, "%s() is not modifiable\n",
10653+
prog->aux->attach_func_name);
10654+
}
10655+
10656+
if (ret)
10657+
goto out;
1065710658
tr->func.addr = (void *)addr;
1065810659
prog->aux->trampoline = tr;
10659-
10660-
if (prog->expected_attach_type == BPF_MODIFY_RETURN)
10661-
ret = check_attach_modify_return(env);
1066210660
out:
1066310661
mutex_unlock(&tr->mutex);
1066410662
if (ret)

net/xdp/xdp_umem.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,8 +341,8 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
341341
{
342342
bool unaligned_chunks = mr->flags & XDP_UMEM_UNALIGNED_CHUNK_FLAG;
343343
u32 chunk_size = mr->chunk_size, headroom = mr->headroom;
344+
u64 npgs, addr = mr->addr, size = mr->len;
344345
unsigned int chunks, chunks_per_page;
345-
u64 addr = mr->addr, size = mr->len;
346346
int err;
347347

348348
if (chunk_size < XDP_UMEM_MIN_CHUNK_SIZE || chunk_size > PAGE_SIZE) {
@@ -372,6 +372,10 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
372372
if ((addr + size) < addr)
373373
return -EINVAL;
374374

375+
npgs = div_u64(size, PAGE_SIZE);
376+
if (npgs > U32_MAX)
377+
return -EINVAL;
378+
375379
chunks = (unsigned int)div_u64(size, chunk_size);
376380
if (chunks == 0)
377381
return -EINVAL;
@@ -391,7 +395,7 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
391395
umem->size = size;
392396
umem->headroom = headroom;
393397
umem->chunk_size_nohr = chunk_size - headroom;
394-
umem->npgs = size / PAGE_SIZE;
398+
umem->npgs = (u32)npgs;
395399
umem->pgs = NULL;
396400
umem->user = NULL;
397401
umem->flags = mr->flags;

tools/testing/selftests/bpf/verifier/bounds.c

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@
238238
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
239239
BPF_LD_MAP_FD(BPF_REG_1, 0),
240240
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
241-
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
241+
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
242242
/* r1 = [0x00, 0xff] */
243243
BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
244244
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
@@ -253,10 +253,6 @@
253253
* [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
254254
*/
255255
BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
256-
/* r1 = 0 or
257-
* [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
258-
*/
259-
BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
260256
/* error on OOB pointer computation */
261257
BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
262258
/* exit */
@@ -265,8 +261,10 @@
265261
},
266262
.fixup_map_hash_8b = { 3 },
267263
/* not actually fully unbounded, but the bound is very high */
268-
.errstr = "value 72057594021150720 makes map_value pointer be out of bounds",
269-
.result = REJECT
264+
.errstr_unpriv = "R1 has unknown scalar with mixed signed bounds, pointer arithmetic with it prohibited for !root",
265+
.result_unpriv = REJECT,
266+
.errstr = "value -4294967168 makes map_value pointer be out of bounds",
267+
.result = REJECT,
270268
},
271269
{
272270
"bounds check after truncation of boundary-crossing range (2)",
@@ -276,7 +274,7 @@
276274
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
277275
BPF_LD_MAP_FD(BPF_REG_1, 0),
278276
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
279-
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
277+
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
280278
/* r1 = [0x00, 0xff] */
281279
BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
282280
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
@@ -293,10 +291,6 @@
293291
* [0xffff'ffff'0000'0080, 0xffff'ffff'ffff'ffff]
294292
*/
295293
BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
296-
/* r1 = 0 or
297-
* [0x00ff'ffff'ff00'0000, 0x00ff'ffff'ffff'ffff]
298-
*/
299-
BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
300294
/* error on OOB pointer computation */
301295
BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
302296
/* exit */
@@ -305,8 +299,10 @@
305299
},
306300
.fixup_map_hash_8b = { 3 },
307301
/* not actually fully unbounded, but the bound is very high */
308-
.errstr = "value 72057594021150720 makes map_value pointer be out of bounds",
309-
.result = REJECT
302+
.errstr_unpriv = "R1 has unknown scalar with mixed signed bounds, pointer arithmetic with it prohibited for !root",
303+
.result_unpriv = REJECT,
304+
.errstr = "value -4294967168 makes map_value pointer be out of bounds",
305+
.result = REJECT,
310306
},
311307
{
312308
"bounds check after wrapping 32-bit addition",
@@ -539,3 +535,25 @@
539535
},
540536
.result = ACCEPT
541537
},
538+
{
539+
"assigning 32bit bounds to 64bit for wA = 0, wB = wA",
540+
.insns = {
541+
BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_1,
542+
offsetof(struct __sk_buff, data_end)),
543+
BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
544+
offsetof(struct __sk_buff, data)),
545+
BPF_MOV32_IMM(BPF_REG_9, 0),
546+
BPF_MOV32_REG(BPF_REG_2, BPF_REG_9),
547+
BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
548+
BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_2),
549+
BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
550+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 8),
551+
BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_8, 1),
552+
BPF_LDX_MEM(BPF_W, BPF_REG_5, BPF_REG_6, 0),
553+
BPF_MOV64_IMM(BPF_REG_0, 0),
554+
BPF_EXIT_INSN(),
555+
},
556+
.prog_type = BPF_PROG_TYPE_SCHED_CLS,
557+
.result = ACCEPT,
558+
.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
559+
},

0 commit comments

Comments
 (0)