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>

+8 -8
+8 -8
arch/x86/kernel/ptrace.c
··· 509 { 510 if (kbuf) { 511 unsigned long *k = kbuf; 512 - while (count > 0) { 513 *k++ = getreg(target, pos); 514 count -= sizeof(*k); 515 pos += sizeof(*k); 516 } 517 } else { 518 unsigned long __user *u = ubuf; 519 - while (count > 0) { 520 if (__put_user(getreg(target, pos), u++)) 521 return -EFAULT; 522 count -= sizeof(*u); ··· 535 int ret = 0; 536 if (kbuf) { 537 const unsigned long *k = kbuf; 538 - while (count > 0 && !ret) { 539 ret = putreg(target, pos, *k++); 540 count -= sizeof(*k); 541 pos += sizeof(*k); 542 } 543 } else { 544 const unsigned long __user *u = ubuf; 545 - while (count > 0 && !ret) { 546 unsigned long word; 547 ret = __get_user(word, u++); 548 if (ret) ··· 1458 { 1459 if (kbuf) { 1460 compat_ulong_t *k = kbuf; 1461 - while (count > 0) { 1462 getreg32(target, pos, k++); 1463 count -= sizeof(*k); 1464 pos += sizeof(*k); 1465 } 1466 } else { 1467 compat_ulong_t __user *u = ubuf; 1468 - while (count > 0) { 1469 compat_ulong_t word; 1470 getreg32(target, pos, &word); 1471 if (__put_user(word, u++)) ··· 1486 int ret = 0; 1487 if (kbuf) { 1488 const compat_ulong_t *k = kbuf; 1489 - while (count > 0 && !ret) { 1490 ret = putreg32(target, pos, *k++); 1491 count -= sizeof(*k); 1492 pos += sizeof(*k); 1493 } 1494 } else { 1495 const compat_ulong_t __user *u = ubuf; 1496 - while (count > 0 && !ret) { 1497 compat_ulong_t word; 1498 ret = __get_user(word, u++); 1499 if (ret)
··· 509 { 510 if (kbuf) { 511 unsigned long *k = kbuf; 512 + while (count >= sizeof(*k)) { 513 *k++ = getreg(target, pos); 514 count -= sizeof(*k); 515 pos += sizeof(*k); 516 } 517 } else { 518 unsigned long __user *u = ubuf; 519 + while (count >= sizeof(*u)) { 520 if (__put_user(getreg(target, pos), u++)) 521 return -EFAULT; 522 count -= sizeof(*u); ··· 535 int ret = 0; 536 if (kbuf) { 537 const unsigned long *k = kbuf; 538 + while (count >= sizeof(*k) && !ret) { 539 ret = putreg(target, pos, *k++); 540 count -= sizeof(*k); 541 pos += sizeof(*k); 542 } 543 } else { 544 const unsigned long __user *u = ubuf; 545 + while (count >= sizeof(*u) && !ret) { 546 unsigned long word; 547 ret = __get_user(word, u++); 548 if (ret) ··· 1458 { 1459 if (kbuf) { 1460 compat_ulong_t *k = kbuf; 1461 + while (count >= sizeof(*k)) { 1462 getreg32(target, pos, k++); 1463 count -= sizeof(*k); 1464 pos += sizeof(*k); 1465 } 1466 } else { 1467 compat_ulong_t __user *u = ubuf; 1468 + while (count >= sizeof(*u)) { 1469 compat_ulong_t word; 1470 getreg32(target, pos, &word); 1471 if (__put_user(word, u++)) ··· 1486 int ret = 0; 1487 if (kbuf) { 1488 const compat_ulong_t *k = kbuf; 1489 + while (count >= sizeof(*k) && !ret) { 1490 ret = putreg32(target, pos, *k++); 1491 count -= sizeof(*k); 1492 pos += sizeof(*k); 1493 } 1494 } else { 1495 const compat_ulong_t __user *u = ubuf; 1496 + while (count >= sizeof(*u) && !ret) { 1497 compat_ulong_t word; 1498 ret = __get_user(word, u++); 1499 if (ret)