39
39
* Espen Skoglund <[email protected] >
40
40
* Francois H. Theron <[email protected] >
41
41
*/
42
+
43
+ #include <asm/unaligned.h>
42
44
#include <linux/kernel.h>
43
45
#include <linux/module.h>
44
46
#include <linux/slab.h>
@@ -285,15 +287,23 @@ nfp_rtsym_to_dest(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
285
287
int __nfp_rtsym_read (struct nfp_cpp * cpp , const struct nfp_rtsym * sym ,
286
288
u8 action , u8 token , u64 off , void * buf , size_t len )
287
289
{
290
+ u64 sym_size = nfp_rtsym_size (sym );
288
291
u32 cpp_id ;
289
292
u64 addr ;
290
293
int err ;
291
294
295
+ if (off > sym_size ) {
296
+ nfp_err (cpp , "rtsym '%s': read out of bounds: off: %lld + len: %zd > size: %lld\n" ,
297
+ sym -> name , off , len , sym_size );
298
+ return - ENXIO ;
299
+ }
300
+ len = min_t (size_t , len , sym_size - off );
301
+
292
302
if (sym -> type == NFP_RTSYM_TYPE_ABS ) {
293
- __le64 tmp = cpu_to_le64 ( sym -> addr ) ;
303
+ u8 tmp [ 8 ] ;
294
304
295
- len = min ( len , sizeof ( tmp ) );
296
- memcpy (buf , & tmp , len );
305
+ put_unaligned_le64 ( sym -> addr , tmp );
306
+ memcpy (buf , & tmp [ off ] , len );
297
307
298
308
return len ;
299
309
}
@@ -318,6 +328,12 @@ int __nfp_rtsym_readl(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
318
328
u64 addr ;
319
329
int err ;
320
330
331
+ if (off + 4 > nfp_rtsym_size (sym )) {
332
+ nfp_err (cpp , "rtsym '%s': readl out of bounds: off: %lld + 4 > size: %lld\n" ,
333
+ sym -> name , off , nfp_rtsym_size (sym ));
334
+ return - ENXIO ;
335
+ }
336
+
321
337
err = nfp_rtsym_to_dest (cpp , sym , action , token , off , & cpp_id , & addr );
322
338
if (err )
323
339
return err ;
@@ -338,6 +354,12 @@ int __nfp_rtsym_readq(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
338
354
u64 addr ;
339
355
int err ;
340
356
357
+ if (off + 8 > nfp_rtsym_size (sym )) {
358
+ nfp_err (cpp , "rtsym '%s': readq out of bounds: off: %lld + 8 > size: %lld\n" ,
359
+ sym -> name , off , nfp_rtsym_size (sym ));
360
+ return - ENXIO ;
361
+ }
362
+
341
363
if (sym -> type == NFP_RTSYM_TYPE_ABS ) {
342
364
* value = sym -> addr ;
343
365
return 0 ;
@@ -359,10 +381,18 @@ int nfp_rtsym_readq(struct nfp_cpp *cpp, const struct nfp_rtsym *sym, u64 off,
359
381
int __nfp_rtsym_write (struct nfp_cpp * cpp , const struct nfp_rtsym * sym ,
360
382
u8 action , u8 token , u64 off , void * buf , size_t len )
361
383
{
384
+ u64 sym_size = nfp_rtsym_size (sym );
362
385
u32 cpp_id ;
363
386
u64 addr ;
364
387
int err ;
365
388
389
+ if (off > sym_size ) {
390
+ nfp_err (cpp , "rtsym '%s': write out of bounds: off: %lld + len: %zd > size: %lld\n" ,
391
+ sym -> name , off , len , sym_size );
392
+ return - ENXIO ;
393
+ }
394
+ len = min_t (size_t , len , sym_size - off );
395
+
366
396
err = nfp_rtsym_to_dest (cpp , sym , action , token , off , & cpp_id , & addr );
367
397
if (err )
368
398
return err ;
@@ -383,6 +413,12 @@ int __nfp_rtsym_writel(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
383
413
u64 addr ;
384
414
int err ;
385
415
416
+ if (off + 4 > nfp_rtsym_size (sym )) {
417
+ nfp_err (cpp , "rtsym '%s': writel out of bounds: off: %lld + 4 > size: %lld\n" ,
418
+ sym -> name , off , nfp_rtsym_size (sym ));
419
+ return - ENXIO ;
420
+ }
421
+
386
422
err = nfp_rtsym_to_dest (cpp , sym , action , token , off , & cpp_id , & addr );
387
423
if (err )
388
424
return err ;
@@ -403,6 +439,12 @@ int __nfp_rtsym_writeq(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
403
439
u64 addr ;
404
440
int err ;
405
441
442
+ if (off + 8 > nfp_rtsym_size (sym )) {
443
+ nfp_err (cpp , "rtsym '%s': writeq out of bounds: off: %lld + 8 > size: %lld\n" ,
444
+ sym -> name , off , nfp_rtsym_size (sym ));
445
+ return - ENXIO ;
446
+ }
447
+
406
448
err = nfp_rtsym_to_dest (cpp , sym , action , token , off , & cpp_id , & addr );
407
449
if (err )
408
450
return err ;
0 commit comments