diff options
author | Kees Cook <keescook@chromium.org> | 2017-05-16 12:03:31 -0700 |
---|---|---|
committer | Kees Cook <keescook@chromium.org> | 2017-05-31 10:13:42 -0700 |
commit | 656de42e83379e5348e3f4236ff1d79353edfb28 (patch) | |
tree | 08af3b75f5c4b4a6e725d19ce45d3455c9081286 /fs/pstore | |
parent | f6525b96dd9f68efe374e5aef864975e628de991 (diff) | |
download | linux-stable-656de42e83379e5348e3f4236ff1d79353edfb28.tar.gz linux-stable-656de42e83379e5348e3f4236ff1d79353edfb28.tar.bz2 linux-stable-656de42e83379e5348e3f4236ff1d79353edfb28.zip |
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>
Diffstat (limited to 'fs/pstore')
-rw-r--r-- | fs/pstore/platform.c | 8 |
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, struct dentry *root, int quiet) { int failed = 0; + unsigned int stop_loop = 65536; if (!psi || !root) return; @@ -835,7 +836,7 @@ void pstore_get_backend_records(struct pstore_info *psi, * may reallocate record.buf. On success, pstore_mkfile() will keep * the record.buf, so free it only on failure. */ - for (;;) { + for (; stop_loop; stop_loop--) { struct pstore_record *record; int rc; @@ -870,8 +871,11 @@ out: mutex_unlock(&psi->read_mutex); if (failed) - pr_warn("failed to load %d record(s) from '%s'\n", + pr_warn("failed to create %d record(s) from '%s'\n", failed, psi->name); + if (!stop_loop) + pr_err("looping? Too many records seen from '%s'\n", + psi->name); } static void pstore_dowork(struct work_struct *work) |