0

I was running some mutation tests on this C-testsuite. One of my mutations caused the following test 00143 to either seg fault, or to run to completion with a stack smashing detected error. My mutation changed n = (count+7) / 8; to n = (count+7) * 8;

I have posted the mutated code below:

#include <stdio.h>
int main()
{
    int  count, n;
    short *from, *to;
    short a[39], b[39];

    for(n = 0; n < 39; n++) {
        a[n] = n;
        b[n] = 0;
    }
    from = a;
    to = b;
    count = 39;
    n = (count + 7) * 8;
    switch (count % 8) {
    case 0: do { *to++ = *from++;
    case 7:      *to++ = *from++;
    case 6:      *to++ = *from++;
    case 5:      *to++ = *from++;
    case 4:      *to++ = *from++;
    case 3:      *to++ = *from++;
    case 2:      *to++ = *from++;
    case 1:      *to++ = *from++;
            } while (--n > 0);
    }
    for(n = 0; n < 39; n++)
        if(a[n] != b[n])
            return 1;
    return 0;
}

You can see that n should not go out of bounds as the last for loop is between 0 <= n < 39.

My question is why does a segmentation fault, or stack smashing occur if I am not accessing out of bound arrays? Additionally why do I get flaky behavior?

Tim
  • 19
  • 3
  • C doesn't always detect buffer overflows. – Barmar Mar 24 '22 at 18:57
  • @Barmar I was interested in looking further into this, and I noticed that if I print out `n` in the final for loop, `n` never goes out of bounds. Why do you think this is a buffer overflow error? More specifically you can see that `a` and `b` are both arrays of length 39, and the final for loop goes from `0->39`. – Watchdog101 Mar 25 '22 at 17:38
  • 3
    n starts at 368, and then you increase to and from 368*8 times. You’re WAY out of your stack (in the while loop: this is a duff’s device) – Max Mar 25 '22 at 18:38
  • 2
    Try printing `to - b` every time through the loop, see if it goes above 39. – Barmar Mar 25 '22 at 18:46
  • There is **NO** `break` statement in your `switch()` so you experience case *fall-through* incrementing `to` and `from` 8-times per-iteration. – David C. Rankin Apr 13 '22 at 04:00
  • 1
    @DavidC.Rankin this is intended. Read about duff’s device. – paladin Apr 13 '22 at 06:33
  • 1
    I vote to close because you ARE accessing out of bounds. – the busybee Apr 13 '22 at 06:36
  • @paladin - granted, it may be intended, but if you switch on `0`, you will `to++` and `from++` 8 times, for `7`, 7 times -- with the logical result more than 39 time taking you out of bounds before all iterations are complete. – David C. Rankin Apr 13 '22 at 06:52
  • Thats true @DavidC.Rankin OP is just changing some values in his program and thinks he can get any meaningful answer from that. He's like changing a `for(int i = 0; i < 10; i++)` to a `for(int i = 0; i < 10; i--)` and is wondering why it doesn't work anymore. – paladin Apr 13 '22 at 10:13

0 Answers0