diff options
author | Kees Cook <keescook@chromium.org> | 2013-09-11 00:40:43 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-09-17 10:39:27 -0400 |
commit | 1ea12fef83c3269eb7ba04f1d20db00c581515b2 (patch) | |
tree | 31a5bc93de8c3a49442fa5db0652e6af7c2e54fc | |
parent | e72b9da08319f6f4f86b0c93499cd522062c5e7b (diff) |
staging: dgap: fix overflows and format strings
The boot message buffer could potentially overflow the stack and the
heap. Additionally make sure format strings could not leak into printk()
calls.
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/dgap/dgap_driver.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/drivers/staging/dgap/dgap_driver.c b/drivers/staging/dgap/dgap_driver.c index 724a685753dd..40ef785a0428 100644 --- a/drivers/staging/dgap/dgap_driver.c +++ b/drivers/staging/dgap/dgap_driver.c | |||
@@ -474,7 +474,7 @@ static void dgap_cleanup_board(struct board_t *brd) | |||
474 | 474 | ||
475 | DGAP_LOCK(dgap_global_lock, flags); | 475 | DGAP_LOCK(dgap_global_lock, flags); |
476 | brd->msgbuf = NULL; | 476 | brd->msgbuf = NULL; |
477 | printk(brd->msgbuf_head); | 477 | printk("%s", brd->msgbuf_head); |
478 | kfree(brd->msgbuf_head); | 478 | kfree(brd->msgbuf_head); |
479 | brd->msgbuf_head = NULL; | 479 | brd->msgbuf_head = NULL; |
480 | DGAP_UNLOCK(dgap_global_lock, flags); | 480 | DGAP_UNLOCK(dgap_global_lock, flags); |
@@ -628,7 +628,7 @@ static int dgap_found_board(struct pci_dev *pdev, int id) | |||
628 | DPR_INIT(("dgap_scan(%d) - printing out the msgbuf\n", i)); | 628 | DPR_INIT(("dgap_scan(%d) - printing out the msgbuf\n", i)); |
629 | DGAP_LOCK(dgap_global_lock, flags); | 629 | DGAP_LOCK(dgap_global_lock, flags); |
630 | brd->msgbuf = NULL; | 630 | brd->msgbuf = NULL; |
631 | printk(brd->msgbuf_head); | 631 | printk("%s", brd->msgbuf_head); |
632 | kfree(brd->msgbuf_head); | 632 | kfree(brd->msgbuf_head); |
633 | brd->msgbuf_head = NULL; | 633 | brd->msgbuf_head = NULL; |
634 | DGAP_UNLOCK(dgap_global_lock, flags); | 634 | DGAP_UNLOCK(dgap_global_lock, flags); |
@@ -955,25 +955,28 @@ static void dgap_mbuf(struct board_t *brd, const char *fmt, ...) { | |||
955 | char buf[1024]; | 955 | char buf[1024]; |
956 | int i; | 956 | int i; |
957 | unsigned long flags; | 957 | unsigned long flags; |
958 | size_t length; | ||
958 | 959 | ||
959 | DGAP_LOCK(dgap_global_lock, flags); | 960 | DGAP_LOCK(dgap_global_lock, flags); |
960 | 961 | ||
961 | /* Format buf using fmt and arguments contained in ap. */ | 962 | /* Format buf using fmt and arguments contained in ap. */ |
962 | va_start(ap, fmt); | 963 | va_start(ap, fmt); |
963 | i = vsprintf(buf, fmt, ap); | 964 | i = vsnprintf(buf, sizeof(buf), fmt, ap); |
964 | va_end(ap); | 965 | va_end(ap); |
965 | 966 | ||
966 | DPR((buf)); | 967 | DPR((buf)); |
967 | 968 | ||
968 | if (!brd || !brd->msgbuf) { | 969 | if (!brd || !brd->msgbuf) { |
969 | printk(buf); | 970 | printk("%s", buf); |
970 | DGAP_UNLOCK(dgap_global_lock, flags); | 971 | DGAP_UNLOCK(dgap_global_lock, flags); |
971 | return; | 972 | return; |
972 | } | 973 | } |
973 | 974 | ||
974 | memcpy(brd->msgbuf, buf, strlen(buf)); | 975 | length = strlen(buf) + 1; |
975 | brd->msgbuf += strlen(buf); | 976 | if (brd->msgbuf - brd->msgbuf_head < length) |
976 | *brd->msgbuf = 0; | 977 | length = brd->msgbuf - brd->msgbuf_head; |
978 | memcpy(brd->msgbuf, buf, length); | ||
979 | brd->msgbuf += length; | ||
977 | 980 | ||
978 | DGAP_UNLOCK(dgap_global_lock, flags); | 981 | DGAP_UNLOCK(dgap_global_lock, flags); |
979 | } | 982 | } |