Skip to content

Commit 9f0733d

Browse files
committed
codeql: add query for "non binary" is function
1 parent 12a143d commit 9f0733d

File tree

4 files changed

+87
-0
lines changed

4 files changed

+87
-0
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* @name Finds functions that suggest a boolean return type, but do not.
3+
* @description This query identifies functions that are named with the `is` prefix but return values outside
4+
* the typical boolean range of 0 and 1.
5+
* @kind problem
6+
* @id asymmetric-research/non-binary-is-function
7+
* @precision medium
8+
* @severity warning
9+
* @tags correctness
10+
* maintainability
11+
*/
12+
13+
import cpp
14+
import semmle.code.cpp.rangeanalysis.new.SimpleRangeAnalysis
15+
16+
/**
17+
* A function whose name suggests it returns a boolean value (0 or 1).
18+
*/
19+
class IsFunction extends Function {
20+
IsFunction() {
21+
this.getName().matches("%\\_is\\_%") and
22+
this.getType() instanceof IntegralType and
23+
not this.getName() = "fd_bn254_pairing_is_one_syscall"
24+
// returns values in [-1, 0]
25+
}
26+
}
27+
28+
from IsFunction f, ReturnStmt rs, int lowerBound, int upperBound
29+
where
30+
rs.getEnclosingFunction() = f and
31+
lowerBound = lowerBound(rs.getExpr().getFullyConverted()) and
32+
upperBound = upperBound(rs.getExpr().getFullyConverted()) and
33+
(
34+
lowerBound < 0 or
35+
upperBound > 1
36+
)
37+
select rs,
38+
"The function $@ is named like an `is` function but returns a value with bounds [" + lowerBound +
39+
", " + upperBound + "].", f, f.getName()
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Add missing typedef and define
2+
#define FD_EXECUTOR_INSTR_ERR_MISSING_ACC (-33) /* An account required by the instruction is missing */
3+
#define FD_BANK_FLAGS_DEAD (0x00000008UL) /* Dead. We stopped replaying it before we could finish it (e.g. invalid block or pruned minority fork). */
4+
5+
typedef struct
6+
{
7+
int acct_cnt;
8+
struct
9+
{
10+
int is_signer;
11+
} accounts[10];
12+
} fd_instr_info_t;
13+
14+
typedef struct
15+
{
16+
int flags;
17+
} fd_bank_t;
18+
19+
int fd_instr_acc_is_signer_idx(fd_instr_info_t const *instr,
20+
short idx)
21+
{
22+
if (FD_UNLIKELY(idx >= instr->acct_cnt))
23+
{
24+
return FD_EXECUTOR_INSTR_ERR_MISSING_ACC; // $ Alert (returns -33 which is not 0 or 1)
25+
}
26+
27+
return !!(instr->accounts[idx].is_signer);
28+
}
29+
30+
static inline int
31+
fd_banks_is_bank_dead(fd_bank_t *bank)
32+
{
33+
return bank->flags & FD_BANK_FLAGS_DEAD; // $ Alert (returns value in [0, 8])
34+
}
35+
36+
// inspired by the function, but heavily simplified
37+
int fd_bn254_pairing_is_one_syscall(unsigned long in_sz)
38+
{
39+
if (in_sz != 128UL)
40+
{
41+
return -1; // No alert
42+
}
43+
return 0;
44+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| NonBinaryIsFunction.c:24:9:24:49 | return ... | The function $@ is named like an `is` function but returns a value with bounds [-33, -33]. | NonBinaryIsFunction.c:19:5:19:30 | fd_instr_acc_is_signer_idx | fd_instr_acc_is_signer_idx |
2+
| NonBinaryIsFunction.c:33:5:33:44 | return ... | The function $@ is named like an `is` function but returns a value with bounds [0, 8]. | NonBinaryIsFunction.c:31:1:31:21 | fd_banks_is_bank_dead | fd_banks_is_bank_dead |
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
query: NonBinaryIsFunction.ql
2+
postprocess: InlineExpectationsTestQuery.ql

0 commit comments

Comments
 (0)