diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-05-22 22:31:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-05-22 22:31:07 -0400 |
commit | fadd2ce5a3680fb265694f573cbfb8bcb7d6c9d5 (patch) | |
tree | 2394d6f51dd41f0917acdd0f19339750862219cd | |
parent | 74a9e7dbbc4a45ee78560f36903f3c3b1f553928 (diff) | |
parent | c10e8031d5b34cde06b039ca2e8af87a33d5ba11 (diff) |
Merge tag 'pstore-v4.12-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
Pull pstore fix from Kees Cook:
"Marta noticed another misbehavior in EFI pstore, which this fixes.
Hopefully this is the last of the v4.12 fixes for pstore!"
* tag 'pstore-v4.12-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
efi-pstore: Fix write/erase id tracking
-rw-r--r-- | drivers/firmware/efi/efi-pstore.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c index ab3a951a17e6..ef1fafdad400 100644 --- a/drivers/firmware/efi/efi-pstore.c +++ b/drivers/firmware/efi/efi-pstore.c | |||
@@ -53,6 +53,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry, | |||
53 | if (sscanf(name, "dump-type%u-%u-%d-%lu-%c", | 53 | if (sscanf(name, "dump-type%u-%u-%d-%lu-%c", |
54 | &record->type, &part, &cnt, &time, &data_type) == 5) { | 54 | &record->type, &part, &cnt, &time, &data_type) == 5) { |
55 | record->id = generic_id(time, part, cnt); | 55 | record->id = generic_id(time, part, cnt); |
56 | record->part = part; | ||
56 | record->count = cnt; | 57 | record->count = cnt; |
57 | record->time.tv_sec = time; | 58 | record->time.tv_sec = time; |
58 | record->time.tv_nsec = 0; | 59 | record->time.tv_nsec = 0; |
@@ -64,6 +65,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry, | |||
64 | } else if (sscanf(name, "dump-type%u-%u-%d-%lu", | 65 | } else if (sscanf(name, "dump-type%u-%u-%d-%lu", |
65 | &record->type, &part, &cnt, &time) == 4) { | 66 | &record->type, &part, &cnt, &time) == 4) { |
66 | record->id = generic_id(time, part, cnt); | 67 | record->id = generic_id(time, part, cnt); |
68 | record->part = part; | ||
67 | record->count = cnt; | 69 | record->count = cnt; |
68 | record->time.tv_sec = time; | 70 | record->time.tv_sec = time; |
69 | record->time.tv_nsec = 0; | 71 | record->time.tv_nsec = 0; |
@@ -77,6 +79,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry, | |||
77 | * multiple logs, remains. | 79 | * multiple logs, remains. |
78 | */ | 80 | */ |
79 | record->id = generic_id(time, part, 0); | 81 | record->id = generic_id(time, part, 0); |
82 | record->part = part; | ||
80 | record->count = 0; | 83 | record->count = 0; |
81 | record->time.tv_sec = time; | 84 | record->time.tv_sec = time; |
82 | record->time.tv_nsec = 0; | 85 | record->time.tv_nsec = 0; |
@@ -241,9 +244,15 @@ static int efi_pstore_write(struct pstore_record *record) | |||
241 | efi_guid_t vendor = LINUX_EFI_CRASH_GUID; | 244 | efi_guid_t vendor = LINUX_EFI_CRASH_GUID; |
242 | int i, ret = 0; | 245 | int i, ret = 0; |
243 | 246 | ||
247 | record->time.tv_sec = get_seconds(); | ||
248 | record->time.tv_nsec = 0; | ||
249 | |||
250 | record->id = generic_id(record->time.tv_sec, record->part, | ||
251 | record->count); | ||
252 | |||
244 | snprintf(name, sizeof(name), "dump-type%u-%u-%d-%lu-%c", | 253 | snprintf(name, sizeof(name), "dump-type%u-%u-%d-%lu-%c", |
245 | record->type, record->part, record->count, | 254 | record->type, record->part, record->count, |
246 | get_seconds(), record->compressed ? 'C' : 'D'); | 255 | record->time.tv_sec, record->compressed ? 'C' : 'D'); |
247 | 256 | ||
248 | for (i = 0; i < DUMP_NAME_LEN; i++) | 257 | for (i = 0; i < DUMP_NAME_LEN; i++) |
249 | efi_name[i] = name[i]; | 258 | efi_name[i] = name[i]; |
@@ -255,7 +264,6 @@ static int efi_pstore_write(struct pstore_record *record) | |||
255 | if (record->reason == KMSG_DUMP_OOPS) | 264 | if (record->reason == KMSG_DUMP_OOPS) |
256 | efivar_run_worker(); | 265 | efivar_run_worker(); |
257 | 266 | ||
258 | record->id = record->part; | ||
259 | return ret; | 267 | return ret; |
260 | }; | 268 | }; |
261 | 269 | ||
@@ -287,7 +295,7 @@ static int efi_pstore_erase_func(struct efivar_entry *entry, void *data) | |||
287 | * holding multiple logs, remains. | 295 | * holding multiple logs, remains. |
288 | */ | 296 | */ |
289 | snprintf(name_old, sizeof(name_old), "dump-type%u-%u-%lu", | 297 | snprintf(name_old, sizeof(name_old), "dump-type%u-%u-%lu", |
290 | ed->record->type, (unsigned int)ed->record->id, | 298 | ed->record->type, ed->record->part, |
291 | ed->record->time.tv_sec); | 299 | ed->record->time.tv_sec); |
292 | 300 | ||
293 | for (i = 0; i < DUMP_NAME_LEN; i++) | 301 | for (i = 0; i < DUMP_NAME_LEN; i++) |
@@ -320,10 +328,7 @@ static int efi_pstore_erase(struct pstore_record *record) | |||
320 | char name[DUMP_NAME_LEN]; | 328 | char name[DUMP_NAME_LEN]; |
321 | efi_char16_t efi_name[DUMP_NAME_LEN]; | 329 | efi_char16_t efi_name[DUMP_NAME_LEN]; |
322 | int found, i; | 330 | int found, i; |
323 | unsigned int part; | ||
324 | 331 | ||
325 | do_div(record->id, 1000); | ||
326 | part = do_div(record->id, 100); | ||
327 | snprintf(name, sizeof(name), "dump-type%u-%u-%d-%lu", | 332 | snprintf(name, sizeof(name), "dump-type%u-%u-%d-%lu", |
328 | record->type, record->part, record->count, | 333 | record->type, record->part, record->count, |
329 | record->time.tv_sec); | 334 | record->time.tv_sec); |