Merge tag 'pstore-v4.12-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/kees...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 23 May 2017 02:31:07 +0000 (19:31 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 23 May 2017 02:31:07 +0000 (19:31 -0700)
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

1  2 
drivers/firmware/efi/efi-pstore.c

@@@ -53,6 -53,7 +53,7 @@@ static int efi_pstore_read_func(struct 
        if (sscanf(name, "dump-type%u-%u-%d-%lu-%c",
                   &record->type, &part, &cnt, &time, &data_type) == 5) {
                record->id = generic_id(time, part, cnt);
+               record->part = part;
                record->count = cnt;
                record->time.tv_sec = time;
                record->time.tv_nsec = 0;
@@@ -64,6 -65,7 +65,7 @@@
        } else if (sscanf(name, "dump-type%u-%u-%d-%lu",
                   &record->type, &part, &cnt, &time) == 4) {
                record->id = generic_id(time, part, cnt);
+               record->part = part;
                record->count = cnt;
                record->time.tv_sec = time;
                record->time.tv_nsec = 0;
@@@ -77,6 -79,7 +79,7 @@@
                 * multiple logs, remains.
                 */
                record->id = generic_id(time, part, 0);
+               record->part = part;
                record->count = 0;
                record->time.tv_sec = time;
                record->time.tv_nsec = 0;
@@@ -241,21 -244,26 +244,26 @@@ static int efi_pstore_write(struct psto
        efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
        int i, ret = 0;
  
+       record->time.tv_sec = get_seconds();
+       record->time.tv_nsec = 0;
+       record->id = generic_id(record->time.tv_sec, record->part,
+                               record->count);
        snprintf(name, sizeof(name), "dump-type%u-%u-%d-%lu-%c",
                 record->type, record->part, record->count,
-                get_seconds(), record->compressed ? 'C' : 'D');
+                record->time.tv_sec, record->compressed ? 'C' : 'D');
  
        for (i = 0; i < DUMP_NAME_LEN; i++)
                efi_name[i] = name[i];
  
 -      efivar_entry_set_safe(efi_name, vendor, PSTORE_EFI_ATTRIBUTES,
 +      ret = efivar_entry_set_safe(efi_name, vendor, PSTORE_EFI_ATTRIBUTES,
                              !pstore_cannot_block_path(record->reason),
                              record->size, record->psi->buf);
  
        if (record->reason == KMSG_DUMP_OOPS)
                efivar_run_worker();
  
-       record->id = record->part;
        return ret;
  };
  
@@@ -287,7 -295,7 +295,7 @@@ static int efi_pstore_erase_func(struc
                 * holding multiple logs, remains.
                 */
                snprintf(name_old, sizeof(name_old), "dump-type%u-%u-%lu",
-                       ed->record->type, (unsigned int)ed->record->id,
+                       ed->record->type, ed->record->part,
                        ed->record->time.tv_sec);
  
                for (i = 0; i < DUMP_NAME_LEN; i++)
@@@ -320,10 -328,7 +328,7 @@@ static int efi_pstore_erase(struct psto
        char name[DUMP_NAME_LEN];
        efi_char16_t efi_name[DUMP_NAME_LEN];
        int found, i;
-       unsigned int part;
  
-       do_div(record->id, 1000);
-       part = do_div(record->id, 100);
        snprintf(name, sizeof(name), "dump-type%u-%u-%d-%lu",
                 record->type, record->part, record->count,
                 record->time.tv_sec);