Skip to content

Commit f6d16b6

Browse files
sshedijohannbg
authored andcommitted
fix(skipcpio): improve error checking
Some other minor tweaks Signed-off-by: Shreenidhi Shedi <sshedi@vmware.com>
1 parent dfbfd33 commit f6d16b6

File tree

1 file changed

+106
-74
lines changed

1 file changed

+106
-74
lines changed

src/skipcpio/skipcpio.c

Lines changed: 106 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* dracut-install.c -- install files and executables
1+
/* skipcpio.c
22
33
Copyright (C) 2012 Harald Hoyer
44
Copyright (C) 2012 Red Hat, Inc. All rights reserved.
@@ -28,11 +28,18 @@
2828
#include <string.h>
2929

3030
#define CPIO_MAGIC "070701"
31+
3132
#define CPIO_END "TRAILER!!!"
3233
#define CPIO_ENDLEN (sizeof(CPIO_END) - 1)
3334

3435
#define CPIO_ALIGNMENT 4
3536

37+
#define ALIGN_UP(n, a) (((n) + (a) - 1) & (~((a) - 1)))
38+
39+
#define pr_err(fmt, ...) \
40+
fprintf(stderr, "ERROR: %s:%d:%s(): " fmt, __FILE__, __LINE__, \
41+
__func__, ##__VA_ARGS__)
42+
3643
struct cpio_header {
3744
char c_magic[6];
3845
char c_ino[8];
@@ -62,110 +69,135 @@ union buf_union {
6269

6370
static union buf_union buf;
6471

65-
#define ALIGN_UP(n, a) (((n) + (a) - 1) & (~((a) - 1)))
66-
6772
int main(int argc, char **argv)
6873
{
69-
FILE *f;
7074
size_t s;
75+
long pos = 0;
76+
FILE *f = NULL;
77+
char *fname = NULL;
78+
int ret = EXIT_FAILURE;
79+
unsigned long filesize;
80+
unsigned long filename_length;
7181

7282
if (argc != 2) {
7383
fprintf(stderr, "Usage: %s <file>\n", argv[0]);
74-
exit(1);
84+
goto end;
7585
}
7686

77-
f = fopen(argv[1], "r");
78-
87+
fname = argv[1];
88+
f = fopen(fname, "r");
7989
if (f == NULL) {
80-
fprintf(stderr, "Cannot open file '%s'\n", argv[1]);
81-
exit(1);
90+
pr_err("Cannot open file '%s'\n", fname);
91+
goto end;
8292
}
8393

84-
s = fread(&buf.cpio, sizeof(buf.cpio), 1, f);
85-
if (s <= 0) {
86-
fprintf(stderr, "Read error from file '%s'\n", argv[1]);
87-
fclose(f);
88-
exit(1);
94+
if ((fread(&buf.cpio, sizeof(buf.cpio), 1, f) != 1) ||
95+
ferror(f)) {
96+
pr_err("Read error from file '%s'\n", fname);
97+
goto end;
8998
}
90-
fseek(f, 0, SEEK_SET);
91-
92-
/* check, if this is a cpio archive */
93-
if (memcmp(buf.cpio.h.c_magic, CPIO_MAGIC, 6) == 0) {
9499

95-
long pos = 0;
100+
if (fseek(f, 0, SEEK_SET)) {
101+
pr_err("fseek error on file '%s'\n", fname);
102+
goto end;
103+
}
96104

97-
unsigned long filesize;
98-
unsigned long filename_length;
105+
/* check, if this is a cpio archive */
106+
if (memcmp(buf.cpio.h.c_magic, CPIO_MAGIC, 6)) {
107+
goto cat_rest;
108+
}
99109

100-
do {
101-
// zero string, spilling into next unused field, to use strtol
102-
buf.cpio.h.c_chksum[0] = 0;
103-
filename_length = strtoul(buf.cpio.h.c_namesize, NULL, 16);
104-
pos = ALIGN_UP(pos + sizeof(struct cpio_header) + filename_length, CPIO_ALIGNMENT);
105-
106-
// zero string, spilling into next unused field, to use strtol
107-
buf.cpio.h.c_dev_maj[0] = 0;
108-
filesize = strtoul(buf.cpio.h.c_filesize, NULL, 16);
109-
pos = ALIGN_UP(pos + filesize, CPIO_ALIGNMENT);
110-
111-
if (filename_length == (CPIO_ENDLEN + 1)
112-
&& strncmp(buf.cpio.filename, CPIO_END, CPIO_ENDLEN) == 0) {
113-
fseek(f, pos, SEEK_SET);
114-
break;
110+
do {
111+
// zero string, spilling into next unused field, to use strtol
112+
buf.cpio.h.c_chksum[0] = 0;
113+
filename_length = strtoul(buf.cpio.h.c_namesize, NULL, 16);
114+
pos = ALIGN_UP(pos + sizeof(struct cpio_header) + filename_length, CPIO_ALIGNMENT);
115+
116+
// zero string, spilling into next unused field, to use strtol
117+
buf.cpio.h.c_dev_maj[0] = 0;
118+
filesize = strtoul(buf.cpio.h.c_filesize, NULL, 16);
119+
pos = ALIGN_UP(pos + filesize, CPIO_ALIGNMENT);
120+
121+
if (filename_length == (CPIO_ENDLEN + 1)
122+
&& strncmp(buf.cpio.filename, CPIO_END, CPIO_ENDLEN) == 0) {
123+
if (fseek(f, pos, SEEK_SET)) {
124+
pr_err("fseek\n");
125+
goto end;
115126
}
127+
break;
128+
}
116129

117-
if (fseek(f, pos, SEEK_SET) != 0) {
118-
perror("fseek");
119-
exit(1);
120-
}
130+
if (fseek(f, pos, SEEK_SET)) {
131+
pr_err("fseek\n");
132+
goto end;
133+
}
121134

122-
if (fread(&buf.cpio, sizeof(buf.cpio), 1, f) != 1) {
123-
perror("fread");
124-
exit(1);
125-
}
135+
if ((fread(&buf.cpio, sizeof(buf.cpio), 1, f) != 1) ||
136+
ferror(f)) {
137+
pr_err("fread\n");
138+
goto end;
139+
}
126140

127-
if (memcmp(buf.cpio.h.c_magic, CPIO_MAGIC, 6) != 0) {
128-
fprintf(stderr, "Corrupt CPIO archive!\n");
129-
exit(1);
130-
}
131-
} while (!feof(f));
141+
if (memcmp(buf.cpio.h.c_magic, CPIO_MAGIC, 6)) {
142+
pr_err("Corrupt CPIO archive!\n");
143+
goto end;
144+
}
145+
} while (!feof(f));
132146

133-
if (feof(f)) {
134-
/* CPIO_END not found, just cat the whole file */
135-
fseek(f, 0, SEEK_SET);
136-
} else {
137-
/* skip zeros */
138-
do {
139-
size_t i;
147+
if (feof(f)) {
148+
/* CPIO_END not found, just cat the whole file */
149+
if (fseek(f, 0, SEEK_SET)) {
150+
pr_err("fseek\n");
151+
goto end;
152+
}
153+
} else {
154+
/* skip zeros */
155+
do {
156+
size_t i;
140157

141-
s = fread(buf.copy_buffer, 1, sizeof(buf.copy_buffer) - 1, f);
142-
if (s <= 0)
143-
break;
158+
s = fread(buf.copy_buffer, 1, sizeof(buf.copy_buffer) - 1, f);
159+
if (ferror(f)) {
160+
pr_err("fread\n");
161+
goto end;
162+
}
144163

145-
for (i = 0; (i < s) && (buf.copy_buffer[i] == 0); i++) ;
164+
for (i = 0; (i < s) && (buf.copy_buffer[i] == 0); i++) ;
146165

147-
if (buf.copy_buffer[i] != 0) {
148-
pos += i;
166+
if (buf.copy_buffer[i]) {
167+
pos += i;
149168

150-
fseek(f, pos, SEEK_SET);
151-
break;
169+
if (fseek(f, pos, SEEK_SET)) {
170+
pr_err("fseek\n");
171+
goto end;
152172
}
173+
break;
174+
}
153175

154-
pos += s;
155-
} while (!feof(f));
156-
}
176+
pos += s;
177+
} while (!feof(f));
157178
}
179+
180+
cat_rest:
158181
/* cat out the rest */
159182
while (!feof(f)) {
160183
s = fread(buf.copy_buffer, 1, sizeof(buf.copy_buffer), f);
161-
if (s <= 0)
162-
break;
184+
if (ferror(f)) {
185+
pr_err("fread\n");
186+
goto end;
187+
}
163188

164-
s = fwrite(buf.copy_buffer, 1, s, stdout);
165-
if (s <= 0)
166-
break;
189+
if (fwrite(buf.copy_buffer, 1, s, stdout) != s) {
190+
pr_err("fwrite\n");
191+
goto end;
192+
}
193+
}
194+
195+
ret = EXIT_SUCCESS;
196+
197+
end:
198+
if (f) {
199+
fclose(f);
167200
}
168-
fclose(f);
169201

170-
return EXIT_SUCCESS;
202+
return ret;
171203
}

0 commit comments

Comments
 (0)