Fix use-after-free when keeping pointers to args from at-files (#1426)

This commit is contained in:
Eldred Habert
2024-07-25 23:00:48 +02:00
committed by GitHub
parent c0904228f2
commit 1d89d75381
4 changed files with 25 additions and 3 deletions

View File

@@ -13,6 +13,7 @@
#include <string.h> #include <string.h>
#include <string_view> #include <string_view>
#include <type_traits> #include <type_traits>
#include <vector>
#include "extern/getopt.hpp" #include "extern/getopt.hpp"
#include "file.hpp" #include "file.hpp"
@@ -601,7 +602,6 @@ int main(int argc, char *argv[]) {
struct AtFileStackEntry { struct AtFileStackEntry {
int parentInd; // Saved offset into parent argv int parentInd; // Saved offset into parent argv
std::vector<char *> argv; // This context's arg pointer vec std::vector<char *> argv; // This context's arg pointer vec
std::vector<char> argPool;
AtFileStackEntry(int parentInd_, std::vector<char *> argv_) AtFileStackEntry(int parentInd_, std::vector<char *> argv_)
: parentInd(parentInd_), argv(argv_) {} : parentInd(parentInd_), argv(argv_) {}
@@ -610,18 +610,24 @@ int main(int argc, char *argv[]) {
int curArgc = argc; int curArgc = argc;
char **curArgv = argv; char **curArgv = argv;
std::vector<std::vector<char>> argPools;
for (;;) { for (;;) {
char *atFileName = parseArgv(curArgc, curArgv); char *atFileName = parseArgv(curArgc, curArgv);
if (atFileName) { if (atFileName) {
// We need to allocate a new arg pool for each at-file, so as not to invalidate pointers
// previous at-files may have generated to their own arg pools.
// But for the same reason, the arg pool must also outlive the at-file's stack entry!
auto &argPool = argPools.emplace_back();
// Copy `argv[0]` for error reporting, and because option parsing skips it // Copy `argv[0]` for error reporting, and because option parsing skips it
AtFileStackEntry &stackEntry = AtFileStackEntry &stackEntry =
atFileStack.emplace_back(musl_optind, std::vector{atFileName}); atFileStack.emplace_back(musl_optind, std::vector{atFileName});
// It would be nice to compute the char pointers on the fly, but reallocs don't allow // It would be nice to compute the char pointers on the fly, but reallocs don't allow
// that; so we must compute the offsets after the pool is fixed // that; so we must compute the offsets after the pool is fixed
auto offsets = readAtFile(&musl_optarg[1], stackEntry.argPool); auto offsets = readAtFile(&musl_optarg[1], argPool);
stackEntry.argv.reserve(offsets.size() + 2); // Avoid a bunch of reallocs stackEntry.argv.reserve(offsets.size() + 2); // Avoid a bunch of reallocs
for (size_t ofs : offsets) { for (size_t ofs : offsets) {
stackEntry.argv.push_back(&stackEntry.argPool.data()[ofs]); stackEntry.argv.push_back(&argPool.data()[ofs]);
} }
stackEntry.argv.push_back(nullptr); // Don't forget the arg vector terminator! stackEntry.argv.push_back(nullptr); // Don't forget the arg vector terminator!

14
test/gfx/at-file-ref.err Normal file
View File

@@ -0,0 +1,14 @@
error: Failed to fit tile colors [$7f55, $7fff] in specified palettes
error: Failed to fit tile colors [$7f55] in specified palettes
error: Failed to fit tile colors [$6c8a, $7f55, $7fff] in specified palettes
error: Failed to fit tile colors [$6c8a, $7fff] in specified palettes
error: Failed to fit tile colors [$6c8a, $7f55] in specified palettes
error: Failed to fit tile colors [$6c8a] in specified palettes
error: Failed to fit tile colors [$7fff] in specified palettes
note: The following palettes were specified:
[$3f65, $36b3, $262a, $50b0]
[$5f77, $213d, $41a6, $40ee]
[$5f77, $267c, $213d, $40ee]
[$53c3, $3f65, $36b3]
[$267c, $41a6]
Conversion aborted after 7 errors

View File

@@ -0,0 +1,2 @@
-m
-c gbc:result.pal

BIN
test/gfx/at-file-ref.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 712 B