Skip to content

Commit ab93a0a

Browse files
committed
Read fru header into struct and check for errors
1 parent 7a40499 commit ab93a0a

File tree

3 files changed

+59
-40
lines changed

3 files changed

+59
-40
lines changed

fru_reader.c

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,42 @@
44
#include "fru_reader.h"
55
#include "fatal.h"
66

7-
void safe_read(int fd, void *buffer, size_t length) {
7+
static void safe_read(int fd, void *buffer, size_t length) {
88
size_t total_bytes_read = 0;
99
while (total_bytes_read != length) {
1010
ssize_t bytes_read = read(
1111
fd, buffer + total_bytes_read, length - total_bytes_read);
1212
if (bytes_read == -1)
1313
fatal("Error reading file");
14+
if (bytes_read == 0)
15+
fatal("Reached end of file");
1416

1517
total_bytes_read += bytes_read;
1618
}
1719
}
1820

21+
fru_t *read_fru_header(int fd) {
22+
fru_t *fru = malloc(sizeof(fru_t));
23+
if (!fru)
24+
return NULL;
25+
safe_read(fd, fru, sizeof(fru_t));
26+
return fru;
27+
}
28+
1929
/**
2030
* Allocate and read a fru_chassis_area_t from a file descriptor
2131
*/
2232
fru_chassis_area_t *read_fru_chassis_area(int fd) {
2333
size_t base_len = sizeof(fru_chassis_area_t);
2434
fru_chassis_area_t *area = malloc(base_len);
35+
if (!area)
36+
return NULL;
2537
safe_read(fd, area, base_len);
2638
size_t data_len = 8 * area->blocks;
27-
area = realloc(area, base_len + data_len);
28-
safe_read(fd, &area->data, data_len);
39+
area = realloc(area, data_len);
40+
if (!area)
41+
return NULL;
42+
safe_read(fd, &area->data, data_len - base_len);
2943

3044
return area;
3145
}
@@ -36,10 +50,14 @@ fru_chassis_area_t *read_fru_chassis_area(int fd) {
3650
fru_board_area_t *read_fru_board_area(int fd) {
3751
size_t base_len = sizeof(fru_board_area_t);
3852
fru_board_area_t *area = malloc(base_len);
53+
if (!area)
54+
return NULL;
3955
safe_read(fd, area, base_len);
4056
size_t data_len = 8 * area->blocks;
41-
area = realloc(area, base_len + data_len);
42-
safe_read(fd, &area->data, data_len);
57+
area = realloc(area, data_len);
58+
if (!area)
59+
return NULL;
60+
safe_read(fd, &area->data, data_len - base_len);
4361

4462
return area;
4563
}
@@ -50,10 +68,14 @@ fru_board_area_t *read_fru_board_area(int fd) {
5068
fru_product_area_t *read_fru_product_area(int fd) {
5169
size_t base_len = sizeof(fru_product_area_t);
5270
fru_product_area_t *area = malloc(base_len);
71+
if (!area)
72+
return NULL;
5373
safe_read(fd, area, base_len);
5474
size_t data_len = 8 * area->blocks;
55-
area = realloc(area, base_len + data_len);
56-
safe_read(fd, &area->data, data_len);
75+
area = realloc(area, data_len);
76+
if (!area)
77+
return NULL;
78+
safe_read(fd, &area->data, data_len - base_len);
5779

5880
return area;
5981
}

fru_reader.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "fru.h"
2+
fru_t *read_fru_header(int fd);
23
fru_chassis_area_t *read_fru_chassis_area(int fd);
34
fru_board_area_t *read_fru_board_area(int fd);
45
fru_product_area_t *read_fru_product_area(int fd);

frugen.c

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -476,57 +476,53 @@ int main(int argc, char *argv[])
476476
fatal("Failed to open file: %s", strerror(errno));
477477
}
478478

479-
char common_header[8];
480-
safe_read(fd, common_header, 8);
481-
482-
// Common Header Format Version = common_header[0]
483-
// Internal Use Area Starting Offset = common_header[1]
484-
uint16_t chassis_start_offset = 8 * common_header[2];
485-
uint16_t board_start_offset = 8 * common_header[3];
486-
uint16_t product_start_offset = 8 * common_header[4];
487-
// MultiRecord Area Starting Offset = 8 * common_header[5]
488-
// Padding = common_header[6] = 0
489-
// Checksum = common_header[7]
490-
491-
// For the above offsets, an offset of 0 is valid and implies
492-
// that the field is not present.
493-
494-
bool data_has_chassis = chassis_start_offset != 0;
495-
bool data_has_board = board_start_offset != 0;
496-
bool data_has_product = product_start_offset != 0;
497-
498-
if (data_has_chassis) {
499-
lseek(fd, chassis_start_offset, SEEK_SET);
500-
fru_chassis_area_t *chassis_raw =
501-
read_fru_chassis_area(fd);
502-
bool success = fru_decode_chassis_info(
503-
chassis_raw, &chassis);
504-
if (!success)
505-
fatal("Failed to decode chassis!");
506-
free(chassis_raw);
507-
479+
fru_t *raw_fru = read_fru_header(fd);
480+
if (!raw_fru)
481+
fatal("Failed to read fru header");
482+
483+
if (raw_fru->chassis != 0) {
484+
if (lseek(fd, 8 * raw_fru->chassis, SEEK_SET) < 0)
485+
fatal("Failed to seek");
486+
487+
fru_chassis_area_t *chassis_raw =
488+
read_fru_chassis_area(fd);
489+
bool success = fru_decode_chassis_info(
490+
chassis_raw, &chassis);
491+
if (!success)
492+
fatal("Failed to decode chassis");
493+
494+
free(chassis_raw);
508495
has_chassis = true;
509496
}
510-
if (data_has_board) {
511-
lseek(fd, board_start_offset, SEEK_SET);
497+
if (raw_fru->board != 0) {
498+
if(lseek(fd, 8 * raw_fru->board, SEEK_SET) < 0)
499+
fatal("Failed to seek");
512500

513501
fru_board_area_t *board_raw = read_fru_board_area(fd);
514502
bool success = fru_decode_board_info(board_raw, &board);
503+
if (!success)
504+
fatal("Failed to decode board");
515505

506+
free(board_raw);
516507
has_board = true;
517508
has_bdate = true;
518509
}
519-
if (data_has_product) {
520-
lseek(fd, product_start_offset, SEEK_SET);
510+
if (raw_fru->product != 0) {
511+
if (lseek(fd, 8 * raw_fru->product, SEEK_SET) < 0)
512+
fatal("Failed to seek");
521513

522514
fru_product_area_t *product_raw =
523515
read_fru_product_area(fd);
524516
bool success =
525517
fru_decode_product_info(product_raw, &product);
518+
if (!success)
519+
fatal("Failed to decode product");
526520

521+
free(product_raw);
527522
has_product = true;
528523
}
529524

525+
free(raw_fru);
530526
close(fd);
531527
}
532528
else {

0 commit comments

Comments
 (0)