summaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorRobert Richter <rrichter@marvell.com>2020-01-23 09:03:00 +0000
committerBorislav Petkov <bp@suse.de>2020-02-17 13:10:14 +0100
commit65bb4d1af92cf007adc0a0c59dadcc393c5cada6 (patch)
treeee8826d490d3e435c3b0ff6790830b64f20cc79a /drivers/edac
parent6334dc4e3ff53031a2d522b826c4fab92cfdea93 (diff)
downloadlinux-65bb4d1af92cf007adc0a0c59dadcc393c5cada6.tar.gz
linux-65bb4d1af92cf007adc0a0c59dadcc393c5cada6.tar.bz2
linux-65bb4d1af92cf007adc0a0c59dadcc393c5cada6.zip
EDAC/mc: Report "unknown memory" on too many DIMM labels found
There is a limitation to report only EDAC_MAX_LABELS in e->label of the error descriptor. This is to prevent a potential string overflow. The current implementation falls back to "any memory" in this case and also stops all further processing to find a unique row and channel of the possible error location. Reporting "any memory" is wrong as the memory controller reported an error location for one of the layers. Instead, report "unknown memory" and also do not break early in the loop to further check row and channel for uniqueness. [ bp: Massage commit message. ] Signed-off-by: Robert Richter <rrichter@marvell.com> Signed-off-by: Borislav Petkov <bp@suse.de> Acked-by: Aristeu Rozanski <aris@redhat.com> Link: https://lkml.kernel.org/r/20200123090210.26933-7-rrichter@marvell.com
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/edac_mc.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 35d282492505..7a1445feb59d 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -1243,20 +1243,21 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
* channel/memory controller/... may be affected.
* Also, don't show errors for empty DIMM slots.
*/
- if (!e->enable_per_layer_report || !dimm->nr_pages)
+ if (!dimm->nr_pages)
continue;
- if (n_labels >= EDAC_MAX_LABELS) {
- e->enable_per_layer_report = false;
- break;
- }
n_labels++;
- if (p != e->label) {
- strcpy(p, OTHER_LABEL);
- p += strlen(OTHER_LABEL);
+ if (n_labels > EDAC_MAX_LABELS) {
+ p = e->label;
+ *p = '\0';
+ } else {
+ if (p != e->label) {
+ strcpy(p, OTHER_LABEL);
+ p += strlen(OTHER_LABEL);
+ }
+ strcpy(p, dimm->label);
+ p += strlen(p);
}
- strcpy(p, dimm->label);
- p += strlen(p);
/*
* get csrow/channel of the DIMM, in order to allow