[Crash-utility] [PATCH] Fix for "bpf -m|-M" options on Linux 5.3 and later

HAGIO KAZUHITO(萩尾 一仁) k-hagio-ab at nec.com
Wed Mar 4 17:29:40 UTC 2020


Fix for the "bpf -m|-M" options on Linux 5.3 and later kernels that
contain commit 3539b96e041c06e4317082816d90ec09160aeb11, titled
"bpf: group memory related fields in struct bpf_map_memory".
Without the patch, the options prints "(unknown)" for MEMLOCK and UID.

Signed-off-by: Kazuhito Hagio <k-hagio-ab at nec.com>
---
 bpf.c     | 22 ++++++++++++++++++++--
 defs.h    |  3 +++
 symbols.c |  6 ++++++
 3 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/bpf.c b/bpf.c
index 056e286..39ced88 100644
--- a/bpf.c
+++ b/bpf.c
@@ -202,6 +202,13 @@ bpf_init(struct bpf_info *bpf)
 		MEMBER_OFFSET_INIT(bpf_map_user, "bpf_map", "user");
 		MEMBER_OFFSET_INIT(user_struct_uid, "user_struct", "uid");
 
+		/* Linux 5.3 */
+		MEMBER_OFFSET_INIT(bpf_map_memory, "bpf_map", "memory");
+		if (VALID_MEMBER(bpf_map_memory)) {
+			MEMBER_OFFSET_INIT(bpf_map_memory_pages, "bpf_map_memory", "pages");
+			MEMBER_OFFSET_INIT(bpf_map_memory_user, "bpf_map_memory", "user");
+		}
+
 		if (!bpf_type_size_init()) {
 			bpf->status = FALSE;
 			command_not_supported();
@@ -576,7 +583,11 @@ do_map_only:
 				fprintf(fp, "(unknown)");
 
 			fprintf(fp, "  MEMLOCK: ");
-			if (VALID_MEMBER(bpf_map_pages)) {
+			if (VALID_MEMBER(bpf_map_memory) && VALID_MEMBER(bpf_map_memory_pages)) {
+				map_pages = UINT(bpf->bpf_map_buf + OFFSET(bpf_map_memory)
+						+ OFFSET(bpf_map_memory_pages));
+				fprintf(fp, "%d\n", map_pages * PAGESIZE());
+			} else if (VALID_MEMBER(bpf_map_pages)) {
 				map_pages = UINT(bpf->bpf_map_buf + OFFSET(bpf_map_pages));
 				fprintf(fp, "%d\n", map_pages * PAGESIZE());
 			} else
@@ -594,8 +605,15 @@ do_map_only:
 				fprintf(fp, "(unknown)\n");
 
 			fprintf(fp, "  UID: ");
-			if (VALID_MEMBER(bpf_map_user) && VALID_MEMBER(user_struct_uid)) {
+			if (VALID_MEMBER(bpf_map_memory) && VALID_MEMBER(bpf_map_memory_user))
+				user = ULONG(bpf->bpf_map_buf + OFFSET(bpf_map_memory)
+						+ OFFSET(bpf_map_memory_user));
+			else if (VALID_MEMBER(bpf_map_user))
 				user = ULONG(bpf->bpf_map_buf + OFFSET(bpf_map_user));
+			else
+				user = 0;
+
+			if (user && VALID_MEMBER(user_struct_uid)) {
 				if (readmem(user + OFFSET(user_struct_uid), KVADDR, &uid, sizeof(uint), 
 				    "user_struct.uid", QUIET|RETURN_ON_ERROR))
 					fprintf(fp, "%d\n", uid);
diff --git a/defs.h b/defs.h
index ac24a5d..fbd19b0 100644
--- a/defs.h
+++ b/defs.h
@@ -2075,6 +2075,9 @@ struct offset_table {                    /* stash of commonly-used offsets */
 	long device_private_knode_class;
 	long timerqueue_head_rb_root;
 	long rb_root_cached_rb_leftmost;
+	long bpf_map_memory;
+	long bpf_map_memory_pages;
+	long bpf_map_memory_user;
 };
 
 struct size_table {         /* stash of commonly-used sizes */
diff --git a/symbols.c b/symbols.c
index f04e8b5..f1f659b 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10479,6 +10479,12 @@ dump_offset_table(char *spec, ulong makestruct)
 		OFFSET(bpf_map_name));
 	fprintf(fp, "                  bpf_map_user: %ld\n",
 		OFFSET(bpf_map_user));
+	fprintf(fp, "                bpf_map_memory: %ld\n",
+		OFFSET(bpf_map_memory));
+	fprintf(fp, "          bpf_map_memory_pages: %ld\n",
+		OFFSET(bpf_map_memory_pages));
+	fprintf(fp, "           bpf_map_memory_user: %ld\n",
+		OFFSET(bpf_map_memory_user));
 
 	fprintf(fp, "     bpf_prog_aux_used_map_cnt: %ld\n",
 		OFFSET(bpf_prog_aux_used_map_cnt));
-- 
2.24.1





More information about the Crash-utility mailing list