github / github/codeql

IRGuardCondition failure to detect NULL condition

Open
#15,186 14 comments 0 reactions 0 assignees View on GitHub
C++ question
Dominant language
CodeQL
Stars
10.1k
Forks
2.1k
Avg merge
2d 15h
Merged PRs (30d)
141

Description

I wrote a small query to understand all the IRGuardConditions inside a function
```
predicate isNotNullCheck3(IRGuardCondition g, Expr e, boolean branch) {

branch = true
and
(g.getEnclosingFunction().hasName("func2")
or g.getEnclosingFunction().hasName("xkb_compose_table_new_from_file"))
and g.getAnOperand().getUse().getUnconvertedResultExpression() = e
}
```
Below is snippet of my custom function func2(...)
```
int func2(int num,test_struct *test){
if(!test) {
return 1;
}
if(num > 0) {
test = (test_struct *)calloc(num, sizeof(*test));
if(!test) {
return 1;
}
}
test[0].a = 1;
test[0].b = 2;
return 0;
}
```
Below is a function named xkb_compose_table_new_from_file from [libxkbcommon](https://github.com/xkbcommon/libxkbcommon/blob/master/src/compose/table.c#L93)
```
xkb_compose_table_new_from_file(struct xkb_context *ctx,
FILE *file,
const char *locale,
enum xkb_compose_format format,
enum xkb_compose_compile_flags flags)
{
struct xkb_compose_table *table;
bool ok;

if (flags & ~(XKB_COMPOSE_COMPILE_NO_FLAGS)) {
log_err_func(ctx, "unrecognized flags: %#x\n", flags);
return NULL;
}

if (format != XKB_COMPOSE_FORMAT_TEXT_V1) {
log_err_func(ctx, "unsupported compose format: %d\n", format);
return NULL;
}

table = xkb_compose_table_new(ctx, locale, format, flags);
if (!table)
return NULL;

ok = parse_file(table, file, "(unknown file)");
if (!ok) {
xkb_compose_table_unref(table);
return NULL;
}

return table;
}
```
The results for func2 are as expected. I see `CompareNE` and `CompareGT`
Screenshot 2023-12-21 at 2 41 44 AM

While for libxkbcommon, I see `Load: table` and `Load: ok` as IRGuardCondition rather than `CompareNE: (bool)...`
Screenshot 2023-12-21 at 2 42 55 AM

Any reason for this discrepancy?
Due to this issue, the predicate below is unable to detect NULL check
```
predicate isNotNullCheck2(IRGuardCondition g, Expr e, boolean branch) {
g.comparesEq(any(Instruction instr | instr.getUnconvertedResultExpression() = e).getAUse(),
any(ConstantValueInstruction const | const.getValue() = "0").getAUse(), 0, false, branch)
}
```

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the IRGuardCondition query against func2 and xkb_compose_table_new_from_file, comparing the reported Load conditions with the CompareNE and CompareGT conditions. Inspect the isNotNullCheck3 and isNotNullCheck2 predicates and the relevant IRGuardCondition behavior. Done means the NULL checks are represented or queryable consistently, with the discrepancy explained and covered by a regression test if the payload identifies one.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
compilers, devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.