Merge tag 'pstore-v4.20-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/kees...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 30 Nov 2018 17:03:15 +0000 (09:03 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 30 Nov 2018 17:03:15 +0000 (09:03 -0800)
Pull pstore fix from Kees Cook:
 "Fix corrupted compression due to unlucky size choice with ECC"

* tag 'pstore-v4.20-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
  pstore/ram: Correctly calculate usable PRZ bytes

1  2 
fs/pstore/ram.c

diff --combined fs/pstore/ram.c
index ffcff6516e89cccfcbbc138a6d7331e4ca9fb63b,8646fe6e916fe61ab7cbbedc57c2d0c354280b99..e02a9039b5ea4410d3b3a986d7f4b6566e196eff
@@@ -816,17 -816,14 +816,14 @@@ static int ramoops_probe(struct platfor
  
        cxt->pstore.data = cxt;
        /*
-        * Console can handle any buffer size, so prefer LOG_LINE_MAX. If we
-        * have to handle dumps, we must have at least record_size buffer. And
-        * for ftrace, bufsize is irrelevant (if bufsize is 0, buf will be
-        * ZERO_SIZE_PTR).
+        * Since bufsize is only used for dmesg crash dumps, it
+        * must match the size of the dprz record (after PRZ header
+        * and ECC bytes have been accounted for).
         */
-       if (cxt->console_size)
-               cxt->pstore.bufsize = 1024; /* LOG_LINE_MAX */
-       cxt->pstore.bufsize = max(cxt->record_size, cxt->pstore.bufsize);
-       cxt->pstore.buf = kmalloc(cxt->pstore.bufsize, GFP_KERNEL);
+       cxt->pstore.bufsize = cxt->dprzs[0]->buffer_size;
+       cxt->pstore.buf = kzalloc(cxt->pstore.bufsize, GFP_KERNEL);
        if (!cxt->pstore.buf) {
-               pr_err("cannot allocate pstore buffer\n");
+               pr_err("cannot allocate pstore crash dump buffer\n");
                err = -ENOMEM;
                goto fail_clear;
        }
@@@ -908,22 -905,8 +905,22 @@@ static struct platform_driver ramoops_d
        },
  };
  
 -static void ramoops_register_dummy(void)
 +static inline void ramoops_unregister_dummy(void)
  {
 +      platform_device_unregister(dummy);
 +      dummy = NULL;
 +
 +      kfree(dummy_data);
 +      dummy_data = NULL;
 +}
 +
 +static void __init ramoops_register_dummy(void)
 +{
 +      /*
 +       * Prepare a dummy platform data structure to carry the module
 +       * parameters. If mem_size isn't set, then there are no module
 +       * parameters, and we can skip this.
 +       */
        if (!mem_size)
                return;
  
        if (IS_ERR(dummy)) {
                pr_info("could not create platform device: %ld\n",
                        PTR_ERR(dummy));
 +              dummy = NULL;
 +              ramoops_unregister_dummy();
        }
  }
  
  static int __init ramoops_init(void)
  {
 +      int ret;
 +
        ramoops_register_dummy();
 -      return platform_driver_register(&ramoops_driver);
 +      ret = platform_driver_register(&ramoops_driver);
 +      if (ret != 0)
 +              ramoops_unregister_dummy();
 +
 +      return ret;
  }
  postcore_initcall(ramoops_init);
  
  static void __exit ramoops_exit(void)
  {
        platform_driver_unregister(&ramoops_driver);
 -      platform_device_unregister(dummy);
 -      kfree(dummy_data);
 +      ramoops_unregister_dummy();
  }
  module_exit(ramoops_exit);