diff options
author | Kees Cook <keescook@chromium.org> | 2017-05-16 15:03:31 -0400 |
---|---|---|
committer | Kees Cook <keescook@chromium.org> | 2017-05-31 13:13:42 -0400 |
commit | 656de42e83379e5348e3f4236ff1d79353edfb28 (patch) | |
tree | 08af3b75f5c4b4a6e725d19ce45d3455c9081286 | |
parent | f6525b96dd9f68efe374e5aef864975e628de991 (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.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, | |||
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 | ||
877 | static void pstore_dowork(struct work_struct *work) | 881 | static void pstore_dowork(struct work_struct *work) |