mirror of
https://github.com/github/codeql.git
synced 2026-04-27 09:45:15 +02:00
Merge pull request #12247 from smowton/smowton/fix/integer-conversion-sign
Go integer conversion: check against sink, not source signedness
This commit is contained in:
@@ -56,14 +56,14 @@ private predicate isIncorrectIntegerConversion(int sourceBitSize, int sinkBitSiz
|
|||||||
* integer types, which could cause unexpected values.
|
* integer types, which could cause unexpected values.
|
||||||
*/
|
*/
|
||||||
class ConversionWithoutBoundsCheckConfig extends TaintTracking::Configuration {
|
class ConversionWithoutBoundsCheckConfig extends TaintTracking::Configuration {
|
||||||
boolean sourceIsSigned;
|
boolean sinkIsSigned;
|
||||||
int sourceBitSize;
|
int sourceBitSize;
|
||||||
int sinkBitSize;
|
int sinkBitSize;
|
||||||
|
|
||||||
ConversionWithoutBoundsCheckConfig() {
|
ConversionWithoutBoundsCheckConfig() {
|
||||||
sourceIsSigned in [true, false] and
|
sinkIsSigned in [true, false] and
|
||||||
isIncorrectIntegerConversion(sourceBitSize, sinkBitSize) and
|
isIncorrectIntegerConversion(sourceBitSize, sinkBitSize) and
|
||||||
this = "ConversionWithoutBoundsCheckConfig" + sourceBitSize + sourceIsSigned + sinkBitSize
|
this = "ConversionWithoutBoundsCheckConfig" + sourceBitSize + sinkIsSigned + sinkBitSize
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the bit size of the source. */
|
/** Gets the bit size of the source. */
|
||||||
@@ -75,11 +75,6 @@ class ConversionWithoutBoundsCheckConfig extends TaintTracking::Configuration {
|
|||||||
|
|
|
|
||||||
c.getTarget() = ip and source = c.getResult(0)
|
c.getTarget() = ip and source = c.getResult(0)
|
||||||
|
|
|
|
||||||
(
|
|
||||||
if ip.getResultType(0) instanceof SignedIntegerType
|
|
||||||
then sourceIsSigned = true
|
|
||||||
else sourceIsSigned = false
|
|
||||||
) and
|
|
||||||
(
|
(
|
||||||
apparentBitSize = ip.getTargetBitSize()
|
apparentBitSize = ip.getTargetBitSize()
|
||||||
or
|
or
|
||||||
@@ -112,10 +107,13 @@ class ConversionWithoutBoundsCheckConfig extends TaintTracking::Configuration {
|
|||||||
predicate isSinkWithBitSize(DataFlow::TypeCastNode sink, int bitSize) {
|
predicate isSinkWithBitSize(DataFlow::TypeCastNode sink, int bitSize) {
|
||||||
sink.asExpr() instanceof ConversionExpr and
|
sink.asExpr() instanceof ConversionExpr and
|
||||||
exists(IntegerType integerType | sink.getResultType().getUnderlyingType() = integerType |
|
exists(IntegerType integerType | sink.getResultType().getUnderlyingType() = integerType |
|
||||||
bitSize = integerType.getSize()
|
(
|
||||||
or
|
bitSize = integerType.getSize()
|
||||||
not exists(integerType.getSize()) and
|
or
|
||||||
bitSize = getIntTypeBitSize(sink.getFile())
|
not exists(integerType.getSize()) and
|
||||||
|
bitSize = getIntTypeBitSize(sink.getFile())
|
||||||
|
) and
|
||||||
|
if integerType instanceof SignedIntegerType then sinkIsSigned = true else sinkIsSigned = false
|
||||||
) and
|
) and
|
||||||
not exists(ShrExpr shrExpr |
|
not exists(ShrExpr shrExpr |
|
||||||
shrExpr.getLeftOperand().getGlobalValueNumber() =
|
shrExpr.getLeftOperand().getGlobalValueNumber() =
|
||||||
@@ -134,7 +132,7 @@ class ConversionWithoutBoundsCheckConfig extends TaintTracking::Configuration {
|
|||||||
if sinkBitSize != 0 then bitSize = sinkBitSize else bitSize = 32
|
if sinkBitSize != 0 then bitSize = sinkBitSize else bitSize = 32
|
||||||
|
|
|
|
||||||
node = DataFlow::BarrierGuard<upperBoundCheckGuard/3>::getABarrierNodeForGuard(g) and
|
node = DataFlow::BarrierGuard<upperBoundCheckGuard/3>::getABarrierNodeForGuard(g) and
|
||||||
g.isBoundFor(bitSize, sourceIsSigned)
|
g.isBoundFor(bitSize, sinkIsSigned)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* The query `go/incorrect-integer-conversion` now correctly recognises guards of the form `if val <= x` to protect a conversion `uintX(val)` when `x` is in the range `(math.MaxIntX, math.MaxUintX]`.
|
||||||
@@ -264,6 +264,9 @@ func testBoundsChecking(input string) {
|
|||||||
_ = int16(parsed)
|
_ = int16(parsed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if parsed <= math.MaxUint16 {
|
||||||
|
_ = uint16(parsed)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
parsed, err := strconv.ParseUint(input, 10, 32)
|
parsed, err := strconv.ParseUint(input, 10, 32)
|
||||||
|
|||||||
Reference in New Issue
Block a user