mirror of
https://github.com/NixOS/nix
synced 2025-06-29 02:11:15 +02:00
Fix segfault or stack overflow caused by large derivation fields
This removes a dynamic stack allocation, making the derivation unparsing logic robust against overflows when large strings are added to a derivation. Overflow behavior depends on the platform and stack configuration. For instance, x86_64-linux/glibc behaves as (somewhat) expected: $ (ulimit -s 20000; nix-instantiate tests/lang/eval-okay-big-derivation-attr.nix) error: stack overflow (possible infinite recursion) $ (ulimit -s 40000; nix-instantiate tests/lang/eval-okay-big-derivation-attr.nix) error: expression does not evaluate to a derivation (or a set or list of those) However, on aarch64-darwin: $ nix-instantiate big-attr.nix ~ zsh: segmentation fault nix-instantiate big-attr.nix This indicates a slight flaw in the single stack protection page approach that is not encountered with normal stack frames.
This commit is contained in:
parent
bc443511eb
commit
d038a67bd3
3 changed files with 28 additions and 1 deletions
|
@ -272,7 +272,15 @@ Derivation parseDerivation(const Store & store, std::string && s, std::string_vi
|
|||
|
||||
static void printString(string & res, std::string_view s)
|
||||
{
|
||||
char buf[s.size() * 2 + 2];
|
||||
char * buf;
|
||||
size_t bufSize = s.size() * 2 + 2;
|
||||
std::unique_ptr<char[]> dynBuf;
|
||||
if (bufSize < 0x10000) {
|
||||
buf = (char *)alloca(bufSize);
|
||||
} else {
|
||||
dynBuf = decltype(dynBuf)(new char[bufSize]);
|
||||
buf = dynBuf.get();
|
||||
}
|
||||
char * p = buf;
|
||||
*p++ = '"';
|
||||
for (auto c : s)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue