5

I find a run-time error in GNU Scientific Library (GSL) when undefined sanitizer is enabled:

deque.c:58:11: runtime error: member access within misaligned address 0x0000024010f4 for type 'struct deque', which requires 8 byte alignment
0x0000024010f4: note: pointer points here
  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
              ^ 
deque.c:59:11: runtime error: member access within misaligned address 0x0000024010f4 for type 'struct deque', which requires 8 byte alignment
0x0000024010f4: note: pointer points here
  00 00 00 00 ff ff ff ff  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
              ^ 
deque.c:60:11: runtime error: member access within misaligned address 0x0000024010f4 for type 'struct deque', which requires 8 byte alignment
0x0000024010f4: note: pointer points here
  00 00 00 00 ff ff ff ff  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
              ^ 
deque.c:61:12: runtime error: member access within misaligned address 0x0000024010f4 for type 'struct deque', which requires 8 byte alignment
0x0000024010f4: note: pointer points here
  00 00 00 00 ff ff ff ff  00 00 00 00 05 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
              ^ 

But I have no idea how to the cause of these errors, or how to fix them. Can someone help explain? Besides, Is it an important issue that should be raised to developers (e.g. could this bee exploited as security attacks)?

The source code "deque.c" can be found here, with relevant lines of runtime errors shown below (the errors occur in lines 58,59,60,61).

enter image description here

And the definition of deque is here, in the same file:

here

[ADDED] The code invoking deque_init is below, in mmacc.c of GSL's movstat library:

static int
mmacc_init(const size_t n, void * vstate)
{
  mmacc_state_t * state = (mmacc_state_t *) vstate;

  state->n = n;
  state->k = 0;
  state->xprev = 0.0;

  state->rbuf = (ringbuf *) ((unsigned char *) vstate + sizeof(mmacc_state_t));
  state->minque = (deque *) ((unsigned char *) state->rbuf + ringbuf_size(n));
  state->maxque = (deque *) ((unsigned char *) state->minque + deque_size(n + 1));

  ringbuf_init(n, state->rbuf);
  deque_init(n + 1, state->minque);
  deque_init(n + 1, state->maxque);

  return GSL_SUCCESS;
}

The ringbuf_size function in the code above refers to the following code in ringbuf.c of the movstat library of GSL.

static size_t
ringbuf_size(const size_t n)
{
  size_t size = 0;

  size += sizeof(ringbuf);
  size += n * sizeof(ringbuf_type_t); /* b->array */

  return size;
}
zell
  • 9,830
  • 10
  • 62
  • 115
  • 1
    The code shown is only tangentially relevant. What matters is the code where `deque_init()` is called. Why is that code passing in a misaligned address to the function? Also, you should post the code in the question, not images of the code. – Jonathan Leffler Dec 27 '20 at 08:55
  • @JonathanLeffler Please see my edits above. Thanks for the nice suggestion. – zell Dec 30 '20 at 22:03

1 Answers1

3

I'm not too familiar with the library, but here's the reason why you get the error.

deque.c:58:11: runtime error: member access within misaligned address 0x0000024010f4 for type 'struct deque', which requires 8 byte alignment
0x0000024010f4: note: pointer points here
  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
              ^ 

We can see, that indeed, pointer is shifted by 4. Let's figure out why.

The pointer comes from

state->minque = (deque *) ((unsigned char *) state->rbuf + ringbuf_size(n));

From this we can judge that either state->rbuf is misaligned or ringbuf_size returns value which is not aligned to 8. With a quick test, we can see, that indeed, ringbuf_size returns not aligned values. With a simple program I printed n, sizeof(ringbuf), n * sizeof(ringbuf_type_t) and final result.

0 24 + 0 = 24
1 24 + 4 = 28
2 24 + 8 = 32
3 24 + 12 = 36
4 24 + 16 = 40
5 24 + 20 = 44
6 24 + 24 = 48
7 24 + 28 = 52
8 24 + 32 = 56
9 24 + 36 = 60
10 24 + 40 = 64
11 24 + 44 = 68
12 24 + 48 = 72
13 24 + 52 = 76
14 24 + 56 = 80
15 24 + 60 = 84

As you can see, if you use odd number as size, then you get misaligned pointer (in your case it was 5). The reason being:

sizeof(size_t) = 8
sizeof(ringbuf_type_t) = 4

Example fix could be to add

size += (size % sizeof(size_t));

in ringbuf_size function. That way, the result changes to:

0 24 + 0 = 24
1 24 + 4 = 32
2 24 + 8 = 32
3 24 + 12 = 40
4 24 + 16 = 40
5 24 + 20 = 48
6 24 + 24 = 48
7 24 + 28 = 56
8 24 + 32 = 56
9 24 + 36 = 64
10 24 + 40 = 64
11 24 + 44 = 72
12 24 + 48 = 72
13 24 + 52 = 80
14 24 + 56 = 80
15 24 + 60 = 88
BonusPlay
  • 141
  • 4
  • Thank you very much for your detailed analysis. You said "With a simple program I printed n, sizeof(ringbuf), n * sizeof(ringbuf_type_t) and final result." Would you share your program to us? Does your program invoke GSL? – zell Jan 05 '21 at 09:12
  • You also said "From this we can judge that either state->rbuf is misaligned or ringbuf_size returns value which is not aligned to 8." in general, if a= b+c, a can be a multiple of 8 while neither b or c is a multiple of 8, e.g., 16=14+2. So I guess you would not draw this conclusion. – zell Jan 05 '21 at 10:50
  • 1) The program was written in C++, it's available [here](https://repl.it/@BonusPlay/WrithingGiganticEngineering). I just copied minimal amount of declarations to make it work. 2) In theory you're right, it could have happened that both of those are misaligned, however `state->rbuf` is set to `state + sizeof(mmacc_state_t)`, which sounded perfectly normal to me. You are right though, my explaination wasn't clear. – BonusPlay Jan 05 '21 at 20:41