Skip to content

Commit e84b2f2

Browse files
Jakub Kicinskidavem330
authored andcommitted
nfp: validate rtsym accesses fall within the symbol
With the accesses to rtsyms now all going via special helpers we can easily make sure the driver is not reading past the end of the symbol. Signed-off-by: Jakub Kicinski <[email protected]> Reviewed-by: Francois H. Theron <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 31e380f commit e84b2f2

File tree

1 file changed

+45
-3
lines changed

1 file changed

+45
-3
lines changed

drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
* Espen Skoglund <[email protected]>
4040
* Francois H. Theron <[email protected]>
4141
*/
42+
43+
#include <asm/unaligned.h>
4244
#include <linux/kernel.h>
4345
#include <linux/module.h>
4446
#include <linux/slab.h>
@@ -285,15 +287,23 @@ nfp_rtsym_to_dest(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
285287
int __nfp_rtsym_read(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
286288
u8 action, u8 token, u64 off, void *buf, size_t len)
287289
{
290+
u64 sym_size = nfp_rtsym_size(sym);
288291
u32 cpp_id;
289292
u64 addr;
290293
int err;
291294

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+
292302
if (sym->type == NFP_RTSYM_TYPE_ABS) {
293-
__le64 tmp = cpu_to_le64(sym->addr);
303+
u8 tmp[8];
294304

295-
len = min(len, sizeof(tmp));
296-
memcpy(buf, &tmp, len);
305+
put_unaligned_le64(sym->addr, tmp);
306+
memcpy(buf, &tmp[off], len);
297307

298308
return len;
299309
}
@@ -318,6 +328,12 @@ int __nfp_rtsym_readl(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
318328
u64 addr;
319329
int err;
320330

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+
321337
err = nfp_rtsym_to_dest(cpp, sym, action, token, off, &cpp_id, &addr);
322338
if (err)
323339
return err;
@@ -338,6 +354,12 @@ int __nfp_rtsym_readq(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
338354
u64 addr;
339355
int err;
340356

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+
341363
if (sym->type == NFP_RTSYM_TYPE_ABS) {
342364
*value = sym->addr;
343365
return 0;
@@ -359,10 +381,18 @@ int nfp_rtsym_readq(struct nfp_cpp *cpp, const struct nfp_rtsym *sym, u64 off,
359381
int __nfp_rtsym_write(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
360382
u8 action, u8 token, u64 off, void *buf, size_t len)
361383
{
384+
u64 sym_size = nfp_rtsym_size(sym);
362385
u32 cpp_id;
363386
u64 addr;
364387
int err;
365388

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+
366396
err = nfp_rtsym_to_dest(cpp, sym, action, token, off, &cpp_id, &addr);
367397
if (err)
368398
return err;
@@ -383,6 +413,12 @@ int __nfp_rtsym_writel(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
383413
u64 addr;
384414
int err;
385415

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+
386422
err = nfp_rtsym_to_dest(cpp, sym, action, token, off, &cpp_id, &addr);
387423
if (err)
388424
return err;
@@ -403,6 +439,12 @@ int __nfp_rtsym_writeq(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
403439
u64 addr;
404440
int err;
405441

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+
406448
err = nfp_rtsym_to_dest(cpp, sym, action, token, off, &cpp_id, &addr);
407449
if (err)
408450
return err;

0 commit comments

Comments
 (0)