Skip to content

Need help for write query [cpp] #3292

@hac425xxx

Description

@hac425xxx

I want to search pattern like this



struct _wStream
{
    char *buffer;
    char *pointer;
    size_t length;
    size_t capacity;

    size_t count;
};
typedef struct _wStream wStream;

#define _stream_read_n32_le(_t, _s, _v, _p)                                                 \
    do                                                                                      \
    {                                                                                       \
        (_v) = (_t)(*(_s)->pointer) + (((_t)(*((_s)->pointer + 1))) << 8) +                 \
               (((_t)(*((_s)->pointer + 2))) << 16) + (((_t)(*((_s)->pointer + 3))) << 24); \
        if (_p)                                                                             \
            Stream_Seek(_s, sizeof(_t));                                                    \
    } while (0)
#define Stream_Read_UINT32(_s, _v) _stream_read_n32_le(UINT32, _s, _v, TRUE)

int realloc_test(wStream *s)
{
    unsigned int count;
    unsigned int x1, x2;

    char *pp = malloc(20);

    Stream_Read_UINT32(s, x1);
    count += x1;
    Stream_Read_UINT32(s, x2);

    count += x2;

    char *p = realloc(pp, count);
    if (p == NULL)
    {
        free(pp);
        return 1;
    }

    return 0;
}

I try write the following query , but I have no result

import cpp
import semmle.code.cpp.dataflow.TaintTracking
import semmle.code.cpp.dataflow.DataFlow

class PointerAccess extends FieldAccess {
  PointerAccess() {
    this.getTarget().getQualifiedName().matches("%wStream%") and
    this.getTarget().hasName("pointer")
  }
}

class ReadSteam extends AssignExpr {
  ReadSteam() {
    exists(PointerDereferenceExpr pde |
      pde.getOperand() instanceof PointerAccess and
      this.getAnOperand() = pde
    )
  }
}

class Target extends Expr {
  Target() {
    this =
      any(MacroInvocation mi | mi.getOutermostMacroAccess().getMacroName().matches("Stream_Read_%"))
          .getExpr()
  }
}

class ReadStreamConfiguration extends TaintTracking::Configuration {
  ReadStreamConfiguration() { this = "ReadStreamConfiguration" }

  override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof Target }

  override predicate isSink(DataFlow::Node sink) {
    exists(FunctionCall fc |
      fc.getTarget().getName().regexpMatch("memcpy|memmove") and
      fc.getArgument(2) = sink.asExpr()
    )
    or
    exists(FunctionCall fc |
      fc.getTarget().hasName("realloc") and
      fc.getArgument(1) = sink.asExpr()
    )
    // and
    // not exists(IfStmt ifs | ifs.getControllingExpr() = sink.asExpr())
  }
}

// from ReadStreamConfiguration cfg, Expr sizeArg, Expr e
// where cfg.hasFlow(DataFlow::exprNode(e), DataFlow::exprNode(sizeArg))
// select e, sizeArg
from Target rs, FunctionCall fc
where
  fc.getTarget().hasName("realloc") and
  exists(DataFlow::Node source, DataFlow::Node sink |
    DataFlow::localFlow(source, sink) and
    source.asExpr() instanceof ReadSteam and
    sink.asExpr() = fc.getArgument(1)
  )
select rs, fc, fc.getArgument(1)

anything worry?

Taint data is in stream->pointer, I want to track data from pointer to the size argument of realloc.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C++questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions