8
8
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9
9
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10
10
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11
+ * Copyright(c) 2018 Intel Corporation
11
12
*
12
13
* This program is free software; you can redistribute it and/or modify
13
14
* it under the terms of version 2 of the GNU General Public License as
30
31
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
31
32
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
32
33
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
34
+ * Copyright(c) 2018 Intel Corporation
33
35
* All rights reserved.
34
36
*
35
37
* Redistribution and use in source and binary forms, with or without
@@ -163,7 +165,7 @@ static int iwl_alloc_fw_paging_mem(struct iwl_fw_runtime *fwrt,
163
165
static int iwl_fill_paging_mem (struct iwl_fw_runtime * fwrt ,
164
166
const struct fw_img * image )
165
167
{
166
- int sec_idx , idx ;
168
+ int sec_idx , idx , ret ;
167
169
u32 offset = 0 ;
168
170
169
171
/*
@@ -190,17 +192,23 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,
190
192
*/
191
193
if (sec_idx >= image -> num_sec - 1 ) {
192
194
IWL_ERR (fwrt , "Paging: Missing CSS and/or paging sections\n" );
193
- iwl_free_fw_paging ( fwrt ) ;
194
- return - EINVAL ;
195
+ ret = - EINVAL ;
196
+ goto err ;
195
197
}
196
198
197
199
/* copy the CSS block to the dram */
198
200
IWL_DEBUG_FW (fwrt , "Paging: load paging CSS to FW, sec = %d\n" ,
199
201
sec_idx );
200
202
203
+ if (image -> sec [sec_idx ].len > fwrt -> fw_paging_db [0 ].fw_paging_size ) {
204
+ IWL_ERR (fwrt , "CSS block is larger than paging size\n" );
205
+ ret = - EINVAL ;
206
+ goto err ;
207
+ }
208
+
201
209
memcpy (page_address (fwrt -> fw_paging_db [0 ].fw_paging_block ),
202
210
image -> sec [sec_idx ].data ,
203
- fwrt -> fw_paging_db [ 0 ]. fw_paging_size );
211
+ image -> sec [ sec_idx ]. len );
204
212
dma_sync_single_for_device (fwrt -> trans -> dev ,
205
213
fwrt -> fw_paging_db [0 ].fw_paging_phys ,
206
214
fwrt -> fw_paging_db [0 ].fw_paging_size ,
@@ -221,6 +229,14 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,
221
229
for (idx = 1 ; idx < fwrt -> num_of_paging_blk ; idx ++ ) {
222
230
struct iwl_fw_paging * block = & fwrt -> fw_paging_db [idx ];
223
231
232
+ if (block -> fw_paging_size > image -> sec [sec_idx ].len - offset ) {
233
+ IWL_ERR (fwrt ,
234
+ "Paging: paging size is larger than remaining data in block %d\n" ,
235
+ idx );
236
+ ret = - EINVAL ;
237
+ goto err ;
238
+ }
239
+
224
240
memcpy (page_address (block -> fw_paging_block ),
225
241
image -> sec [sec_idx ].data + offset ,
226
242
block -> fw_paging_size );
@@ -231,19 +247,32 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,
231
247
232
248
IWL_DEBUG_FW (fwrt ,
233
249
"Paging: copied %d paging bytes to block %d\n" ,
234
- fwrt -> fw_paging_db [idx ].fw_paging_size ,
235
- idx );
250
+ block -> fw_paging_size , idx );
236
251
237
- offset += fwrt -> fw_paging_db [idx ].fw_paging_size ;
252
+ offset += block -> fw_paging_size ;
253
+
254
+ if (offset > image -> sec [sec_idx ].len ) {
255
+ IWL_ERR (fwrt ,
256
+ "Paging: offset goes over section size\n" );
257
+ ret = - EINVAL ;
258
+ goto err ;
259
+ }
238
260
}
239
261
240
262
/* copy the last paging block */
241
263
if (fwrt -> num_of_pages_in_last_blk > 0 ) {
242
264
struct iwl_fw_paging * block = & fwrt -> fw_paging_db [idx ];
243
265
266
+ if (image -> sec [sec_idx ].len - offset > block -> fw_paging_size ) {
267
+ IWL_ERR (fwrt ,
268
+ "Paging: last block is larger than paging size\n" );
269
+ ret = - EINVAL ;
270
+ goto err ;
271
+ }
272
+
244
273
memcpy (page_address (block -> fw_paging_block ),
245
274
image -> sec [sec_idx ].data + offset ,
246
- FW_PAGING_SIZE * fwrt -> num_of_pages_in_last_blk );
275
+ image -> sec [ sec_idx ]. len - offset );
247
276
dma_sync_single_for_device (fwrt -> trans -> dev ,
248
277
block -> fw_paging_phys ,
249
278
block -> fw_paging_size ,
@@ -255,6 +284,10 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,
255
284
}
256
285
257
286
return 0 ;
287
+
288
+ err :
289
+ iwl_free_fw_paging (fwrt );
290
+ return ret ;
258
291
}
259
292
260
293
static int iwl_save_fw_paging (struct iwl_fw_runtime * fwrt ,
0 commit comments