031-CVE-2017-12163-v3.6.patch 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. From: =?utf-8?q?Guido_G=C3=BCnther?= <agx@sigxcpu.org>
  2. Date: Wed, 20 Sep 2017 20:02:03 +0200
  3. Subject: CVE-2017-12163: s3:smbd: Prevent client short SMB1 write from
  4. writing server memory to file.
  5. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13020
  6. Author: Jeremy Allison <jra@samba.org>
  7. Signed-off-by: Jeremy Allison <jra@samba.org>
  8. Signed-off-by: Stefan Metzmacher <metze@samba.org>
  9. ---
  10. source3/smbd/reply.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
  11. 1 file changed, 50 insertions(+)
  12. --- a/source3/smbd/reply.c
  13. +++ b/source3/smbd/reply.c
  14. @@ -3979,6 +3979,9 @@ void reply_writebraw(struct smb_request
  15. }
  16. /* Ensure we don't write bytes past the end of this packet. */
  17. + /*
  18. + * This already protects us against CVE-2017-12163.
  19. + */
  20. if (data + numtowrite > smb_base(req->inbuf) + smb_len(req->inbuf)) {
  21. reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  22. error_to_writebrawerr(req);
  23. @@ -4080,6 +4083,11 @@ void reply_writebraw(struct smb_request
  24. exit_server_cleanly("secondary writebraw failed");
  25. }
  26. + /*
  27. + * We are not vulnerable to CVE-2017-12163
  28. + * here as we are guarenteed to have numtowrite
  29. + * bytes available - we just read from the client.
  30. + */
  31. nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite);
  32. if (nwritten == -1) {
  33. TALLOC_FREE(buf);
  34. @@ -4161,6 +4169,7 @@ void reply_writeunlock(struct smb_reques
  35. connection_struct *conn = req->conn;
  36. ssize_t nwritten = -1;
  37. size_t numtowrite;
  38. + size_t remaining;
  39. SMB_OFF_T startpos;
  40. const char *data;
  41. NTSTATUS status = NT_STATUS_OK;
  42. @@ -4193,6 +4202,17 @@ void reply_writeunlock(struct smb_reques
  43. startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
  44. data = (const char *)req->buf + 3;
  45. + /*
  46. + * Ensure client isn't asking us to write more than
  47. + * they sent. CVE-2017-12163.
  48. + */
  49. + remaining = smbreq_bufrem(req, data);
  50. + if (numtowrite > remaining) {
  51. + reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  52. + END_PROFILE(SMBwriteunlock);
  53. + return;
  54. + }
  55. +
  56. if (!fsp->print_file && numtowrite > 0) {
  57. init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
  58. (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
  59. @@ -4274,6 +4294,7 @@ void reply_write(struct smb_request *req
  60. {
  61. connection_struct *conn = req->conn;
  62. size_t numtowrite;
  63. + size_t remaining;
  64. ssize_t nwritten = -1;
  65. SMB_OFF_T startpos;
  66. const char *data;
  67. @@ -4314,6 +4335,17 @@ void reply_write(struct smb_request *req
  68. startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
  69. data = (const char *)req->buf + 3;
  70. + /*
  71. + * Ensure client isn't asking us to write more than
  72. + * they sent. CVE-2017-12163.
  73. + */
  74. + remaining = smbreq_bufrem(req, data);
  75. + if (numtowrite > remaining) {
  76. + reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  77. + END_PROFILE(SMBwrite);
  78. + return;
  79. + }
  80. +
  81. if (!fsp->print_file) {
  82. init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
  83. (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
  84. @@ -4525,6 +4557,9 @@ void reply_write_and_X(struct smb_reques
  85. return;
  86. }
  87. } else {
  88. + /*
  89. + * This already protects us against CVE-2017-12163.
  90. + */
  91. if (smb_doff > smblen || smb_doff + numtowrite < numtowrite ||
  92. smb_doff + numtowrite > smblen) {
  93. reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  94. @@ -4894,6 +4929,7 @@ void reply_writeclose(struct smb_request
  95. {
  96. connection_struct *conn = req->conn;
  97. size_t numtowrite;
  98. + size_t remaining;
  99. ssize_t nwritten = -1;
  100. NTSTATUS close_status = NT_STATUS_OK;
  101. SMB_OFF_T startpos;
  102. @@ -4927,6 +4963,17 @@ void reply_writeclose(struct smb_request
  103. mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+4));
  104. data = (const char *)req->buf + 1;
  105. + /*
  106. + * Ensure client isn't asking us to write more than
  107. + * they sent. CVE-2017-12163.
  108. + */
  109. + remaining = smbreq_bufrem(req, data);
  110. + if (numtowrite > remaining) {
  111. + reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  112. + END_PROFILE(SMBwriteclose);
  113. + return;
  114. + }
  115. +
  116. if (!fsp->print_file) {
  117. init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
  118. (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
  119. @@ -5497,6 +5544,9 @@ void reply_printwrite(struct smb_request
  120. numtowrite = SVAL(req->buf, 1);
  121. + /*
  122. + * This already protects us against CVE-2017-12163.
  123. + */
  124. if (req->buflen < numtowrite + 3) {
  125. reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
  126. END_PROFILE(SMBsplwr);