tpm: eventlog: Replace zero-length array with flexible-array member
Subsystems (2)
PATCH v2 1/1 tpm: eventlog: Replace zero-length array with flexible-array member
The current codebase makes use of the zero-length array language extension to the C90 standard, but the preferred mechanism to declare variable-length types such as these ones is a flexible array member[1][2], introduced in C99:
struct foo {
int stuff;
struct boo array[];
};By making use of the mechanism above, we will get a compiler warning in case the flexible array does not occur last in the structure, which will help us prevent some kind of undefined behavior bugs from being inadvertently introduced[3] to the codebase from now on.
Also, notice that, dynamic memory allocations won't be affected by this change:
"Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1]
sizeof(flexible-array-member) triggers a warning because flexible array members have incomplete type[1]. There are some instances of code in which the sizeof operator is being incorrectly/erroneously applied to zero-length arrays and the result is zero. Such instances may be hiding some bugs. So, this work (flexible-array member conversions) will also help to get completely rid of those sorts of issues.
Also, the following issue shows up due to the flexible-array member having incomplete type[4]:
drivers/char/tpm/eventlog/tpm2.c: In function ‘tpm2_bios_measurements_start’:drivers/char/tpm/eventlog/tpm2.c:54:46: error: invalid application of ‘sizeof’ to incomplete type ‘u8[]’ {aka ‘unsigned char[]’}
54 | size = sizeof(struct tcg_pcr_event) - sizeof(event_header->event)
| ^drivers/char/tpm/eventlog/tpm2.c: In function ‘tpm2_bios_measurements_next’:drivers/char/tpm/eventlog/tpm2.c:102:10: error: invalid application of ‘sizeof’ to incomplete type ‘u8[]’ {aka ‘unsigned char[]’}
102 | sizeof(event_header->event) + event_header->event_size;
| ^drivers/char/tpm/eventlog/tpm2.c: In function ‘tpm2_binary_bios_measurements_show’:drivers/char/tpm/eventlog/tpm2.c:140:10: error: invalid application of ‘sizeof’ to incomplete type ‘u8[]’ {aka ‘unsigned char[]’}
140 | sizeof(event_header->event) + event_header->event_size;
| ^scripts/Makefile.build:266: recipe for target 'drivers/char/tpm/eventlog/tpm2.o' failed
make[3]: *** [drivers/char/tpm/eventlog/tpm2.o] Error 1
As mentioned above: "Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1] As in "sizeof(event_header->event) always evaluated to 0, so removing it has no effect".
Lastly, make use of the struct_size() helper to deal with the flexible array member and its host structure.
This issue was found with the help of Coccinelle.
[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] https://github.com/KSPP/linux/issues/21
[3] commit 76497732932f ("cxgb3/l2t: Fix undefined behaviour")
[4] https://github.com/KSPP/linux/issues/43
---
Changes in v2:
- Update changelog text.
- Make use of the struct_size() helper.
drivers/char/tpm/eventlog/tpm2.c | 12 +++++------- include/linux/tpm_eventlog.h | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-)
drivers/char/tpm/eventlog/tpm2.c +5 -7
@@ -51,8 +51,7 @@ static void *tpm2_bios_measurements_start(struct seq_file *m, loff_t *pos)int i; event_header = addr; - size =sizeof (struct tcg_pcr_event ) -sizeof (event_header->event) - + event_header->event_size; + size =struct_size (event_header, event, event_header->event_size);if (*pos ==0 ) {if (addr + size < limit) {
@@ -98,8 +97,8 @@ static void *tpm2_bios_measurements_next(struct seq_file *m, void *v, event_header = log->bios_event_log;if (v ==SEQ_START_TOKEN ) { - event_size =sizeof (struct tcg_pcr_event ) - -sizeof (event_header->event) + event_header->event_size; + event_size =struct_size (event_header, event, + event_header->event_size); marker = event_header; }else { event = v;
@@ -136,9 +135,8 @@ static int tpm2_binary_bios_measurements_show(struct seq_file *m, void *v)size_t size;if (v ==SEQ_START_TOKEN ) { - size =sizeof (struct tcg_pcr_event ) - -sizeof (event_header->event) + event_header->event_size; - + size =struct_size (event_header, event, + event_header->event_size); temp_ptr = event_header;if (size >0 )
include/linux/tpm_eventlog.h +1 -1
@@ -97,7 +97,7 @@ struct tcg_pcr_event {u32 event_type;u8 digest[20 ];u32 event_size; -u8 event[0 ]; +u8 event[]; } __packed;struct tcg_event_field {
Signature · 1 line
2.26.2
Quoted 56 lines · Gustavo A. R. Silva
The current codebase makes use of the zero-length array language extension to the C90 standard, but the preferred mechanism to declare variable-length types such as these ones is a flexible array member[1][2], introduced in C99:
struct foo { int stuff; struct boo array[]; };By making use of the mechanism above, we will get a compiler warning in case the flexible array does not occur last in the structure, which will help us prevent some kind of undefined behavior bugs from being inadvertently introduced[3] to the codebase from now on.
Also, notice that, dynamic memory allocations won't be affected by this change:
"Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1]
sizeof(flexible-array-member) triggers a warning because flexible array members have incomplete type[1]. There are some instances of code in which the sizeof operator is being incorrectly/erroneously applied to zero-length arrays and the result is zero. Such instances may be hiding some bugs. So, this work (flexible-array member conversions) will also help to get completely rid of those sorts of issues.
Also, the following issue shows up due to the flexible-array member having incomplete type[4]:
drivers/char/tpm/eventlog/tpm2.c: In function ‘tpm2_bios_measurements_start’:drivers/char/tpm/eventlog/tpm2.c:54:46: error: invalid application of ‘sizeof’ to incomplete type ‘u8[]’ {aka ‘unsigned char[]’}
54 | size =sizeof(struct tcg_pcr_event)-sizeof(event_header->event)
| ^drivers/char/tpm/eventlog/tpm2.c: In function ‘tpm2_bios_measurements_next’:drivers/char/tpm/eventlog/tpm2.c:102:10: error: invalid application of ‘sizeof’ to incomplete type ‘u8[]’ {aka ‘unsigned char[]’}
102 |sizeof(event_header->event)+event_header->event_size;
| ^drivers/char/tpm/eventlog/tpm2.c: In function ‘tpm2_binary_bios_measurements_show’:drivers/char/tpm/eventlog/tpm2.c:140:10: error: invalid application of ‘sizeof’ to incomplete type ‘u8[]’ {aka ‘unsigned char[]’}
140 |sizeof(event_header->event)+event_header->event_size;
| ^scripts/Makefile.build:266: recipe for target 'drivers/char/tpm/eventlog/tpm2.o' failed
make[3]: *** [drivers/char/tpm/eventlog/tpm2.o] Error 1As mentioned above: "Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1] As in "
sizeof(event_header->event)always evaluated to 0, so removing it has no effect".Lastly, make use of the
struct_size()helper to deal with the flexible array member and its host structure.
Quoted 8 lines
This issue was found with the help of Coccinelle.
[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] https://github.com/KSPP/linux/issues/21
[3] commit76497732932f("cxgb3/l2t: Fix undefined behaviour")
[4] https://github.com/KSPP/linux/issues/43Signed-off-by Gustavo A. R. Silva <[email protected]>
Signature · 1 line
Kees Cook
Quoted 59 lines · Kees Cook
Quoted 58 lines · Gustavo A. R. Silva
The current codebase makes use of the zero-length array language extension to the C90 standard, but the preferred mechanism to declare variable-length types such as these ones is a flexible array member[1][2], introduced in C99:
struct foo { int stuff; struct boo array[]; };By making use of the mechanism above, we will get a compiler warning in case the flexible array does not occur last in the structure, which will help us prevent some kind of undefined behavior bugs from being inadvertently introduced[3] to the codebase from now on.
Also, notice that, dynamic memory allocations won't be affected by this change:
"Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1]
sizeof(flexible-array-member) triggers a warning because flexible array members have incomplete type[1]. There are some instances of code in which the sizeof operator is being incorrectly/erroneously applied to zero-length arrays and the result is zero. Such instances may be hiding some bugs. So, this work (flexible-array member conversions) will also help to get completely rid of those sorts of issues.
Also, the following issue shows up due to the flexible-array member having incomplete type[4]:
drivers/char/tpm/eventlog/tpm2.c: In function ‘tpm2_bios_measurements_start’:drivers/char/tpm/eventlog/tpm2.c:54:46: error: invalid application of ‘sizeof’ to incomplete type ‘u8[]’ {aka ‘unsigned char[]’}
54 | size =sizeof(struct tcg_pcr_event)-sizeof(event_header->event)
| ^drivers/char/tpm/eventlog/tpm2.c: In function ‘tpm2_bios_measurements_next’:drivers/char/tpm/eventlog/tpm2.c:102:10: error: invalid application of ‘sizeof’ to incomplete type ‘u8[]’ {aka ‘unsigned char[]’}
102 |sizeof(event_header->event)+event_header->event_size;
| ^drivers/char/tpm/eventlog/tpm2.c: In function ‘tpm2_binary_bios_measurements_show’:drivers/char/tpm/eventlog/tpm2.c:140:10: error: invalid application of ‘sizeof’ to incomplete type ‘u8[]’ {aka ‘unsigned char[]’}
140 |sizeof(event_header->event)+event_header->event_size;
| ^scripts/Makefile.build:266: recipe for target 'drivers/char/tpm/eventlog/tpm2.o' failed
make[3]: *** [drivers/char/tpm/eventlog/tpm2.o] Error 1As mentioned above: "Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1] As in "
sizeof(event_header->event)always evaluated to 0, so removing it has no effect".Lastly, make use of the
struct_size()helper to deal with the flexible array member and its host structure.This issue was found with the help of Coccinelle.
Quoted 9 lines
Quoted 6 lines
[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] https://github.com/KSPP/linux/issues/21
[3] commit76497732932f("cxgb3/l2t: Fix undefined behaviour")
[4] https://github.com/KSPP/linux/issues/43Signed-off-by Gustavo A. R. Silva <[email protected]>Reviewed-by Kees Cook <[email protected]>
Thanks, Kees.
--
Gustavo
Jarkko Sakkinen
AppliedQuoted 59 lines · Kees Cook
Quoted 58 lines · Gustavo A. R. Silva
The current codebase makes use of the zero-length array language extension to the C90 standard, but the preferred mechanism to declare variable-length types such as these ones is a flexible array member[1][2], introduced in C99:
struct foo { int stuff; struct boo array[]; };By making use of the mechanism above, we will get a compiler warning in case the flexible array does not occur last in the structure, which will help us prevent some kind of undefined behavior bugs from being inadvertently introduced[3] to the codebase from now on.
Also, notice that, dynamic memory allocations won't be affected by this change:
"Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1]
sizeof(flexible-array-member) triggers a warning because flexible array members have incomplete type[1]. There are some instances of code in which the sizeof operator is being incorrectly/erroneously applied to zero-length arrays and the result is zero. Such instances may be hiding some bugs. So, this work (flexible-array member conversions) will also help to get completely rid of those sorts of issues.
Also, the following issue shows up due to the flexible-array member having incomplete type[4]:
drivers/char/tpm/eventlog/tpm2.c: In function ‘tpm2_bios_measurements_start’:drivers/char/tpm/eventlog/tpm2.c:54:46: error: invalid application of ‘sizeof’ to incomplete type ‘u8[]’ {aka ‘unsigned char[]’}
54 | size =sizeof(struct tcg_pcr_event)-sizeof(event_header->event)
| ^drivers/char/tpm/eventlog/tpm2.c: In function ‘tpm2_bios_measurements_next’:drivers/char/tpm/eventlog/tpm2.c:102:10: error: invalid application of ‘sizeof’ to incomplete type ‘u8[]’ {aka ‘unsigned char[]’}
102 |sizeof(event_header->event)+event_header->event_size;
| ^drivers/char/tpm/eventlog/tpm2.c: In function ‘tpm2_binary_bios_measurements_show’:drivers/char/tpm/eventlog/tpm2.c:140:10: error: invalid application of ‘sizeof’ to incomplete type ‘u8[]’ {aka ‘unsigned char[]’}
140 |sizeof(event_header->event)+event_header->event_size;
| ^scripts/Makefile.build:266: recipe for target 'drivers/char/tpm/eventlog/tpm2.o' failed
make[3]: *** [drivers/char/tpm/eventlog/tpm2.o] Error 1As mentioned above: "Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1] As in "
sizeof(event_header->event)always evaluated to 0, so removing it has no effect".Lastly, make use of the
struct_size()helper to deal with the flexible array member and its host structure.This issue was found with the help of Coccinelle.
Quoted 8 lines
Quoted 6 lines
[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] https://github.com/KSPP/linux/issues/21
[3] commit76497732932f("cxgb3/l2t: Fix undefined behaviour")
[4] https://github.com/KSPP/linux/issues/43Signed-off-by Gustavo A. R. Silva <[email protected]>Reviewed-by Kees Cook <[email protected]>
Thank you.
I applied this patch, will include it to the next PR.
/Jarkko
Quoted 9 lines · Jarkko Sakkinen
Quoted 4 lines
Quoted 2 lines
Signed-off-by Gustavo A. R. Silva <[email protected]>Reviewed-by Kees Cook <[email protected]>Thank you.
I applied this patch, will include it to the next PR.
Awesome. :)
Thanks, Jarkko.
--
Gustavo
Quoted 11 lines · Gustavo A. R. Silva
Quoted 8 lines · Jarkko Sakkinen
Quoted 3 lines
Quoted 1 line
Signed-off-by Gustavo A. R. Silva <[email protected]>Reviewed-by Kees Cook <[email protected]>Thank you.
I applied this patch, will include it to the next PR.
Awesome. :)
NP, sorry for the latencies!
Right now SGX is very near getting pulled. That might cause some *temporary* latencies in my review queue during the phase of this month and maybe early next month. After that things should return to normal.
/Jarkko
Quoted 56 lines · Gustavo A. R. Silva
The current codebase makes use of the zero-length array language extension to the C90 standard, but the preferred mechanism to declare variable-length types such as these ones is a flexible array member[1][2], introduced in C99:
struct foo { int stuff; struct boo array[]; };By making use of the mechanism above, we will get a compiler warning in case the flexible array does not occur last in the structure, which will help us prevent some kind of undefined behavior bugs from being inadvertently introduced[3] to the codebase from now on.
Also, notice that, dynamic memory allocations won't be affected by this change:
"Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1]
sizeof(flexible-array-member) triggers a warning because flexible array members have incomplete type[1]. There are some instances of code in which the sizeof operator is being incorrectly/erroneously applied to zero-length arrays and the result is zero. Such instances may be hiding some bugs. So, this work (flexible-array member conversions) will also help to get completely rid of those sorts of issues.
Also, the following issue shows up due to the flexible-array member having incomplete type[4]:
drivers/char/tpm/eventlog/tpm2.c: In function ‘tpm2_bios_measurements_start’:drivers/char/tpm/eventlog/tpm2.c:54:46: error: invalid application of ‘sizeof’ to incomplete type ‘u8[]’ {aka ‘unsigned char[]’}
54 | size =sizeof(struct tcg_pcr_event)-sizeof(event_header->event)
| ^drivers/char/tpm/eventlog/tpm2.c: In function ‘tpm2_bios_measurements_next’:drivers/char/tpm/eventlog/tpm2.c:102:10: error: invalid application of ‘sizeof’ to incomplete type ‘u8[]’ {aka ‘unsigned char[]’}
102 |sizeof(event_header->event)+event_header->event_size;
| ^drivers/char/tpm/eventlog/tpm2.c: In function ‘tpm2_binary_bios_measurements_show’:drivers/char/tpm/eventlog/tpm2.c:140:10: error: invalid application of ‘sizeof’ to incomplete type ‘u8[]’ {aka ‘unsigned char[]’}
140 |sizeof(event_header->event)+event_header->event_size;
| ^scripts/Makefile.build:266: recipe for target 'drivers/char/tpm/eventlog/tpm2.o' failed
make[3]: *** [drivers/char/tpm/eventlog/tpm2.o] Error 1As mentioned above: "Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1] As in "
sizeof(event_header->event)always evaluated to 0, so removing it has no effect".Lastly, make use of the
struct_size()helper to deal with the flexible array member and its host structure.
Quoted 8 lines
This issue was found with the help of Coccinelle.
[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] https://github.com/KSPP/linux/issues/21
[3] commit76497732932f("cxgb3/l2t: Fix undefined behaviour")
[4] https://github.com/KSPP/linux/issues/43Signed-off-by Gustavo A. R. Silva <[email protected]>
/Jarkko
Quoted 59 lines
---
Changes in v2:
- Update changelog text.
- Make use of thestruct_size()helper.drivers/char/tpm/eventlog/tpm2.c | 12 +++++------- include/linux/tpm_eventlog.h | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-)drivers/char/tpm/eventlog/tpm2.c +5
-7@@ -51,8 +51,7 @@ static void *tpm2_bios_measurements_start(struct seq_file *m, loff_t *pos)int i; event_header = addr; - size =sizeof (struct tcg_pcr_event ) -sizeof (event_header->event) - + event_header->event_size; + size =struct_size (event_header, event, event_header->event_size);if (*pos ==0 ) {if (addr + size < limit) {@@ -98,8 +97,8 @@ static void *tpm2_bios_measurements_next(struct seq_file *m, void *v, event_header = log->bios_event_log;if (v ==SEQ_START_TOKEN ) { - event_size =sizeof (struct tcg_pcr_event ) - -sizeof (event_header->event) + event_header->event_size; + event_size =struct_size (event_header, event, + event_header->event_size); marker = event_header; }else { event = v;@@ -136,9 +135,8 @@ static int tpm2_binary_bios_measurements_show(struct seq_file *m, void *v)size_t size;if (v ==SEQ_START_TOKEN ) { - size =sizeof (struct tcg_pcr_event ) - -sizeof (event_header->event) + event_header->event_size; - + size =struct_size (event_header, event, + event_header->event_size); temp_ptr = event_header;if (size >0 )include/linux/tpm_eventlog.h +1
-1@@ -97,7 +97,7 @@ struct tcg_pcr_event {u32 event_type;u8 digest[20 ];u32 event_size; -u8 event[0 ]; +u8 event[]; } __packed;struct tcg_event_field {