@@ -20,7 +20,7 @@ struct bpil_array_desc {
2020 */
2121};
2222
23- static struct bpil_array_desc bpil_array_desc [] = {
23+ static const struct bpil_array_desc bpil_array_desc [] = {
2424 [PERF_BPIL_JITED_INSNS ] = {
2525 offsetof(struct bpf_prog_info , jited_prog_insns ),
2626 offsetof(struct bpf_prog_info , jited_prog_len ),
@@ -115,7 +115,7 @@ get_bpf_prog_info_linear(int fd, __u64 arrays)
115115 __u32 info_len = sizeof (info );
116116 __u32 data_len = 0 ;
117117 int i , err ;
118- void * ptr ;
118+ __u8 * ptr ;
119119
120120 if (arrays >> PERF_BPIL_LAST_ARRAY )
121121 return ERR_PTR (- EINVAL );
@@ -126,15 +126,15 @@ get_bpf_prog_info_linear(int fd, __u64 arrays)
126126 pr_debug ("can't get prog info: %s" , strerror (errno ));
127127 return ERR_PTR (- EFAULT );
128128 }
129+ if (info .type >= __MAX_BPF_PROG_TYPE )
130+ pr_debug ("%s:%d: unexpected program type %u\n" , __func__ , __LINE__ , info .type );
129131
130132 /* step 2: calculate total size of all arrays */
131133 for (i = PERF_BPIL_FIRST_ARRAY ; i < PERF_BPIL_LAST_ARRAY ; ++ i ) {
134+ const struct bpil_array_desc * desc = & bpil_array_desc [i ];
132135 bool include_array = (arrays & (1UL << i )) > 0 ;
133- struct bpil_array_desc * desc ;
134136 __u32 count , size ;
135137
136- desc = bpil_array_desc + i ;
137-
138138 /* kernel is too old to support this field */
139139 if (info_len < desc -> array_offset + sizeof (__u32 ) ||
140140 info_len < desc -> count_offset + sizeof (__u32 ) ||
@@ -163,19 +163,20 @@ get_bpf_prog_info_linear(int fd, __u64 arrays)
163163 ptr = info_linear -> data ;
164164
165165 for (i = PERF_BPIL_FIRST_ARRAY ; i < PERF_BPIL_LAST_ARRAY ; ++ i ) {
166- struct bpil_array_desc * desc ;
166+ const struct bpil_array_desc * desc = & bpil_array_desc [ i ] ;
167167 __u32 count , size ;
168168
169169 if ((arrays & (1UL << i )) == 0 )
170170 continue ;
171171
172- desc = bpil_array_desc + i ;
173172 count = bpf_prog_info_read_offset_u32 (& info , desc -> count_offset );
174173 size = bpf_prog_info_read_offset_u32 (& info , desc -> size_offset );
175174 bpf_prog_info_set_offset_u32 (& info_linear -> info ,
176175 desc -> count_offset , count );
177176 bpf_prog_info_set_offset_u32 (& info_linear -> info ,
178177 desc -> size_offset , size );
178+ assert (ptr >= info_linear -> data );
179+ assert (ptr < & info_linear -> data [data_len ]);
179180 bpf_prog_info_set_offset_u64 (& info_linear -> info ,
180181 desc -> array_offset ,
181182 ptr_to_u64 (ptr ));
@@ -189,27 +190,45 @@ get_bpf_prog_info_linear(int fd, __u64 arrays)
189190 free (info_linear );
190191 return ERR_PTR (- EFAULT );
191192 }
193+ if (info_linear -> info .type >= __MAX_BPF_PROG_TYPE ) {
194+ pr_debug ("%s:%d: unexpected program type %u\n" ,
195+ __func__ , __LINE__ , info_linear -> info .type );
196+ }
192197
193198 /* step 6: verify the data */
199+ ptr = info_linear -> data ;
194200 for (i = PERF_BPIL_FIRST_ARRAY ; i < PERF_BPIL_LAST_ARRAY ; ++ i ) {
195- struct bpil_array_desc * desc ;
196- __u32 v1 , v2 ;
201+ const struct bpil_array_desc * desc = & bpil_array_desc [i ];
202+ __u32 count1 , count2 , size1 , size2 ;
203+ __u64 ptr2 ;
197204
198205 if ((arrays & (1UL << i )) == 0 )
199206 continue ;
200207
201- desc = bpil_array_desc + i ;
202- v1 = bpf_prog_info_read_offset_u32 (& info , desc -> count_offset );
203- v2 = bpf_prog_info_read_offset_u32 (& info_linear -> info ,
208+ count1 = bpf_prog_info_read_offset_u32 (& info , desc -> count_offset );
209+ count2 = bpf_prog_info_read_offset_u32 (& info_linear -> info ,
204210 desc -> count_offset );
205- if (v1 != v2 )
206- pr_warning ("%s: mismatch in element count\n" , __func__ );
211+ if (count1 != count2 ) {
212+ pr_warning ("%s: mismatch in element count %u vs %u\n" , __func__ , count1 , count2 );
213+ free (info_linear );
214+ return ERR_PTR (- ERANGE );
215+ }
207216
208- v1 = bpf_prog_info_read_offset_u32 (& info , desc -> size_offset );
209- v2 = bpf_prog_info_read_offset_u32 (& info_linear -> info ,
217+ size1 = bpf_prog_info_read_offset_u32 (& info , desc -> size_offset );
218+ size2 = bpf_prog_info_read_offset_u32 (& info_linear -> info ,
210219 desc -> size_offset );
211- if (v1 != v2 )
212- pr_warning ("%s: mismatch in rec size\n" , __func__ );
220+ if (size1 != size2 ) {
221+ pr_warning ("%s: mismatch in rec size %u vs %u\n" , __func__ , size1 , size2 );
222+ free (info_linear );
223+ return ERR_PTR (- ERANGE );
224+ }
225+ ptr2 = bpf_prog_info_read_offset_u64 (& info_linear -> info , desc -> array_offset );
226+ if (ptr_to_u64 (ptr ) != ptr2 ) {
227+ pr_warning ("%s: mismatch in array %p vs %llx\n" , __func__ , ptr , ptr2 );
228+ free (info_linear );
229+ return ERR_PTR (- ERANGE );
230+ }
231+ ptr += roundup (count1 * size1 , sizeof (__u64 ));
213232 }
214233
215234 /* step 7: update info_len and data_len */
@@ -224,13 +243,12 @@ void bpil_addr_to_offs(struct perf_bpil *info_linear)
224243 int i ;
225244
226245 for (i = PERF_BPIL_FIRST_ARRAY ; i < PERF_BPIL_LAST_ARRAY ; ++ i ) {
227- struct bpil_array_desc * desc ;
246+ const struct bpil_array_desc * desc = & bpil_array_desc [ i ] ;
228247 __u64 addr , offs ;
229248
230249 if ((info_linear -> arrays & (1UL << i )) == 0 )
231250 continue ;
232251
233- desc = bpil_array_desc + i ;
234252 addr = bpf_prog_info_read_offset_u64 (& info_linear -> info ,
235253 desc -> array_offset );
236254 offs = addr - ptr_to_u64 (info_linear -> data );
@@ -244,13 +262,12 @@ void bpil_offs_to_addr(struct perf_bpil *info_linear)
244262 int i ;
245263
246264 for (i = PERF_BPIL_FIRST_ARRAY ; i < PERF_BPIL_LAST_ARRAY ; ++ i ) {
247- struct bpil_array_desc * desc ;
265+ const struct bpil_array_desc * desc = & bpil_array_desc [ i ] ;
248266 __u64 addr , offs ;
249267
250268 if ((info_linear -> arrays & (1UL << i )) == 0 )
251269 continue ;
252270
253- desc = bpil_array_desc + i ;
254271 offs = bpf_prog_info_read_offset_u64 (& info_linear -> info ,
255272 desc -> array_offset );
256273 addr = offs + ptr_to_u64 (info_linear -> data );
0 commit comments