mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Fix use-after-free when keeping pointers to args from at-files (#1426)
This commit is contained in:
@@ -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
14
test/gfx/at-file-ref.err
Normal 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
|
||||||
2
test/gfx/at-file-ref.flags
Normal file
2
test/gfx/at-file-ref.flags
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
-m
|
||||||
|
-c gbc:result.pal
|
||||||
BIN
test/gfx/at-file-ref.png
Normal file
BIN
test/gfx/at-file-ref.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 712 B |
Reference in New Issue
Block a user