← Back to context

Comment by accessvector

2 years ago

Just to handle the case where the same syscall number is specified twice by the ELF header: in that case, the entry is set to -1 (presumably meaning it’s invalid).

I still don't get it. Shouldn't [9] always evaluate to false, and the code be equivalent to:

    pins = mallocarray(npins, sizeof(int), M_PINSYSCALL, M_WAITOK|M_ZERO);
    for (i = 0; i < nsyscalls; i++) {
        pins[syscalls[i].sysno] = syscalls[i].offset;
    }

Edit:

Hang on - npins is already checked in the loop before, and incremented with ++

syscalls[i].sysno can't be larger than what is allocated with:

pins = mallocarray(npins, sizeof(int), M_PINSYSCALL, M_WAITOK|M_ZERO);

So I still can't find the problem

  • Consider this:

        struct pinsyscall entries[] = {
            { .sysno = 1, .offset = 0x1234 },
            { .sysno = 2, .offset = 0x5678 },
            { .sysno = 1, .offset = 0x9abc }
        };
    

    Now `nsyscalls` will be 3 and `pin` will be an array of 3 ints, initialised to `{ 0, 0, 0 }`.

    When we loop through, we'll set:

        1. `pin[syscalls[0].sysno] = 0x1234` => `pin[1] = 0x1234`
        2. `pin[syscalls[1].sysno] = 0x5678` => `pin[2] = 0x5678`
    

    Now when we come to 3, we'll find `pin[syscalls[2].sysno] != 0` since `syscalls[2].sysno == syscalls[0].sysno` - so we set `pin[1] = -1` instead of `0x9abc`.

    • Oh, thanks, now I understand why there is an if in the for loop! But I still can't see how pin[] could be accessed out of bounds, since the array is allocated to be large enough to hold the largest value of .sysno occurring in the entries[] array.

      2 replies →