@@ -737,81 +737,104 @@ static void print_verifier_state(struct bpf_verifier_env *env,
737
737
verbose (env , "\n" );
738
738
}
739
739
740
- #define COPY_STATE_FN (NAME , COUNT , FIELD , SIZE ) \
741
- static int copy_##NAME##_state(struct bpf_func_state *dst, \
742
- const struct bpf_func_state *src) \
743
- { \
744
- if (!src->FIELD) \
745
- return 0; \
746
- if (WARN_ON_ONCE(dst->COUNT < src->COUNT)) { \
747
- /* internal bug, make state invalid to reject the program */ \
748
- memset (dst , 0 , sizeof (* dst )); \
749
- return - EFAULT ; \
750
- } \
751
- memcpy (dst -> FIELD , src -> FIELD , \
752
- sizeof (* src -> FIELD ) * (src -> COUNT / SIZE )); \
753
- return 0 ; \
754
- }
755
- /* copy_reference_state() */
756
- COPY_STATE_FN (reference , acquired_refs , refs , 1 )
757
- /* copy_stack_state() */
758
- COPY_STATE_FN (stack , allocated_stack , stack , BPF_REG_SIZE )
759
- #undef COPY_STATE_FN
760
-
761
- #define REALLOC_STATE_FN (NAME , COUNT , FIELD , SIZE ) \
762
- static int realloc_##NAME##_state(struct bpf_func_state *state, int size, \
763
- bool copy_old) \
764
- { \
765
- u32 old_size = state->COUNT; \
766
- struct bpf_##NAME##_state *new_##FIELD; \
767
- int slot = size / SIZE; \
768
- \
769
- if (size <= old_size || !size) { \
770
- if (copy_old) \
771
- return 0; \
772
- state->COUNT = slot * SIZE; \
773
- if (!size && old_size) { \
774
- kfree(state->FIELD); \
775
- state->FIELD = NULL; \
776
- } \
777
- return 0; \
778
- } \
779
- new_##FIELD = kmalloc_array(slot, sizeof(struct bpf_##NAME##_state), \
780
- GFP_KERNEL); \
781
- if (!new_##FIELD) \
782
- return -ENOMEM; \
783
- if (copy_old) { \
784
- if (state->FIELD) \
785
- memcpy(new_##FIELD, state->FIELD, \
786
- sizeof(*new_##FIELD) * (old_size / SIZE)); \
787
- memset(new_##FIELD + old_size / SIZE, 0, \
788
- sizeof(*new_##FIELD) * (size - old_size) / SIZE); \
789
- } \
790
- state->COUNT = slot * SIZE; \
791
- kfree(state->FIELD); \
792
- state->FIELD = new_##FIELD; \
793
- return 0; \
794
- }
795
- /* realloc_reference_state() */
796
- REALLOC_STATE_FN (reference , acquired_refs , refs , 1 )
797
- /* realloc_stack_state() */
798
- REALLOC_STATE_FN (stack , allocated_stack , stack , BPF_REG_SIZE )
799
- #undef REALLOC_STATE_FN
800
-
801
- /* do_check() starts with zero-sized stack in struct bpf_verifier_state to
802
- * make it consume minimal amount of memory. check_stack_write() access from
803
- * the program calls into realloc_func_state() to grow the stack size.
804
- * Note there is a non-zero 'parent' pointer inside bpf_verifier_state
805
- * which realloc_stack_state() copies over. It points to previous
806
- * bpf_verifier_state which is never reallocated.
740
+ /* copy array src of length n * size bytes to dst. dst is reallocated if it's too
741
+ * small to hold src. This is different from krealloc since we don't want to preserve
742
+ * the contents of dst.
743
+ *
744
+ * Leaves dst untouched if src is NULL or length is zero. Returns NULL if memory could
745
+ * not be allocated.
807
746
*/
808
- static int realloc_func_state (struct bpf_func_state * state , int stack_size ,
809
- int refs_size , bool copy_old )
747
+ static void * copy_array (void * dst , const void * src , size_t n , size_t size , gfp_t flags )
810
748
{
811
- int err = realloc_reference_state (state , refs_size , copy_old );
812
- if (err )
813
- return err ;
814
- return realloc_stack_state (state , stack_size , copy_old );
749
+ size_t bytes ;
750
+
751
+ if (ZERO_OR_NULL_PTR (src ))
752
+ goto out ;
753
+
754
+ if (unlikely (check_mul_overflow (n , size , & bytes )))
755
+ return NULL ;
756
+
757
+ if (ksize (dst ) < bytes ) {
758
+ kfree (dst );
759
+ dst = kmalloc_track_caller (bytes , flags );
760
+ if (!dst )
761
+ return NULL ;
762
+ }
763
+
764
+ memcpy (dst , src , bytes );
765
+ out :
766
+ return dst ? dst : ZERO_SIZE_PTR ;
767
+ }
768
+
769
+ /* resize an array from old_n items to new_n items. the array is reallocated if it's too
770
+ * small to hold new_n items. new items are zeroed out if the array grows.
771
+ *
772
+ * Contrary to krealloc_array, does not free arr if new_n is zero.
773
+ */
774
+ static void * realloc_array (void * arr , size_t old_n , size_t new_n , size_t size )
775
+ {
776
+ if (!new_n || old_n == new_n )
777
+ goto out ;
778
+
779
+ arr = krealloc_array (arr , new_n , size , GFP_KERNEL );
780
+ if (!arr )
781
+ return NULL ;
782
+
783
+ if (new_n > old_n )
784
+ memset (arr + old_n * size , 0 , (new_n - old_n ) * size );
785
+
786
+ out :
787
+ return arr ? arr : ZERO_SIZE_PTR ;
788
+ }
789
+
790
+ static int copy_reference_state (struct bpf_func_state * dst , const struct bpf_func_state * src )
791
+ {
792
+ dst -> refs = copy_array (dst -> refs , src -> refs , src -> acquired_refs ,
793
+ sizeof (struct bpf_reference_state ), GFP_KERNEL );
794
+ if (!dst -> refs )
795
+ return - ENOMEM ;
796
+
797
+ dst -> acquired_refs = src -> acquired_refs ;
798
+ return 0 ;
799
+ }
800
+
801
+ static int copy_stack_state (struct bpf_func_state * dst , const struct bpf_func_state * src )
802
+ {
803
+ size_t n = src -> allocated_stack / BPF_REG_SIZE ;
804
+
805
+ dst -> stack = copy_array (dst -> stack , src -> stack , n , sizeof (struct bpf_stack_state ),
806
+ GFP_KERNEL );
807
+ if (!dst -> stack )
808
+ return - ENOMEM ;
809
+
810
+ dst -> allocated_stack = src -> allocated_stack ;
811
+ return 0 ;
812
+ }
813
+
814
+ static int resize_reference_state (struct bpf_func_state * state , size_t n )
815
+ {
816
+ state -> refs = realloc_array (state -> refs , state -> acquired_refs , n ,
817
+ sizeof (struct bpf_reference_state ));
818
+ if (!state -> refs )
819
+ return - ENOMEM ;
820
+
821
+ state -> acquired_refs = n ;
822
+ return 0 ;
823
+ }
824
+
825
+ static int grow_stack_state (struct bpf_func_state * state , int size )
826
+ {
827
+ size_t old_n = state -> allocated_stack / BPF_REG_SIZE , n = size / BPF_REG_SIZE ;
828
+
829
+ if (old_n >= n )
830
+ return 0 ;
831
+
832
+ state -> stack = realloc_array (state -> stack , old_n , n , sizeof (struct bpf_stack_state ));
833
+ if (!state -> stack )
834
+ return - ENOMEM ;
835
+
836
+ state -> allocated_stack = size ;
837
+ return 0 ;
815
838
}
816
839
817
840
/* Acquire a pointer id from the env and update the state->refs to include
@@ -825,7 +848,7 @@ static int acquire_reference_state(struct bpf_verifier_env *env, int insn_idx)
825
848
int new_ofs = state -> acquired_refs ;
826
849
int id , err ;
827
850
828
- err = realloc_reference_state (state , state -> acquired_refs + 1 , true );
851
+ err = resize_reference_state (state , state -> acquired_refs + 1 );
829
852
if (err )
830
853
return err ;
831
854
id = ++ env -> id_gen ;
@@ -854,18 +877,6 @@ static int release_reference_state(struct bpf_func_state *state, int ptr_id)
854
877
return - EINVAL ;
855
878
}
856
879
857
- static int transfer_reference_state (struct bpf_func_state * dst ,
858
- struct bpf_func_state * src )
859
- {
860
- int err = realloc_reference_state (dst , src -> acquired_refs , false);
861
- if (err )
862
- return err ;
863
- err = copy_reference_state (dst , src );
864
- if (err )
865
- return err ;
866
- return 0 ;
867
- }
868
-
869
880
static void free_func_state (struct bpf_func_state * state )
870
881
{
871
882
if (!state )
@@ -904,10 +915,6 @@ static int copy_func_state(struct bpf_func_state *dst,
904
915
{
905
916
int err ;
906
917
907
- err = realloc_func_state (dst , src -> allocated_stack , src -> acquired_refs ,
908
- false);
909
- if (err )
910
- return err ;
911
918
memcpy (dst , src , offsetof(struct bpf_func_state , acquired_refs ));
912
919
err = copy_reference_state (dst , src );
913
920
if (err )
@@ -2590,8 +2597,7 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
2590
2597
u32 dst_reg = env -> prog -> insnsi [insn_idx ].dst_reg ;
2591
2598
struct bpf_reg_state * reg = NULL ;
2592
2599
2593
- err = realloc_func_state (state , round_up (slot + 1 , BPF_REG_SIZE ),
2594
- state -> acquired_refs , true);
2600
+ err = grow_stack_state (state , round_up (slot + 1 , BPF_REG_SIZE ));
2595
2601
if (err )
2596
2602
return err ;
2597
2603
/* caller checked that off % size == 0 and -MAX_BPF_STACK <= off < 0,
@@ -2753,8 +2759,7 @@ static int check_stack_write_var_off(struct bpf_verifier_env *env,
2753
2759
if (value_reg && register_is_null (value_reg ))
2754
2760
writing_zero = true;
2755
2761
2756
- err = realloc_func_state (state , round_up (- min_off , BPF_REG_SIZE ),
2757
- state -> acquired_refs , true);
2762
+ err = grow_stack_state (state , round_up (- min_off , BPF_REG_SIZE ));
2758
2763
if (err )
2759
2764
return err ;
2760
2765
@@ -5629,7 +5634,7 @@ static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn
5629
5634
subprog /* subprog number within this prog */ );
5630
5635
5631
5636
/* Transfer references to the callee */
5632
- err = transfer_reference_state (callee , caller );
5637
+ err = copy_reference_state (callee , caller );
5633
5638
if (err )
5634
5639
return err ;
5635
5640
@@ -5780,7 +5785,7 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
5780
5785
}
5781
5786
5782
5787
/* Transfer references to the caller */
5783
- err = transfer_reference_state (caller , callee );
5788
+ err = copy_reference_state (caller , callee );
5784
5789
if (err )
5785
5790
return err ;
5786
5791
0 commit comments