2 Bugs 1 Day¶
2023-11-23
If I had a nickel every time I encountered a cursed bug today, I'd have two. It's not a lot but weird how it happened twice.
Bug 1¶
My roommate asked me about a bug in his C code. He passed a value to a function. The value is not supposed to be zero, but in the output, it apparently is. Why?
We could not find any lines of code that could have changed this value. It
was initialized with a command line argument (i.e. atoi(argv[2])
), then
remains read-only.
After ruling out off-by-one errors and floating point rounding, I hypothesize it has something to do with the data structure. The value is within a struct as follows:
struct foo_t {
bar_t bar[256];
int value;
} foo;
foo
is a global instance of struct foo_t
. To initialize it, we set
value
to a command line argument and initialize bar
with a for loop,
which looks like:
for (int i = 0; i < arg1; i++) {
for (int j = 0; j < arg2; j++) {
foo.bar[i * arg2 * arg3 + j] = 0;
}
}
I realized that arg3
was unnecessary. By multiplying it, we're spacing
out the indices too much. If arg1
gets big enough, we'll get a buffer
overflow.
It just so happens that all arguments are powers of 2, and bar
is an
array of 256. Which means… You'll overwrite value
!
We removed arg3
and sure enough, it worked.
Conclusion: Lack of bound checking in C.
Bug 2¶
Right after we hunted down this bug, my roommate said there's another bug in VSCode that has bothered him for a while. It seems like whenever he types the word "store" in a Markdown code block, the syntax highlighting (regardless of language) breaks. He looked through the VSCode repo and didn't find anything particular.
We found that the keyword doesn't have to be "store", it just needs to be "re" + whitespace.
What does re
stand for? The Python package?
This is so cursed that I decided to make the ultimate sacrifice — to install VSCode on my own machine.
However, I failed to reproduce. My roommate correctly suggests it's a problem with a plugin. He disabled all the Markdown-related plugins on his machine. The bug is still there.
He then disabled all plugins (except those bundled). The bug is gone.
VSCode has a "plugin bisect" tool that does a binary search to find the problematic plugin in O(log(# plugins)) time. I did that and the problem is…
OCaml Platform.
Do you realize how shocked we were? Like, we would rather believe it was ghosts or something. OCaml is literally the single most innocent plugin.
We looked at OCaml Platform's code and found something interesting.
{
"repository": {
"reason-code-block": {
"begin": "(re|reason|reasonml)(\\s+[^`~]*)?$",
"end": "(^|\\G)(?=\\s*[`~]{3,}\\s*$)",
...
},
...
}
I do not know how this works, but boy I sure know regex checks out. We
tried reason
, and yes, it broke as well.
This code was added in a 2020 commit, and remains unchanged since. It's such a minor bug that I believe 90% its users didn't even notice. I encouraged my roommate to file a bug report — or even a pull request.
My hypothesis is OCaml programmers simply don't program in anything else.
Conclusion: OCaml plugin ships a regex with false positives.
Takeaway¶
- There is a reason for every bug.
- There is not an obvious reason for every bug.
- C will just silently overflow your buffer without you knowing. Can't wait till Linux is 100% Rust