Back to success stories

Sample of Defect

Project Name CID Checker Category Developer Description
curl 1299430 TAINTED_SCALAR Insecure data handling This turned out to be a security flaw, now known as CVE-2015-3237. Full description here: http://curl.haxx.se/docs/adv_20150617B.html It could make a malicious server fool a client to send off data from memory it didn't intend to.
File: /lib/smb.c
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
    *done = true;
    break;

  default:
    smb_pop_message(conn);
    return CURLE_OK; /* ignore */
  }

  smb_pop_message(conn);

  return CURLE_OK;
}

static CURLcode smb_request_state(struct connectdata *conn, bool *done)
{
  struct smb_request *req = conn->data->req.protop;
  struct smb_header *h;
  enum smb_req_state next_state = SMB_DONE;
  unsigned short len;
  unsigned short off;
  CURLcode result;
  void *msg = NULL;

  /* Start the request */
 < 1. Condition "req->state == SMB_REQUESTING", taking false branch
720
721
722
723
724
725
726
727
728
729
730
731
  if(req->state == SMB_REQUESTING) {
    result = smb_send_tree_connect(conn);
    if(result) {
      connclose(conn, "SMB: failed to send tree connect message");
      return result;
    }

    request_state(conn, SMB_TREE_CONNECT);
  }

  /* Send the previous message and check for a response */
  result = smb_send_and_recv(conn, &msg);
 < 2. Condition "result", taking false branch
732
733
734
735
  if(result && result != CURLE_AGAIN) {
    connclose(conn, "SMB: failed to communicate");
    return result;
  }
 < 3. Condition "!msg", taking false branch
737
738
739
740
  if(!msg)
    return CURLE_OK;

  h = msg;
 < 4. Switch case value "SMB_DOWNLOAD"
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
  switch(req->state) {
  case SMB_TREE_CONNECT:
    if(h->status) {
      req->result = CURLE_REMOTE_FILE_NOT_FOUND;
      if(h->status == smb_swap32(SMB_ERR_NOACCESS))
        req->result = CURLE_REMOTE_ACCESS_DENIED;
      break;
    }
    req->tid = smb_swap16(h->tid);
    next_state = SMB_OPEN;
    break;

  case SMB_OPEN:
    if(h->status) {
      req->result = CURLE_REMOTE_FILE_NOT_FOUND;
      next_state = SMB_TREE_DISCONNECT;
      break;
    }
    req->fid = smb_swap16(((struct smb_nt_create_response *)msg)->fid);
    conn->data->req.offset = 0;
    if(conn->data->set.upload) {
      conn->data->req.size = conn->data->state.infilesize;
      Curl_pgrsSetUploadSize(conn->data, conn->data->req.size);
      next_state = SMB_UPLOAD;
    }
    else {
      conn->data->req.size =
        smb_swap64(((struct smb_nt_create_response *)msg)->end_of_file);
      Curl_pgrsSetDownloadSize(conn->data, conn->data->req.size);
      next_state = SMB_DOWNLOAD;
    }
    break;

  case SMB_DOWNLOAD:
 < 5. Condition "h->status", taking false branch
776
777
778
779
780
    if(h->status) {
      req->result = CURLE_RECV_ERROR;
      next_state = SMB_CLOSE;
      break;
    }
 <<< CID 1299430: Insecure data handling TAINTED_SCALAR
 <<< 6. Function "Curl_read16_le" returns tainted data.
 << 7. Assigning: "len" = "Curl_read16_le", which taints "len".
781
782
783
784
    len = Curl_read16_le(((unsigned char *) msg) +
                         sizeof(struct smb_header) + 11);
    off = Curl_read16_le(((unsigned char *) msg) +
                         sizeof(struct smb_header) + 13);
 << 8. Casting narrower unsigned "len" to wider signed type "int" effectively tests its lower bound.
 < 9. Condition "len > 0", taking true branch
 << 10. Checking lower bounds of unsigned scalar "len" by "len > 0".
785
    if(len > 0) {
 <<< CID 1299430: Insecure data handling TAINTED_SCALAR
 <<< 11. Passing tainted variable "len" to a tainted sink.
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
      result = Curl_client_write(conn, CLIENTWRITE_BODY,
                                 (char *)msg + off + sizeof(unsigned int),
                                 len);
      if(result) {
        req->result = result;
        next_state = SMB_CLOSE;
        break;
      }
    }
    conn->data->req.bytecount += len;
    conn->data->req.offset += len;
    Curl_pgrsSetDownloadCounter(conn->data, conn->data->req.bytecount);
    next_state = (len < MAX_PAYLOAD_SIZE) ? SMB_CLOSE : SMB_DOWNLOAD;
    break;

  case SMB_UPLOAD:
    if(h->status) {
      req->result = CURLE_UPLOAD_FAILED;
      next_state = SMB_CLOSE;
      break;
    }
    len = Curl_read16_le(((unsigned char *) msg) +
                         sizeof(struct smb_header) + 5);
    conn->data->req.bytecount += len;
    conn->data->req.offset += len;
    Curl_pgrsSetUploadCounter(conn->data, conn->data->req.bytecount);
    if(conn->data->req.bytecount >= conn->data->req.size)
Events:
7. var_assign smb.c:781
8. lower_bounds smb.c:785
10. lower_bounds smb.c:785
6. tainted_data_return smb.c:781
11. tainted_data smb.c:786