diff options
author | Bryan O'Sullivan <bos@pathscale.com> | 2007-03-15 17:45:10 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-04-18 23:20:59 -0400 |
commit | 490462c2686df6e35c21d1efe935e0b4a3bddb39 (patch) | |
tree | 455262ace80556289cf5ff10247246adcbe0b9d0 /drivers/infiniband/hw/ipath/ipath_diag.c | |
parent | f5408ac7ccec0a7edd2b6add0da82735375a37a0 (diff) |
IB/ipath: Prevent random program use of diags interface
To prevent random utility reads and writes of the diag interface to the
chip, we first require a handshake of reading from offset 0 and writing
to offset 0 before any other reads or writes can be done through the
diags device. Otherwise chip errors can be triggered.
Signed-off-by: Dave Olson <dave.olson@qlogic.com>
Signed-off-by: Bryan O'Sullivan <bryan.osullivan@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_diag.c')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_diag.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_diag.c b/drivers/infiniband/hw/ipath/ipath_diag.c index 0f13a2182cc7..63e8368b0e95 100644 --- a/drivers/infiniband/hw/ipath/ipath_diag.c +++ b/drivers/infiniband/hw/ipath/ipath_diag.c | |||
@@ -296,7 +296,7 @@ static int ipath_diag_open(struct inode *in, struct file *fp) | |||
296 | } | 296 | } |
297 | 297 | ||
298 | fp->private_data = dd; | 298 | fp->private_data = dd; |
299 | ipath_diag_inuse = 1; | 299 | ipath_diag_inuse = -2; |
300 | diag_set_link = 0; | 300 | diag_set_link = 0; |
301 | ret = 0; | 301 | ret = 0; |
302 | 302 | ||
@@ -461,6 +461,8 @@ static ssize_t ipath_diag_read(struct file *fp, char __user *data, | |||
461 | else if ((count % 4) || (*off % 4)) | 461 | else if ((count % 4) || (*off % 4)) |
462 | /* address or length is not 32-bit aligned, hence invalid */ | 462 | /* address or length is not 32-bit aligned, hence invalid */ |
463 | ret = -EINVAL; | 463 | ret = -EINVAL; |
464 | else if (ipath_diag_inuse < 1 && (*off || count != 8)) | ||
465 | ret = -EINVAL; /* prevent cat /dev/ipath_diag* */ | ||
464 | else if ((count % 8) || (*off % 8)) | 466 | else if ((count % 8) || (*off % 8)) |
465 | /* address or length not 64-bit aligned; do 32-bit reads */ | 467 | /* address or length not 64-bit aligned; do 32-bit reads */ |
466 | ret = ipath_read_umem32(dd, data, kreg_base + *off, count); | 468 | ret = ipath_read_umem32(dd, data, kreg_base + *off, count); |
@@ -470,6 +472,8 @@ static ssize_t ipath_diag_read(struct file *fp, char __user *data, | |||
470 | if (ret >= 0) { | 472 | if (ret >= 0) { |
471 | *off += count; | 473 | *off += count; |
472 | ret = count; | 474 | ret = count; |
475 | if (ipath_diag_inuse == -2) | ||
476 | ipath_diag_inuse++; | ||
473 | } | 477 | } |
474 | 478 | ||
475 | return ret; | 479 | return ret; |
@@ -489,6 +493,9 @@ static ssize_t ipath_diag_write(struct file *fp, const char __user *data, | |||
489 | else if ((count % 4) || (*off % 4)) | 493 | else if ((count % 4) || (*off % 4)) |
490 | /* address or length is not 32-bit aligned, hence invalid */ | 494 | /* address or length is not 32-bit aligned, hence invalid */ |
491 | ret = -EINVAL; | 495 | ret = -EINVAL; |
496 | else if ((ipath_diag_inuse == -1 && (*off || count != 8)) || | ||
497 | ipath_diag_inuse == -2) /* read qw off 0, write qw off 0 */ | ||
498 | ret = -EINVAL; /* before any other write allowed */ | ||
492 | else if ((count % 8) || (*off % 8)) | 499 | else if ((count % 8) || (*off % 8)) |
493 | /* address or length not 64-bit aligned; do 32-bit writes */ | 500 | /* address or length not 64-bit aligned; do 32-bit writes */ |
494 | ret = ipath_write_umem32(dd, kreg_base + *off, data, count); | 501 | ret = ipath_write_umem32(dd, kreg_base + *off, data, count); |
@@ -498,6 +505,8 @@ static ssize_t ipath_diag_write(struct file *fp, const char __user *data, | |||
498 | if (ret >= 0) { | 505 | if (ret >= 0) { |
499 | *off += count; | 506 | *off += count; |
500 | ret = count; | 507 | ret = count; |
508 | if (ipath_diag_inuse == -1) | ||
509 | ipath_diag_inuse = 1; /* all read/write OK now */ | ||
501 | } | 510 | } |
502 | 511 | ||
503 | return ret; | 512 | return ret; |