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