@@ -20,7 +20,7 @@ struct bpil_array_desc {
20
20
*/
21
21
};
22
22
23
- static struct bpil_array_desc bpil_array_desc [] = {
23
+ static const struct bpil_array_desc bpil_array_desc [] = {
24
24
[PERF_BPIL_JITED_INSNS ] = {
25
25
offsetof(struct bpf_prog_info , jited_prog_insns ),
26
26
offsetof(struct bpf_prog_info , jited_prog_len ),
@@ -115,7 +115,7 @@ get_bpf_prog_info_linear(int fd, __u64 arrays)
115
115
__u32 info_len = sizeof (info );
116
116
__u32 data_len = 0 ;
117
117
int i , err ;
118
- void * ptr ;
118
+ __u8 * ptr ;
119
119
120
120
if (arrays >> PERF_BPIL_LAST_ARRAY )
121
121
return ERR_PTR (- EINVAL );
@@ -126,15 +126,15 @@ get_bpf_prog_info_linear(int fd, __u64 arrays)
126
126
pr_debug ("can't get prog info: %s" , strerror (errno ));
127
127
return ERR_PTR (- EFAULT );
128
128
}
129
+ if (info .type >= __MAX_BPF_PROG_TYPE )
130
+ pr_debug ("%s:%d: unexpected program type %u\n" , __func__ , __LINE__ , info .type );
129
131
130
132
/* step 2: calculate total size of all arrays */
131
133
for (i = PERF_BPIL_FIRST_ARRAY ; i < PERF_BPIL_LAST_ARRAY ; ++ i ) {
134
+ const struct bpil_array_desc * desc = & bpil_array_desc [i ];
132
135
bool include_array = (arrays & (1UL << i )) > 0 ;
133
- struct bpil_array_desc * desc ;
134
136
__u32 count , size ;
135
137
136
- desc = bpil_array_desc + i ;
137
-
138
138
/* kernel is too old to support this field */
139
139
if (info_len < desc -> array_offset + sizeof (__u32 ) ||
140
140
info_len < desc -> count_offset + sizeof (__u32 ) ||
@@ -163,19 +163,20 @@ get_bpf_prog_info_linear(int fd, __u64 arrays)
163
163
ptr = info_linear -> data ;
164
164
165
165
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 ] ;
167
167
__u32 count , size ;
168
168
169
169
if ((arrays & (1UL << i )) == 0 )
170
170
continue ;
171
171
172
- desc = bpil_array_desc + i ;
173
172
count = bpf_prog_info_read_offset_u32 (& info , desc -> count_offset );
174
173
size = bpf_prog_info_read_offset_u32 (& info , desc -> size_offset );
175
174
bpf_prog_info_set_offset_u32 (& info_linear -> info ,
176
175
desc -> count_offset , count );
177
176
bpf_prog_info_set_offset_u32 (& info_linear -> info ,
178
177
desc -> size_offset , size );
178
+ assert (ptr >= info_linear -> data );
179
+ assert (ptr < & info_linear -> data [data_len ]);
179
180
bpf_prog_info_set_offset_u64 (& info_linear -> info ,
180
181
desc -> array_offset ,
181
182
ptr_to_u64 (ptr ));
@@ -189,27 +190,45 @@ get_bpf_prog_info_linear(int fd, __u64 arrays)
189
190
free (info_linear );
190
191
return ERR_PTR (- EFAULT );
191
192
}
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
+ }
192
197
193
198
/* step 6: verify the data */
199
+ ptr = info_linear -> data ;
194
200
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 ;
197
204
198
205
if ((arrays & (1UL << i )) == 0 )
199
206
continue ;
200
207
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 ,
204
210
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
+ }
207
216
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 ,
210
219
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 ));
213
232
}
214
233
215
234
/* step 7: update info_len and data_len */
@@ -224,13 +243,12 @@ void bpil_addr_to_offs(struct perf_bpil *info_linear)
224
243
int i ;
225
244
226
245
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 ] ;
228
247
__u64 addr , offs ;
229
248
230
249
if ((info_linear -> arrays & (1UL << i )) == 0 )
231
250
continue ;
232
251
233
- desc = bpil_array_desc + i ;
234
252
addr = bpf_prog_info_read_offset_u64 (& info_linear -> info ,
235
253
desc -> array_offset );
236
254
offs = addr - ptr_to_u64 (info_linear -> data );
@@ -244,13 +262,12 @@ void bpil_offs_to_addr(struct perf_bpil *info_linear)
244
262
int i ;
245
263
246
264
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 ] ;
248
266
__u64 addr , offs ;
249
267
250
268
if ((info_linear -> arrays & (1UL << i )) == 0 )
251
269
continue ;
252
270
253
- desc = bpil_array_desc + i ;
254
271
offs = bpf_prog_info_read_offset_u64 (& info_linear -> info ,
255
272
desc -> array_offset );
256
273
addr = offs + ptr_to_u64 (info_linear -> data );
0 commit comments