<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p>Sorry I didn't go through the details and thought you were
      hitting the<br>
      length OOB issue. Your fix looks valid to me. Would you please
      post<br>
      the patch on net-dev ?<br>
      <br>
    </p>
    <br>
    <div class="moz-cite-prefix">On 1/2/2018 10:32 AM, Mohamed Ghannam
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAP8jf_DK03c0Xcn0wixgC3U6q6iyc965zVm739UXxxDeMYvA4Q@mail.gmail.com">
      <div dir="ltr">Hi,
        <div><br>
        </div>
        <div>I believe that my report has nothing to do with that fix,
          it's completely unrelated,</div>
        <div>I re-checked the proof of concept and still crash the
          kernel,</div>
        <div><br>
        </div>
        <div>The fix should be simple : args-&gt;nr_local should be
          checked against 0 </div>
        <div><br>
        </div>
        <div>Please re-check and let me know if you want any further
          information,</div>
        <div><br>
        </div>
        <div>Bests,</div>
        <div>Mohamed</div>
      </div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">2018-01-02 17:38 GMT+00:00 Santosh
          Shilimkar <span dir="ltr">&lt;<a
              href="mailto:santosh.shilimkar@oracle.com" target="_blank"
              moz-do-not-send="true">santosh.shilimkar@oracle.com</a>&gt;</span>:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">The fix is
            in mainline and marked for stable but am not sure<br>
            if it will get back-ported all the way.<br>
            <br>
            <a
href="https://urldefense.proofpoint.com/v2/url?u=https-3A__patchwork.kernel.org_patch_10128783_&amp;d=DwMFaQ&amp;c=RoP1YumCXCgaWHvlZYR8PZh8Bv7qIrMUB65eapI_JnE&amp;r=hWpFvp_cTkkwMMULcvbV65orOO9Gv3OUaY0ATWhQwak&amp;m=IO0CDsTpgmJIRZcvXV9IivkHeVmf5fAVxPittvU0VvM&amp;s=AGrRlGToeJ8fptgH2R7ilm4_omqi3dBtHnf4oJBPl3o&amp;e="
              rel="noreferrer" target="_blank" moz-do-not-send="true">https://patchwork.kernel.org/p<wbr>atch/10128783/</a><span
              class=""><br>
              <br>
              On 1/2/2018 8:23 AM, Mohamed Ghannam wrote:<br>
            </span>
            <blockquote class="gmail_quote" style="margin:0 0 0
              .8ex;border-left:1px #ccc solid;padding-left:1ex"><span
                class="">
                Hi,<br>
                <br>
                I reported this bug a while ago and still have no
                answer, so this mail is just a reminder and making sure
                that it's been well received,<br>
                <br>
                Cheers,<br>
                Mohamed<br>
                <br>
              </span>
              2017-12-17 12:44 GMT+00:00 Mohamed Ghannam &lt;<a
                href="mailto:simo.ghannam@gmail.com" target="_blank"
                moz-do-not-send="true">simo.ghannam@gmail.com</a>
              &lt;mailto:<a href="mailto:simo.ghannam@gmail.com"
                target="_blank" moz-do-not-send="true">simo.ghannam@gmail.com</a><wbr>&gt;&gt;:
              <div>
                <div class="h5"><br>
                  <br>
                      Hi,<br>
                  <br>
                      Here is a bug I found in RDS socket, it's an Out
                  of bound write<br>
                      The vulnerability affects Linux Kernel from
                  v2.6.29-rc6 to the<br>
                      latest version, it's been introduced in this
                  commit<br>
                      eff5f53bef75c0864a5da06bb68893<wbr>9092b848dc<br>
                  <br>
                      The vulnerability occurs when we deal with
                  ancullary data (through<br>
                      cmsghdr)<br>
                  <br>
                      int rds_sendmsg(struct socket *sock, struct msghdr
                  *msg, size_t<br>
                      payload_len)<br>
                      {<br>
                      ...<br>
                  <br>
                      /* size of rm including all sgs */<br>
                      ret = rds_rm_size(msg, payload_len);&lt;--- (1)<br>
                      if (ret &lt; 0)<br>
                      goto out;<br>
                      ...<br>
                      ...<br>
                      ret = rds_cmsg_send(rs, rm, msg,
                  &amp;allocated_mr);&lt;----- (3)<br>
                      ...<br>
                      }<br>
                  <br>
                      ---<br>
                      int rds_rdma_extra_size(struct rds_rdma_args
                  *args)<br>
                      {<br>
                      ...<br>
                      int tot_pages = 0;<br>
                      ...<br>
                      local_vec = (struct rds_iovec __user *)(unsigned
                  long)<br>
                      args-&gt;local_vec_addr;<br>
                  <br>
                      /* figure out the number of pages in the vector */<br>
                      for (i = 0; i &lt; args-&gt;nr_local; i++)
                  {&lt;---- (3)<br>
                      if (copy_from_user(&amp;vec, &amp;local_vec[i],<br>
                         sizeof(struct rds_iovec)))<br>
                      return -EFAULT;<br>
                  <br>
                      ...<br>
                      /* skipped */<br>
                      }<br>
                  <br>
                      return tot_pages * sizeof(struct scatterlist);
                  &lt;----- (4) :<br>
                      tot_pages = 0;<br>
                      }<br>
                      ----<br>
                      (1) - rds_rm_size() does some sanity checks and
                  return the number of<br>
                      pages should be allocated for the buffer.<br>
                      (2) - rds_cmsg_send() parse the cmsghdr structure
                  and call the<br>
                      appropriate function to handle the packet<br>
                      (3) - in rds_rm_size() calls
                  rds_rdma_extra_size(), when<br>
                      cmsg-&gt;cmsg_types has RDS_CMSG_RDMA_ARGS , args
                  is a user<br>
                      controllable object, these line of codes (in the
                  loop) are never<br>
                      reached when nr_local = 0<br>
                      (4) - if we put nr_local to zero the former
                  function returns 0 due<br>
                      tot_page= 0;<br>
                  <br>
                      int rds_cmsg_rdma_args(struct rds_sock *rs, struct
                  rds_message *rm,<br>
                        struct cmsghdr *cmsg)<br>
                      {<br>
                      ...<br>
                  <br>
                      op-&gt;op_sg = rds_message_alloc_sgs(rm,
                  nr_pages); &lt;---- (5)<br>
                      if (!op-&gt;op_sg) {<br>
                      ret = -ENOMEM;<br>
                      goto out;<br>
                      }<br>
                      ...<br>
                      ...<br>
                      }<br>
                      ---<br>
                  <br>
                      void sg_init_table(struct scatterlist *sgl,
                  unsigned int nents)<br>
                      {<br>
                      memset(sgl, 0, sizeof(*sgl) * nents);<br>
                      #ifdef CONFIG_DEBUG_SG<br>
                      {<br>
                      unsigned int i;<br>
                      for (i = 0; i &lt; nents; i++)<br>
                      sgl[i].sg_magic = SG_MAGIC;<br>
                      }<br>
                      #endif<br>
                      sg_mark_end(&amp;sgl[nents - 1]);&lt;----- (6)<br>
                      }<br>
                  <br>
                      (5) - rds_message_alloc_sgs() allocates pages for
                  DMA , and keep in<br>
                      mind that nr_pages still has 0<br>
                      (6) - sg_init_table is called from
                  rds_message_alloc_sgs(), it tries<br>
                      to initialize the buffer for the incoming packets,
                  the function<br>
                      doesn't check 'nents' variable (which is
                  nr_pages=0) .<br>
                      by decrementing nents by 1, it gives huge invalid
                  integer (integer<br>
                      underflow) which is used as index in the
                  scatterlist array,<br>
                  <br>
                  <br>
                      I've attached also a proof of concept code that
                  crashes the kernel<br>
                      as well as the panic log<br>
                  <br>
                      Bests,<br>
                      Mohamed<br>
                  <br>
                  <br>
                  <br>
                  <br>
                  <br>
                </div>
              </div>
            </blockquote>
          </blockquote>
        </div>
        <br>
      </div>
    </blockquote>
    <br>
  </body>
</html>