1 |
From a995e6bc0524450adfd6181dfdcd9d0520cfaba5 Mon Sep 17 00:00:00 2001 |
2 |
From: Masami Hiramatsu <mhiramat@kernel.org> |
3 |
Date: Thu, 19 Nov 2020 14:53:31 +0900 |
4 |
Subject: [PATCH 102/150] tools/bootconfig: Fix to check the write failure |
5 |
correctly |
6 |
|
7 |
Fix to check the write(2) failure including partial write |
8 |
correctly and try to rollback the partial write, because |
9 |
if there is no BOOTCONFIG_MAGIC string, we can not remove it. |
10 |
|
11 |
Link: https://lkml.kernel.org/r/160576521135.320071.3883101436675969998.stgit@devnote2 |
12 |
|
13 |
Fixes: 85c46b78da58 ("bootconfig: Add bootconfig magic word for indicating bootconfig explicitly") |
14 |
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> |
15 |
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> |
16 |
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> |
17 |
--- |
18 |
tools/bootconfig/main.c | 30 ++++++++++++++++++++++++++---- |
19 |
1 file changed, 26 insertions(+), 4 deletions(-) |
20 |
|
21 |
diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c |
22 |
index 52eb2bbe8966..a0733cbb3c49 100644 |
23 |
--- a/tools/bootconfig/main.c |
24 |
+++ b/tools/bootconfig/main.c |
25 |
@@ -337,6 +337,7 @@ static int delete_xbc(const char *path) |
26 |
|
27 |
static int apply_xbc(const char *path, const char *xbc_path) |
28 |
{ |
29 |
+ struct stat stat; |
30 |
u32 size, csum; |
31 |
char *buf, *data; |
32 |
int ret, fd; |
33 |
@@ -394,16 +395,26 @@ static int apply_xbc(const char *path, const char *xbc_path) |
34 |
return ret; |
35 |
} |
36 |
/* TODO: Ensure the @path is initramfs/initrd image */ |
37 |
+ if (fstat(fd, &stat) < 0) { |
38 |
+ pr_err("Failed to get the size of %s\n", path); |
39 |
+ goto out; |
40 |
+ } |
41 |
ret = write(fd, data, size + 8); |
42 |
- if (ret < 0) { |
43 |
+ if (ret < size + 8) { |
44 |
+ if (ret < 0) |
45 |
+ ret = -errno; |
46 |
pr_err("Failed to apply a boot config: %d\n", ret); |
47 |
- goto out; |
48 |
+ if (ret < 0) |
49 |
+ goto out; |
50 |
+ goto out_rollback; |
51 |
} |
52 |
/* Write a magic word of the bootconfig */ |
53 |
ret = write(fd, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN); |
54 |
- if (ret < 0) { |
55 |
+ if (ret < BOOTCONFIG_MAGIC_LEN) { |
56 |
+ if (ret < 0) |
57 |
+ ret = -errno; |
58 |
pr_err("Failed to apply a boot config magic: %d\n", ret); |
59 |
- goto out; |
60 |
+ goto out_rollback; |
61 |
} |
62 |
ret = 0; |
63 |
out: |
64 |
@@ -411,6 +422,17 @@ static int apply_xbc(const char *path, const char *xbc_path) |
65 |
free(data); |
66 |
|
67 |
return ret; |
68 |
+ |
69 |
+out_rollback: |
70 |
+ /* Map the partial write to -ENOSPC */ |
71 |
+ if (ret >= 0) |
72 |
+ ret = -ENOSPC; |
73 |
+ if (ftruncate(fd, stat.st_size) < 0) { |
74 |
+ ret = -errno; |
75 |
+ pr_err("Failed to rollback the write error: %d\n", ret); |
76 |
+ pr_err("The initrd %s may be corrupted. Recommend to rebuild.\n", path); |
77 |
+ } |
78 |
+ goto out; |
79 |
} |
80 |
|
81 |
static int usage(void) |
82 |
-- |
83 |
2.29.2 |
84 |
|