Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Use of uninitialized memory in s2n_aead_aes_test #150

@pascal-cuoq

Description

@pascal-cuoq

Here are the contents, in symbolic form, of the char array pointed to by conn->in.blob.data at the time when the line https://github.com/awslabs/s2n/blob/09261380262fca884567b941897ae3f095f55aad/tests/unit/s2n_aead_aes_test.c#L154 is reached:

[0..7] ∈ {0}
[bits 64 to 127] ∈ {4533304577153303563}
[bits 128 to 191] ∈ {1703996142823241576}
[24] ∈ {62}
[25] ∈ {31}
[26] ∈ {98}
[27] ∈ {216}
[bits 224 to 287] ∈ {10729224154281305815}
[bits 288 to 351] ∈ {3412835101196934063}
[44..1434] ∈ UNINITIALIZED

In the symbolic representation of the contents above, some values are integers wider than 8-bit. These values are represented as bit ranges, e.g. “bits 64 to 127”. When “bits” does not appear, it means the indices can be interpreted as indices into a char array. In other words, the first 44 bytes of that dynamically allocated memory zone are initialized to some numbers, and the rest is uninitialized, up to the index 1434.

conn->in.blob.size contains 1435, which is consistent with the size of the zone pointed to by conn->in.blob.data.

The line 154 attempts to access the last byte (and then the 15 bytes before that) with respect to the end of the character array. These characters are uninitialized. I am surprised that the test even works as you wanted.

Perhaps you mean to do something to the last bytes of the message, which in this case seems to be 44-byte long?

One word of warning: the tool we use stops at the first error (it is theoretically impossible to predict what happens in a C program after the first undefined behavior), so the same code pattern leading to using uninitialized memory may happen again later in the test.

Off-topic: in #146 there was the question:

I wonder why -Wuninitialized doesn't catch it.

I wouldn't expect a compiler to warn about the following program, where the local variable being left uninitialized and the function where it is used are different.

void g(int *p) {
  static int s;
  s = 1 + *p;
}

int main(){
  int l;
  g(&l);
}

There are analyses that can find this use of uninitialized memory across function calls, but these are more expensive than a compiler can afford to run in the few seconds the user allows it when the user launches compilation.

In the issue 146, the two functions were in different files, so because of separate compilation, even an ideal compiler that somehow could afford this kind of analysis would not be able to warn for either file.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions