Skip to content

CodeQL: Multiplication result converted to larger type #245

@robn

Description

@robn

I ran CodeQL, a static analysis tool, on monocypher 3.1.3 (more below). It reports "Multiple result converted to large type" on these four lines in poly1305_blocks:

const u64 x0 = s0*r0+ s1*rr3+ s2*rr2+ s3*rr1+ s4*rr0; // <= 97ffffe007fffff8
const u64 x1 = s0*r1+ s1*r0 + s2*rr3+ s3*rr2+ s4*rr1; // <= 8fffffe20ffffff6
const u64 x2 = s0*r2+ s1*r1 + s2*r0 + s3*rr3+ s4*rr2; // <= 87ffffe417fffff4
const u64 x3 = s0*r3+ s1*r2 + s2*r1 + s3*r0 + s4*rr3; // <= 7fffffe61ffffff2

Adding a pile of casts silences the warnings, and the tests still pass:

const u64 x0 = (u64)s0*r0+ (u64)s1*rr3+ (u64)s2*rr2+ (u64)s3*rr1+ (u64)s4*rr0; // <= 97ffffe007fffff8
const u64 x1 = (u64)s0*r1+ (u64)s1*r0 + (u64)s2*rr3+ (u64)s3*rr2+ (u64)s4*rr1; // <= 8fffffe20ffffff6
const u64 x2 = (u64)s0*r2+ (u64)s1*r1 + (u64)s2*r0 + (u64)s3*rr3+ (u64)s4*rr2; // <= 87ffffe417fffff4
const u64 x3 = (u64)s0*r3+ (u64)s1*r2 + (u64)s2*r1 + (u64)s3*r0 + (u64)s4*rr3; // <= 7fffffe61ffffff2

I looked at the disassembly of both and they are subtly different, but I don't know enough to know if that's meaningful.

If you think this is a false positive I would be happy to take it up with the CodeQL people myself, but I'd be interested to know if you think the version with the casts is still "safe", as that is likely the workaround I will use for my project.

As for CodeQL, I don't actually know it or use it myself; its an automated Github thing that open source projects can opt in to, and one I am contributing to (see openzfs/zfs#14249) is using it. I am mostly looking to you for guidance here.

Reproduction:

monocypher-3.1.3$ codeql database create codeql.db --language=cpp --command='bash -c "make clean && make"'
Initializing database at monocypher-3.1.3/codeql.db.
Running build command: [bash, -c, make clean && make]
[2022-12-03 11:20:10] [build-stdout] rm -rf lib/
[2022-12-03 11:20:10] [build-stdout] rm -f  *.out
[2022-12-03 11:20:10] [build-stdout] gcc -std=gnu99  -pedantic -Wall -Wextra -O3 -march=native -I src -I src/optional -fPIC -c -o lib/monocypher.o src/monocypher.c
[2022-12-03 11:20:12] [build-stdout] ar cr lib/libmonocypher.a lib/monocypher.o
[2022-12-03 11:20:12] [build-stdout] gcc -std=gnu99  -pedantic -Wall -Wextra -O3 -march=native  -shared -Wl,-soname,libmonocypher.so.3 -o lib/libmonocypher.so.3 lib/monocypher.o
[2022-12-03 11:20:12] [build-stdout] ln -sf `basename lib/libmonocypher.so.3` lib/libmonocypher.so
Finalizing database at monocypher-3.1.3/codeql.db.
Successfully created database at monocypher-3.1.3/codeql.db.

monocypher-3.1.3$ codeql database analyze --format=csv --output=codeql.csv --download -- codeql.db codeql/cpp-queries:'Likely Bugs/Arithmetic/IntMultToLong.ql'
{
  "packs" : [
    {
      "name" : "codeql/cpp-queries",
      "version" : "0.4.4",
      "library" : false,
      "result" : "IGNORED"
    }
  ],
  "packDir" : "/home/robn/.codeql/packages"
}
Running queries.
[1/1] Loaded /home/robn/.codeql/packages/codeql/cpp-queries/0.4.4/Likely Bugs/Arithmetic/IntMultToLong.qlx.
IntMultToLong.ql: [1/1 eval 6.5s] Results written to codeql/cpp-queries/Likely Bugs/Arithmetic/IntMultToLong.bqrs.
Shutting down query evaluator.
Interpreting results.

monocypher-3.1.3$ cat codeql.csv 
"Multiplication result converted to larger type","A multiplication result that is converted to a larger type can be a sign that the result can overflow the type converted from.","warning","Multiplication result may overflow 'unsigned int' before it is converted to 'unsigned long'.","/src/monocypher.c","349","51","349","56"
"Multiplication result converted to larger type","A multiplication result that is converted to a larger type can be a sign that the result can overflow the type converted from.","warning","Multiplication result may overflow 'unsigned int' before it is converted to 'unsigned long'.","/src/monocypher.c","350","51","350","56"
"Multiplication result converted to larger type","A multiplication result that is converted to a larger type can be a sign that the result can overflow the type converted from.","warning","Multiplication result may overflow 'unsigned int' before it is converted to 'unsigned long'.","/src/monocypher.c","351","51","351","56"
"Multiplication result converted to larger type","A multiplication result that is converted to a larger type can be a sign that the result can overflow the type converted from.","warning","Multiplication result may overflow 'unsigned int' before it is converted to 'unsigned long'.","/src/monocypher.c","352","51","352","56"

GCC 10.2.1, Linux x86_64.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions