summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Chase <[email protected]>2016-07-10 09:09:02 -0500
committerBrian Behlendorf <[email protected]>2016-07-14 16:25:03 -0700
commit8887c7d778dce8cadee422de97e557a224555bdf (patch)
tree302744ab06a765ac2751918ef3eddc2861ad4a42
parent8d9e12451530418778f57315717e35cc5868d98d (diff)
Prevent null dereferences when accessing dbuf kstat
In arc_buf_info(), the arc_buf_t may have no header. If not, don't try to fetch the arc buffer stats and instead just zero them. The null dereferences were observed while accessing the dbuf kstat with awk on a system in which millions of small files were being created in order to overflow the system's metadata limit. Signed-off-by: Tim Chase <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Signed-off-by: Chunwei Chen <[email protected]> Closes #4837
-rw-r--r--module/zfs/arc.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/module/zfs/arc.c b/module/zfs/arc.c
index 77181b1fd..2dbca8da9 100644
--- a/module/zfs/arc.c
+++ b/module/zfs/arc.c
@@ -1461,6 +1461,13 @@ arc_buf_info(arc_buf_t *ab, arc_buf_info_t *abi, int state_index)
l2arc_buf_hdr_t *l2hdr = NULL;
arc_state_t *state = NULL;
+ memset(abi, 0, sizeof (arc_buf_info_t));
+
+ if (hdr == NULL)
+ return;
+
+ abi->abi_flags = hdr->b_flags;
+
if (HDR_HAS_L1HDR(hdr)) {
l1hdr = &hdr->b_l1hdr;
state = l1hdr->b_state;
@@ -1468,9 +1475,6 @@ arc_buf_info(arc_buf_t *ab, arc_buf_info_t *abi, int state_index)
if (HDR_HAS_L2HDR(hdr))
l2hdr = &hdr->b_l2hdr;
- memset(abi, 0, sizeof (arc_buf_info_t));
- abi->abi_flags = hdr->b_flags;
-
if (l1hdr) {
abi->abi_datacnt = l1hdr->b_datacnt;
abi->abi_access = l1hdr->b_arc_access;