aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pstore/ram.c
diff options
context:
space:
mode:
authorBen Zhang <benzh@chromium.org>2014-10-30 20:14:21 -0400
committerTony Luck <tony.luck@intel.com>2014-11-05 12:58:17 -0500
commita28726b4fb624f81d637a8afb9ea12fc16500f61 (patch)
tree97dbec898efa336bca564174d2311acb35eb2c78 /fs/pstore/ram.c
parent0df1f2487d2f0d04703f142813d53615d62a1da4 (diff)
pstore/ram: Strip ramoops header for correct decompression
pstore compression/decompression was added during 3.12. The ramoops driver prepends a "====timestamp.timestamp-C|D\n" header to the compressed record before handing it over to pstore driver which doesn't know about the header. In pstore_decompress(), the pstore driver reads the first "==" as a zlib header, so the decompression always fails. For example, this causes the driver to write /dev/pstore/dmesg-ramoops-0.enc.z instead of /dev/pstore/dmesg-ramoops-0. This patch makes the ramoops driver remove the header before pstore decompression. Signed-off-by: Ben Zhang <benzh@chromium.org> Acked-by: Kees Cook <keescook@chromium.org> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'fs/pstore/ram.c')
-rw-r--r--fs/pstore/ram.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 3b5744306ed8..ec881b312700 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -135,25 +135,27 @@ ramoops_get_next_prz(struct persistent_ram_zone *przs[], uint *c, uint max,
135 return prz; 135 return prz;
136} 136}
137 137
138static void ramoops_read_kmsg_hdr(char *buffer, struct timespec *time, 138static int ramoops_read_kmsg_hdr(char *buffer, struct timespec *time,
139 bool *compressed) 139 bool *compressed)
140{ 140{
141 char data_type; 141 char data_type;
142 int header_length = 0;
142 143
143 if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n", 144 if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n%n", &time->tv_sec,
144 &time->tv_sec, &time->tv_nsec, &data_type) == 3) { 145 &time->tv_nsec, &data_type, &header_length) == 3) {
145 if (data_type == 'C') 146 if (data_type == 'C')
146 *compressed = true; 147 *compressed = true;
147 else 148 else
148 *compressed = false; 149 *compressed = false;
149 } else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu\n", 150 } else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu\n%n",
150 &time->tv_sec, &time->tv_nsec) == 2) { 151 &time->tv_sec, &time->tv_nsec, &header_length) == 2) {
151 *compressed = false; 152 *compressed = false;
152 } else { 153 } else {
153 time->tv_sec = 0; 154 time->tv_sec = 0;
154 time->tv_nsec = 0; 155 time->tv_nsec = 0;
155 *compressed = false; 156 *compressed = false;
156 } 157 }
158 return header_length;
157} 159}
158 160
159static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, 161static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
@@ -165,6 +167,7 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
165 ssize_t ecc_notice_size; 167 ssize_t ecc_notice_size;
166 struct ramoops_context *cxt = psi->data; 168 struct ramoops_context *cxt = psi->data;
167 struct persistent_ram_zone *prz; 169 struct persistent_ram_zone *prz;
170 int header_length;
168 171
169 prz = ramoops_get_next_prz(cxt->przs, &cxt->dump_read_cnt, 172 prz = ramoops_get_next_prz(cxt->przs, &cxt->dump_read_cnt,
170 cxt->max_dump_cnt, id, type, 173 cxt->max_dump_cnt, id, type,
@@ -178,7 +181,13 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
178 if (!prz) 181 if (!prz)
179 return 0; 182 return 0;
180 183
184 if (!persistent_ram_old(prz))
185 return 0;
186
181 size = persistent_ram_old_size(prz); 187 size = persistent_ram_old_size(prz);
188 header_length = ramoops_read_kmsg_hdr(persistent_ram_old(prz), time,
189 compressed);
190 size -= header_length;
182 191
183 /* ECC correction notice */ 192 /* ECC correction notice */
184 ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0); 193 ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0);
@@ -187,8 +196,7 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
187 if (*buf == NULL) 196 if (*buf == NULL)
188 return -ENOMEM; 197 return -ENOMEM;
189 198
190 memcpy(*buf, persistent_ram_old(prz), size); 199 memcpy(*buf, (char *)persistent_ram_old(prz) + header_length, size);
191 ramoops_read_kmsg_hdr(*buf, time, compressed);
192 persistent_ram_ecc_string(prz, *buf + size, ecc_notice_size + 1); 200 persistent_ram_ecc_string(prz, *buf + size, ecc_notice_size + 1);
193 201
194 return size + ecc_notice_size; 202 return size + ecc_notice_size;