Here is an example, considering a smaller (empty) 70 char buffer: ...................................................................... For simplicity, we'll note messages as their sequence number (artificially starting at one), empty area as dots and zeroed area as zero and consider that the header is only one char. This does not change anything in the logic but simplifies the schema. Let's start by filling the buffers with some messages: 1111112222222222222333333344444444455555555555666666667777............ At that moment, we have: log_first_seq = 1, log_next_seq = 8 log_first_idx = 0, log_next_idx = 58 Let's now starts a reader, which will read everything and wait with: seq = 8, idx = 58 Due to scheduling/reader choice, the reader now stops. A 20 character-long message arrives. The buffers removes messages from before and wraps arround: 88888888888888888883333333444444444555555555556666666677770........... And we now have: log_first_seq = 3, log_next_seq = 9 log_first_idx = 20, log_next_idx = 20 Let's continue filling the buffer, without wrapping: 88888888888888888889999999999999999999aaaaaaaaaaaaabbbbbbbbbbbbbb..... We now have: log_first_seq = 8, log_next_seq = 0xc log_first_idx = 0, log_next_idx = 65 And now the reader restarts, it still have the same sequence number, '8' As `seq < log_first_seq` is false, it will consider that this message is valid and continue. Unfortunately, it's first action will be `log_from_idx(idx)`, which will first try to read the header of the message at the offset `idx`. This header, which was supposed to be zeroed due to the wrap-around, has now been overritten and thus contain random junk, which might ultimately lead to a kernel panic (wrong memory access from the reader). As I understand it, the underlying problem is that the zeroed-header is not properly protected by the sequence number cheks.