Skip to content

Invalid codegen / dangling pointer for openArray escaping from block #24261

Open
@arnetheduck

Description

@arnetheduck

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions