Skip to content

Commit a28726b

Browse files
bzhgaegl
authored andcommitted
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 <[email protected]> Acked-by: Kees Cook <[email protected]> Signed-off-by: Tony Luck <[email protected]>
1 parent 0df1f24 commit a28726b

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

fs/pstore/ram.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,25 +135,27 @@ ramoops_get_next_prz(struct persistent_ram_zone *przs[], uint *c, uint max,
135135
return prz;
136136
}
137137

138-
static void ramoops_read_kmsg_hdr(char *buffer, struct timespec *time,
138+
static int ramoops_read_kmsg_hdr(char *buffer, struct timespec *time,
139139
bool *compressed)
140140
{
141141
char data_type;
142+
int header_length = 0;
142143

143-
if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n",
144-
&time->tv_sec, &time->tv_nsec, &data_type) == 3) {
144+
if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n%n", &time->tv_sec,
145+
&time->tv_nsec, &data_type, &header_length) == 3) {
145146
if (data_type == 'C')
146147
*compressed = true;
147148
else
148149
*compressed = false;
149-
} else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu\n",
150-
&time->tv_sec, &time->tv_nsec) == 2) {
150+
} else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu\n%n",
151+
&time->tv_sec, &time->tv_nsec, &header_length) == 2) {
151152
*compressed = false;
152153
} else {
153154
time->tv_sec = 0;
154155
time->tv_nsec = 0;
155156
*compressed = false;
156157
}
158+
return header_length;
157159
}
158160

159161
static 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,
165167
ssize_t ecc_notice_size;
166168
struct ramoops_context *cxt = psi->data;
167169
struct persistent_ram_zone *prz;
170+
int header_length;
168171

169172
prz = ramoops_get_next_prz(cxt->przs, &cxt->dump_read_cnt,
170173
cxt->max_dump_cnt, id, type,
@@ -178,7 +181,13 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
178181
if (!prz)
179182
return 0;
180183

184+
if (!persistent_ram_old(prz))
185+
return 0;
186+
181187
size = persistent_ram_old_size(prz);
188+
header_length = ramoops_read_kmsg_hdr(persistent_ram_old(prz), time,
189+
compressed);
190+
size -= header_length;
182191

183192
/* ECC correction notice */
184193
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,
187196
if (*buf == NULL)
188197
return -ENOMEM;
189198

190-
memcpy(*buf, persistent_ram_old(prz), size);
191-
ramoops_read_kmsg_hdr(*buf, time, compressed);
199+
memcpy(*buf, (char *)persistent_ram_old(prz) + header_length, size);
192200
persistent_ram_ecc_string(prz, *buf + size, ecc_notice_size + 1);
193201

194202
return size + ecc_notice_size;

0 commit comments

Comments
 (0)