aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-17 10:04:56 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-17 10:04:56 -0500
commit04a1e62c2cec820501f93526ad1e46073b802dc4 (patch)
treec997e71d095d521f945daacc5b1e6b0e767639dc
parent718deb6b61e34c200c1f2b706176d9aac334cb2d (diff)
x86/ptrace: make genregs[32]_get/set more robust
The loop condition is fragile: we compare an unsigned value to zero, and then decrement it by something larger than one in the loop. All the callers should be passing in appropriately aligned buffer lengths, but it's better to just not rely on it, and have some appropriate defensive loop limits. Acked-by: Roland McGrath <roland@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/x86/kernel/ptrace.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 2779321046bd..017d937639fe 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -509,14 +509,14 @@ static int genregs_get(struct task_struct *target,
509{ 509{
510 if (kbuf) { 510 if (kbuf) {
511 unsigned long *k = kbuf; 511 unsigned long *k = kbuf;
512 while (count > 0) { 512 while (count >= sizeof(*k)) {
513 *k++ = getreg(target, pos); 513 *k++ = getreg(target, pos);
514 count -= sizeof(*k); 514 count -= sizeof(*k);
515 pos += sizeof(*k); 515 pos += sizeof(*k);
516 } 516 }
517 } else { 517 } else {
518 unsigned long __user *u = ubuf; 518 unsigned long __user *u = ubuf;
519 while (count > 0) { 519 while (count >= sizeof(*u)) {
520 if (__put_user(getreg(target, pos), u++)) 520 if (__put_user(getreg(target, pos), u++))
521 return -EFAULT; 521 return -EFAULT;
522 count -= sizeof(*u); 522 count -= sizeof(*u);
@@ -535,14 +535,14 @@ static int genregs_set(struct task_struct *target,
535 int ret = 0; 535 int ret = 0;
536 if (kbuf) { 536 if (kbuf) {
537 const unsigned long *k = kbuf; 537 const unsigned long *k = kbuf;
538 while (count > 0 && !ret) { 538 while (count >= sizeof(*k) && !ret) {
539 ret = putreg(target, pos, *k++); 539 ret = putreg(target, pos, *k++);
540 count -= sizeof(*k); 540 count -= sizeof(*k);
541 pos += sizeof(*k); 541 pos += sizeof(*k);
542 } 542 }
543 } else { 543 } else {
544 const unsigned long __user *u = ubuf; 544 const unsigned long __user *u = ubuf;
545 while (count > 0 && !ret) { 545 while (count >= sizeof(*u) && !ret) {
546 unsigned long word; 546 unsigned long word;
547 ret = __get_user(word, u++); 547 ret = __get_user(word, u++);
548 if (ret) 548 if (ret)
@@ -1458,14 +1458,14 @@ static int genregs32_get(struct task_struct *target,
1458{ 1458{
1459 if (kbuf) { 1459 if (kbuf) {
1460 compat_ulong_t *k = kbuf; 1460 compat_ulong_t *k = kbuf;
1461 while (count > 0) { 1461 while (count >= sizeof(*k)) {
1462 getreg32(target, pos, k++); 1462 getreg32(target, pos, k++);
1463 count -= sizeof(*k); 1463 count -= sizeof(*k);
1464 pos += sizeof(*k); 1464 pos += sizeof(*k);
1465 } 1465 }
1466 } else { 1466 } else {
1467 compat_ulong_t __user *u = ubuf; 1467 compat_ulong_t __user *u = ubuf;
1468 while (count > 0) { 1468 while (count >= sizeof(*u)) {
1469 compat_ulong_t word; 1469 compat_ulong_t word;
1470 getreg32(target, pos, &word); 1470 getreg32(target, pos, &word);
1471 if (__put_user(word, u++)) 1471 if (__put_user(word, u++))
@@ -1486,14 +1486,14 @@ static int genregs32_set(struct task_struct *target,
1486 int ret = 0; 1486 int ret = 0;
1487 if (kbuf) { 1487 if (kbuf) {
1488 const compat_ulong_t *k = kbuf; 1488 const compat_ulong_t *k = kbuf;
1489 while (count > 0 && !ret) { 1489 while (count >= sizeof(*k) && !ret) {
1490 ret = putreg32(target, pos, *k++); 1490 ret = putreg32(target, pos, *k++);
1491 count -= sizeof(*k); 1491 count -= sizeof(*k);
1492 pos += sizeof(*k); 1492 pos += sizeof(*k);
1493 } 1493 }
1494 } else { 1494 } else {
1495 const compat_ulong_t __user *u = ubuf; 1495 const compat_ulong_t __user *u = ubuf;
1496 while (count > 0 && !ret) { 1496 while (count >= sizeof(*u) && !ret) {
1497 compat_ulong_t word; 1497 compat_ulong_t word;
1498 ret = __get_user(word, u++); 1498 ret = __get_user(word, u++);
1499 if (ret) 1499 if (ret)