nfc-emulate-forum-tag4: fix TOCTOU

Hopefully fix TOCTOU by calling fopen() before stat()

At least this should prevent Coverity to complain about it:
CID 1090346 (#1 of 1): Time of check time of use (TOCTOU)
  fs_check_call: Calling function "stat(char const *, struct stat *)" to perform check on "filename".
  toctou: Calling function "fopen(char const * restrict, char const * restrict)" that uses "filename" after a check function. This can cause a time-of-check, time-of-use race condition.

Note that it seems pretty hard to avoid completely:
https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use#Preventing_TOCTTOU
This commit is contained in:
Philippe Teuwen 2013-09-22 02:29:07 +02:00
parent feb5f37aa3
commit 679897d0a1

View file

@ -255,14 +255,21 @@ static int
ndef_message_load(char *filename, struct nfcforum_tag4_ndef_data *tag_data) ndef_message_load(char *filename, struct nfcforum_tag4_ndef_data *tag_data)
{ {
struct stat sb; struct stat sb;
FILE *F;
if (!(F = fopen(filename, "r"))) {
printf("File not found or not accessible '%s'\n", filename);
return -1;
}
if (stat(filename, &sb) < 0) { if (stat(filename, &sb) < 0) {
printf("file not found or not accessible '%s'", filename); printf("File not found or not accessible '%s'\n", filename);
fclose(F);
return -1; return -1;
} }
/* Check file size */ /* Check file size */
if (sb.st_size > 0xFFFF) { if (sb.st_size > 0xFFFF) {
printf("file size too large '%s'", filename); printf("File size too large '%s'\n", filename);
fclose(F);
return -1; return -1;
} }
@ -271,14 +278,9 @@ ndef_message_load(char *filename, struct nfcforum_tag4_ndef_data *tag_data)
tag_data->ndef_file[0] = (uint8_t)(sb.st_size >> 8); tag_data->ndef_file[0] = (uint8_t)(sb.st_size >> 8);
tag_data->ndef_file[1] = (uint8_t)(sb.st_size); tag_data->ndef_file[1] = (uint8_t)(sb.st_size);
FILE *F;
if (!(F = fopen(filename, "r"))) {
printf("fopen (%s, \"r\")", filename);
return -1;
}
if (1 != fread(tag_data->ndef_file + 2, sb.st_size, 1, F)) { if (1 != fread(tag_data->ndef_file + 2, sb.st_size, 1, F)) {
printf("Can't read from %s", filename); printf("Can't read from %s\n", filename);
fclose(F); fclose(F);
return -1; return -1;
} }
@ -292,12 +294,12 @@ ndef_message_save(char *filename, struct nfcforum_tag4_ndef_data *tag_data)
{ {
FILE *F; FILE *F;
if (!(F = fopen(filename, "w"))) { if (!(F = fopen(filename, "w"))) {
printf("fopen (%s, w)", filename); printf("fopen (%s, w)\n", filename);
return -1; return -1;
} }
if (1 != fwrite(tag_data->ndef_file + 2, tag_data->ndef_file_len - 2, 1, F)) { if (1 != fwrite(tag_data->ndef_file + 2, tag_data->ndef_file_len - 2, 1, F)) {
printf("fwrite (%d)", (int) tag_data->ndef_file_len - 2); printf("fwrite (%d)\n", (int) tag_data->ndef_file_len - 2);
fclose(F); fclose(F);
return -1; return -1;
} }
@ -381,7 +383,7 @@ main(int argc, char *argv[])
// If some file is provided load it // If some file is provided load it
if (argc >= (2 + options)) { if (argc >= (2 + options)) {
if (ndef_message_load(argv[1 + options], &nfcforum_tag4_data) < 0) { if (ndef_message_load(argv[1 + options], &nfcforum_tag4_data) < 0) {
printf("Can't load NDEF file '%s'", argv[1 + options]); printf("Can't load NDEF file '%s'\n", argv[1 + options]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }