aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2017-05-16 15:03:31 -0400
committerKees Cook <keescook@chromium.org>2017-05-31 13:13:42 -0400
commit656de42e83379e5348e3f4236ff1d79353edfb28 (patch)
tree08af3b75f5c4b4a6e725d19ce45d3455c9081286
parentf6525b96dd9f68efe374e5aef864975e628de991 (diff)
pstore: Avoid potential infinite loop
If a backend does not correctly iterate through its records, pstore will get stuck loading entries. Detect this with a large record count, and announce if we ever hit the limit. This will let future backend reading bugs less annoying to debug. Additionally adjust the error about pstore_mkfile() failing. Signed-off-by: Kees Cook <keescook@chromium.org>
-rw-r--r--fs/pstore/platform.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 4c5cd9368460..d8289ce00f99 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -822,6 +822,7 @@ void pstore_get_backend_records(struct pstore_info *psi,
822 struct dentry *root, int quiet) 822 struct dentry *root, int quiet)
823{ 823{
824 int failed = 0; 824 int failed = 0;
825 unsigned int stop_loop = 65536;
825 826
826 if (!psi || !root) 827 if (!psi || !root)
827 return; 828 return;
@@ -835,7 +836,7 @@ void pstore_get_backend_records(struct pstore_info *psi,
835 * may reallocate record.buf. On success, pstore_mkfile() will keep 836 * may reallocate record.buf. On success, pstore_mkfile() will keep
836 * the record.buf, so free it only on failure. 837 * the record.buf, so free it only on failure.
837 */ 838 */
838 for (;;) { 839 for (; stop_loop; stop_loop--) {
839 struct pstore_record *record; 840 struct pstore_record *record;
840 int rc; 841 int rc;
841 842
@@ -870,8 +871,11 @@ out:
870 mutex_unlock(&psi->read_mutex); 871 mutex_unlock(&psi->read_mutex);
871 872
872 if (failed) 873 if (failed)
873 pr_warn("failed to load %d record(s) from '%s'\n", 874 pr_warn("failed to create %d record(s) from '%s'\n",
874 failed, psi->name); 875 failed, psi->name);
876 if (!stop_loop)
877 pr_err("looping? Too many records seen from '%s'\n",
878 psi->name);
875} 879}
876 880
877static void pstore_dowork(struct work_struct *work) 881static void pstore_dowork(struct work_struct *work)