@@ -352,7 +352,7 @@ static bool convert_bpf_extensions(struct sock_filter *fp,
352
352
* bpf_convert_filter - convert filter program
353
353
* @prog: the user passed filter program
354
354
* @len: the length of the user passed filter program
355
- * @new_prog: buffer where converted program will be stored
355
+ * @new_prog: allocated 'struct bpf_prog' or NULL
356
356
* @new_len: pointer to store length of converted program
357
357
*
358
358
* Remap 'sock_filter' style classic BPF (cBPF) instruction set to 'bpf_insn'
@@ -364,14 +364,13 @@ static bool convert_bpf_extensions(struct sock_filter *fp,
364
364
*
365
365
* 2) 2nd pass to remap in two passes: 1st pass finds new
366
366
* jump offsets, 2nd pass remapping:
367
- * new_prog = kmalloc(sizeof(struct bpf_insn) * new_len);
368
367
* bpf_convert_filter(old_prog, old_len, new_prog, &new_len);
369
368
*/
370
369
static int bpf_convert_filter (struct sock_filter * prog , int len ,
371
- struct bpf_insn * new_prog , int * new_len )
370
+ struct bpf_prog * new_prog , int * new_len )
372
371
{
373
- int new_flen = 0 , pass = 0 , target , i ;
374
- struct bpf_insn * new_insn ;
372
+ int new_flen = 0 , pass = 0 , target , i , stack_off ;
373
+ struct bpf_insn * new_insn , * first_insn = NULL ;
375
374
struct sock_filter * fp ;
376
375
int * addrs = NULL ;
377
376
u8 bpf_src ;
@@ -383,18 +382,19 @@ static int bpf_convert_filter(struct sock_filter *prog, int len,
383
382
return - EINVAL ;
384
383
385
384
if (new_prog ) {
385
+ first_insn = new_prog -> insnsi ;
386
386
addrs = kcalloc (len , sizeof (* addrs ),
387
387
GFP_KERNEL | __GFP_NOWARN );
388
388
if (!addrs )
389
389
return - ENOMEM ;
390
390
}
391
391
392
392
do_pass :
393
- new_insn = new_prog ;
393
+ new_insn = first_insn ;
394
394
fp = prog ;
395
395
396
396
/* Classic BPF related prologue emission. */
397
- if (new_insn ) {
397
+ if (new_prog ) {
398
398
/* Classic BPF expects A and X to be reset first. These need
399
399
* to be guaranteed to be the first two instructions.
400
400
*/
@@ -415,7 +415,7 @@ static int bpf_convert_filter(struct sock_filter *prog, int len,
415
415
struct bpf_insn * insn = tmp_insns ;
416
416
417
417
if (addrs )
418
- addrs [i ] = new_insn - new_prog ;
418
+ addrs [i ] = new_insn - first_insn ;
419
419
420
420
switch (fp -> code ) {
421
421
/* All arithmetic insns and skb loads map as-is. */
@@ -561,17 +561,25 @@ static int bpf_convert_filter(struct sock_filter *prog, int len,
561
561
/* Store to stack. */
562
562
case BPF_ST :
563
563
case BPF_STX :
564
+ stack_off = fp -> k * 4 + 4 ;
564
565
* insn = BPF_STX_MEM (BPF_W , BPF_REG_FP , BPF_CLASS (fp -> code ) ==
565
566
BPF_ST ? BPF_REG_A : BPF_REG_X ,
566
- - (BPF_MEMWORDS - fp -> k ) * 4 );
567
+ - stack_off );
568
+ /* check_load_and_stores() verifies that classic BPF can
569
+ * load from stack only after write, so tracking
570
+ * stack_depth for ST|STX insns is enough
571
+ */
572
+ if (new_prog && new_prog -> aux -> stack_depth < stack_off )
573
+ new_prog -> aux -> stack_depth = stack_off ;
567
574
break ;
568
575
569
576
/* Load from stack. */
570
577
case BPF_LD | BPF_MEM :
571
578
case BPF_LDX | BPF_MEM :
579
+ stack_off = fp -> k * 4 + 4 ;
572
580
* insn = BPF_LDX_MEM (BPF_W , BPF_CLASS (fp -> code ) == BPF_LD ?
573
581
BPF_REG_A : BPF_REG_X , BPF_REG_FP ,
574
- - ( BPF_MEMWORDS - fp -> k ) * 4 );
582
+ - stack_off );
575
583
break ;
576
584
577
585
/* A = K or X = K */
@@ -619,13 +627,13 @@ static int bpf_convert_filter(struct sock_filter *prog, int len,
619
627
620
628
if (!new_prog ) {
621
629
/* Only calculating new length. */
622
- * new_len = new_insn - new_prog ;
630
+ * new_len = new_insn - first_insn ;
623
631
return 0 ;
624
632
}
625
633
626
634
pass ++ ;
627
- if (new_flen != new_insn - new_prog ) {
628
- new_flen = new_insn - new_prog ;
635
+ if (new_flen != new_insn - first_insn ) {
636
+ new_flen = new_insn - first_insn ;
629
637
if (pass > 2 )
630
638
goto err ;
631
639
goto do_pass ;
@@ -1017,7 +1025,7 @@ static struct bpf_prog *bpf_migrate_filter(struct bpf_prog *fp)
1017
1025
fp -> len = new_len ;
1018
1026
1019
1027
/* 2nd pass: remap sock_filter insns into bpf_insn insns. */
1020
- err = bpf_convert_filter (old_prog , old_len , fp -> insnsi , & new_len );
1028
+ err = bpf_convert_filter (old_prog , old_len , fp , & new_len );
1021
1029
if (err )
1022
1030
/* 2nd bpf_convert_filter() can fail only if it fails
1023
1031
* to allocate memory, remapping must succeed. Note,
0 commit comments