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
@@ -174,7 +176,7 @@ static int iwl_alloc_fw_paging_mem(struct iwl_fw_runtime *fwrt,
174
176
static int iwl_fill_paging_mem (struct iwl_fw_runtime * fwrt ,
175
177
const struct fw_img * image )
176
178
{
177
- int sec_idx , idx ;
179
+ int sec_idx , idx , ret ;
178
180
u32 offset = 0 ;
179
181
180
182
/*
@@ -201,17 +203,23 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,
201
203
*/
202
204
if (sec_idx >= image -> num_sec - 1 ) {
203
205
IWL_ERR (fwrt , "Paging: Missing CSS and/or paging sections\n" );
204
- iwl_free_fw_paging ( fwrt ) ;
205
- return - EINVAL ;
206
+ ret = - EINVAL ;
207
+ goto err ;
206
208
}
207
209
208
210
/* copy the CSS block to the dram */
209
211
IWL_DEBUG_FW (fwrt , "Paging: load paging CSS to FW, sec = %d\n" ,
210
212
sec_idx );
211
213
214
+ if (image -> sec [sec_idx ].len > fwrt -> fw_paging_db [0 ].fw_paging_size ) {
215
+ IWL_ERR (fwrt , "CSS block is larger than paging size\n" );
216
+ ret = - EINVAL ;
217
+ goto err ;
218
+ }
219
+
212
220
memcpy (page_address (fwrt -> fw_paging_db [0 ].fw_paging_block ),
213
221
image -> sec [sec_idx ].data ,
214
- fwrt -> fw_paging_db [ 0 ]. fw_paging_size );
222
+ image -> sec [ sec_idx ]. len );
215
223
dma_sync_single_for_device (fwrt -> trans -> dev ,
216
224
fwrt -> fw_paging_db [0 ].fw_paging_phys ,
217
225
fwrt -> fw_paging_db [0 ].fw_paging_size ,
@@ -232,6 +240,14 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,
232
240
for (idx = 1 ; idx < fwrt -> num_of_paging_blk ; idx ++ ) {
233
241
struct iwl_fw_paging * block = & fwrt -> fw_paging_db [idx ];
234
242
243
+ if (block -> fw_paging_size > image -> sec [sec_idx ].len - offset ) {
244
+ IWL_ERR (fwrt ,
245
+ "Paging: paging size is larger than remaining data in block %d\n" ,
246
+ idx );
247
+ ret = - EINVAL ;
248
+ goto err ;
249
+ }
250
+
235
251
memcpy (page_address (block -> fw_paging_block ),
236
252
image -> sec [sec_idx ].data + offset ,
237
253
block -> fw_paging_size );
@@ -242,19 +258,32 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,
242
258
243
259
IWL_DEBUG_FW (fwrt ,
244
260
"Paging: copied %d paging bytes to block %d\n" ,
245
- fwrt -> fw_paging_db [idx ].fw_paging_size ,
246
- idx );
261
+ block -> fw_paging_size , idx );
262
+
263
+ offset += block -> fw_paging_size ;
247
264
248
- offset += fwrt -> fw_paging_db [idx ].fw_paging_size ;
265
+ if (offset > image -> sec [sec_idx ].len ) {
266
+ IWL_ERR (fwrt ,
267
+ "Paging: offset goes over section size\n" );
268
+ ret = - EINVAL ;
269
+ goto err ;
270
+ }
249
271
}
250
272
251
273
/* copy the last paging block */
252
274
if (fwrt -> num_of_pages_in_last_blk > 0 ) {
253
275
struct iwl_fw_paging * block = & fwrt -> fw_paging_db [idx ];
254
276
277
+ if (image -> sec [sec_idx ].len - offset > block -> fw_paging_size ) {
278
+ IWL_ERR (fwrt ,
279
+ "Paging: last block is larger than paging size\n" );
280
+ ret = - EINVAL ;
281
+ goto err ;
282
+ }
283
+
255
284
memcpy (page_address (block -> fw_paging_block ),
256
285
image -> sec [sec_idx ].data + offset ,
257
- FW_PAGING_SIZE * fwrt -> num_of_pages_in_last_blk );
286
+ image -> sec [ sec_idx ]. len - offset );
258
287
dma_sync_single_for_device (fwrt -> trans -> dev ,
259
288
block -> fw_paging_phys ,
260
289
block -> fw_paging_size ,
@@ -266,6 +295,10 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,
266
295
}
267
296
268
297
return 0 ;
298
+
299
+ err :
300
+ iwl_free_fw_paging (fwrt );
301
+ return ret ;
269
302
}
270
303
271
304
static int iwl_save_fw_paging (struct iwl_fw_runtime * fwrt ,
0 commit comments