Nim icon indicating copy to clipboard operation
Nim copied to clipboard

Invalid codegen / dangling pointer for openArray escaping from `block`

Open arnetheduck opened this issue 1 year ago • 2 comments

Description

The following snippet results in a dangling pointer for the array access:

type ArrayBuf = object
  buf: array[32, byte]
  n: int

template data*(bParam: ArrayBuf): openArray =
  block:
    let b = bParam
    b.buf.toOpenArray(0, b.n - 1)

proc leaky() =
  var a: ArrayBuf

  echo a.data()

leaky()
N_LIB_PRIVATE N_NIMCALL(void, _ZN6testit5leakyE)(void) {
  tyObject_ArrayBuf__3ViybJCcjsNgggY4gNLhwQ a;
  tyArray__nHXaesL0DJZHyVS07ARPRA T1_;
  tyOpenArray__UMVJID9bgFAzHOc9bt5jE4PA T2_;
  nimZeroMem((void *)(&a), sizeof(tyObject_ArrayBuf__3ViybJCcjsNgggY4gNLhwQ));
  nimZeroMem((void *)T1_, sizeof(tyArray__nHXaesL0DJZHyVS07ARPRA));
  {
    tyObject_ArrayBuf__3ViybJCcjsNgggY4gNLhwQ bX60gensym0_;
    NI TM__8qVWOq10n9bbKER8oGDqhuw_2;
    nimZeroMem((void *)(&bX60gensym0_),
               sizeof(tyObject_ArrayBuf__3ViybJCcjsNgggY4gNLhwQ));
    bX60gensym0_ = a;
    if (nimSubInt(bX60gensym0_.n, ((NI)1), &TM__8qVWOq10n9bbKER8oGDqhuw_2)) {
      raiseOverflow();
    };
    if ((NI)(TM__8qVWOq10n9bbKER8oGDqhuw_2) - ((NI)0) != -1 &&
        ((NI)(TM__8qVWOq10n9bbKER8oGDqhuw_2) - ((NI)0) < -1 || ((NI)0) < 0 ||
         ((NI)0) > 31 || (NI)(TM__8qVWOq10n9bbKER8oGDqhuw_2) < 0 ||
         (NI)(TM__8qVWOq10n9bbKER8oGDqhuw_2) > 31)) {
      raiseIndexError();
    }
    T2_.Field0 = (NU8 *)((bX60gensym0_.buf) + (((NI)0)));
    T2_.Field1 = ((NI)(TM__8qVWOq10n9bbKER8oGDqhuw_2)) - (((NI)0)) + 1;
  }
  T1_[0] = _ZN7dollars7dollar_E9openArrayI5uInt8E(T2_.Field0, T2_.Field1);
  echoBinSafe(T1_, 1);
}

Here, tyObject_ArrayBuf__3ViybJCcjsNgggY4gNLhwQ bX60gensym0_; is generated inside a {} block and the pointer T2_.Field0 is allowed to escape from out of that block.

Because bX60gensym0_ has gone out of scope, this allows the C compiler to reuse the stack space for other purposes which results in data corruption when T2_ is accessed.

Nim Version

2.0.8

Current Output

No response

Expected Output

No response

Known Workarounds

No response

Additional Information

No response

arnetheduck avatar Oct 08 '24 08:10 arnetheduck