You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

57 lines
2.1 KiB

  1. From 26b9d22dd24c17eb118d0205bf7b02b75d435e3c Mon Sep 17 00:00:00 2001
  2. From: "Alexander E. Patrakov" <patrakov@gmail.com>
  3. Date: Thu, 5 Jun 2014 22:29:25 +0600
  4. Subject: [PATCH] rtp-recv: fix crash on empty UDP packets (CVE-2014-3970)
  5. On FIONREAD returning 0 bytes, we cannot return success, as the caller
  6. (rtpoll_work_cb in module-rtp-recv.c) would then try to
  7. pa_memblock_unref(chunk.memblock) and, because memblock is NULL, trigger
  8. an assertion.
  9. Also we have to read out the possible empty packet from the socket, so
  10. that the kernel doesn't tell us again and again about it.
  11. Signed-off-by: Alexander E. Patrakov <patrakov@gmail.com>
  12. ---
  13. src/modules/rtp/rtp.c | 25 +++++++++++++++++++++++--
  14. 1 file changed, 23 insertions(+), 2 deletions(-)
  15. diff --git a/src/modules/rtp/rtp.c b/src/modules/rtp/rtp.c
  16. index 570737e..7b75e0e 100644
  17. --- a/src/modules/rtp/rtp.c
  18. +++ b/src/modules/rtp/rtp.c
  19. @@ -182,8 +182,29 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool, struct
  20. goto fail;
  21. }
  22. - if (size <= 0)
  23. - return 0;
  24. + if (size <= 0) {
  25. + /* size can be 0 due to any of the following reasons:
  26. + *
  27. + * 1. Somebody sent us a perfectly valid zero-length UDP packet.
  28. + * 2. Somebody sent us a UDP packet with a bad CRC.
  29. + *
  30. + * It is unknown whether size can actually be less than zero.
  31. + *
  32. + * In the first case, the packet has to be read out, otherwise the
  33. + * kernel will tell us again and again about it, thus preventing
  34. + * reception of any further packets. So let's just read it out
  35. + * now and discard it later, when comparing the number of bytes
  36. + * received (0) with the number of bytes wanted (1, see below).
  37. + *
  38. + * In the second case, recvmsg() will fail, thus allowing us to
  39. + * return the error.
  40. + *
  41. + * Just to avoid passing zero-sized memchunks and NULL pointers to
  42. + * recvmsg(), let's force allocation of at least one byte by setting
  43. + * size to 1.
  44. + */
  45. + size = 1;
  46. + }
  47. if (c->memchunk.length < (unsigned) size) {
  48. size_t l;
  49. --
  50. 2.0.0