|
| 1 | +/** |
| 2 | + * @name `memcpy` size argument probably wrong |
| 3 | + * @description The memcpy size argument is a sizeof(type_t) parameter, |
| 4 | + and dst and src are pointers to types, but the sizes |
| 5 | + of the types referred to by the arguments differ. |
| 6 | + Consider using an assignment expression instead. |
| 7 | + * @kind problem |
| 8 | + * @id firedancer-io/trivial-memcpy-wrong |
| 9 | + * @problem.severity error |
| 10 | + * @precision medium |
| 11 | + * @tags correctness |
| 12 | + */ |
| 13 | + |
| 14 | +import cpp |
| 15 | +import filter |
| 16 | + |
| 17 | +class MemcpyFunction extends Function { |
| 18 | + MemcpyFunction() { |
| 19 | + this.hasGlobalOrStdName("memcpy") |
| 20 | + or |
| 21 | + this.hasGlobalName(["fd_memcpy", "__builtin_memcpy"]) |
| 22 | + } |
| 23 | +} |
| 24 | + |
| 25 | +class NotVoidChar extends Type { |
| 26 | + NotVoidChar() { |
| 27 | + not this instanceof CharType and |
| 28 | + not this instanceof VoidType |
| 29 | + } |
| 30 | +} |
| 31 | + |
| 32 | +from FunctionCall call, MemcpyFunction memcpy, NotVoidChar t1, NotVoidChar t2 |
| 33 | +where |
| 34 | + included(call.getLocation()) and |
| 35 | + not call.isInMacroExpansion() and |
| 36 | + call.getTarget() = memcpy and |
| 37 | + call.getArgument(2) instanceof SizeofTypeOperator and |
| 38 | + call.getArgument(0).getUnspecifiedType().(PointerType).getBaseType() = t1 and |
| 39 | + call.getArgument(1).getUnspecifiedType().(PointerType).getBaseType() = t2 and |
| 40 | + ( |
| 41 | + call.getArgument(0).getUnspecifiedType().(PointerType).getBaseType().getSize() != call.getArgument(1).getUnspecifiedType().(DerivedType).getBaseType().getSize() or |
| 42 | + call.getArgument(0).getUnspecifiedType().(PointerType).getBaseType().getSize() != call.getArgument(2).(SizeofTypeOperator).getTypeOperand().getUnspecifiedType().getSize() |
| 43 | + ) |
| 44 | +select call, "Call to " + memcpy.getName() + " probably has wrong size argument (" + |
| 45 | + "sizeof(dst)=" + call.getArgument(0).getUnspecifiedType().(PointerType).getBaseType().getSize() + |
| 46 | + ", sizeof(src)=" + call.getArgument(1).getUnspecifiedType().(PointerType).getBaseType().getSize() + |
| 47 | + ", sz=" + call.getArgument(2).(SizeofTypeOperator).getTypeOperand().getUnspecifiedType().getSize() |
| 48 | + + ")." |
0 commit comments