dwarf2json
dwarf2json copied to clipboard
`fs_struct` type is not converted correctly
For Ubuntu 23.10 the fs_struct
type is not converted correctly. No clue if this is the only type that is affected, or if there is a bigger issue. Using commit 15baf31210af272dc2b79ba79a6e58abc5d0336b
You can download the kernel+map here.
$ llvm-dwarfdump -r 1 ../kernels/ubuntu-23.10-live-server-amd64-0052522788-vmlinux-6.5.0-14-generic-2e44e-2e44e.elf | head | grep Compile
0x00000000: Compile Unit: length = 0x0002592c, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x00025930)
$ gdb -n -q --batch -ex 'ptype /r init_task.fs' -ex "quit" ../kernels/ubuntu-23.10-live-server-amd64-0052522788-vmlinux-6.5.0-14-generic-2e44e-2e44e.elf
type = struct fs_struct {
int users;
spinlock_t lock;
seqcount_spinlock_t seq;
int umask;
int in_exec;
struct path root;
struct path pwd;
} *
$ pahole -F dwarf ../kernels/ubuntu-23.10-live-server-amd64-0052522788-vmlinux-6.5.0-14-generic-2e44e-2e44e.elf | rg '^struct fs_struct \{' -A 15
struct fs_struct {
int users; /* 0 4 */
spinlock_t lock; /* 4 4 */
seqcount_spinlock_t seq; /* 8 4 */
int umask; /* 12 4 */
int in_exec; /* 16 4 */
/* XXX 4 bytes hole, try to pack */
struct path root; /* 24 16 */
struct path pwd; /* 40 16 */
/* size: 56, cachelines: 1, members: 7 */
/* sum members: 52, holes: 1, sum holes: 4 */
/* last cacheline: 56 bytes */
};
# ./volshell.py -f /io/dumps/ubuntu-23.10-live-server-amd64-0052522788_19.raw -l --script <(echo -e "dt('fs_struct')\nquit()")
Volshell (Volatility 3 Framework) 2.5.2
Readline imported successfully Stacking attempts finished
Running code from file:///dev/fd/63
symbol_table_name1!fs_struct (0 bytes)
0x0 : _unused symbol_table_name1!array
$ cat ubuntu-23.10-live-server-amd64-0052522788-vmlinux-6.5.0-14-generic-2e44e-2e44e.isf.json| rg '"fs_struct": \{' -A 16
"fs_struct": {
"size": 0,
"fields": {
"_unused": {
"type": {
"count": 0,
"kind": "array",
"subtype": {
"kind": "base",
"name": "u8"
}
},
"offset": 0
}
},
"kind": "struct"
},
Applying the following diff :
diff --git a/main.go b/main.go
index 6910a01..f88ee2c 100644
--- a/main.go
+++ b/main.go
@@ -206,8 +206,16 @@ func (doc *vtypeJson) addStruct(structType *dwarf.StructType, name, endian strin
Kind: structType.Kind,
}
+ debug := false
+ if structName(structType) == "fs_struct" {
+ debug = true
+ fmt.Printf("Processing Struct: %s\n", structName(structType))
+ }
anonymousCount := 0
for _, field := range structType.Field {
+ if debug == true {
+ fmt.Printf("Processing field: %s\n", field)
+ }
if field == nil {
continue
}
We can notice :
Processing Struct: fs_struct
Processing field: &{users int %!s(int64=0) %!s(int64=0) %!s(int64=0) %!s(int64=0) %!s(int64=0)}
Processing field: &{lock spinlock_t %!s(int64=4) %!s(int64=0) %!s(int64=0) %!s(int64=0) %!s(int64=0)}
Processing field: &{seq seqcount_spinlock_t %!s(int64=8) %!s(int64=0) %!s(int64=0) %!s(int64=0) %!s(int64=0)}
Processing field: &{umask int %!s(int64=12) %!s(int64=0) %!s(int64=0) %!s(int64=0) %!s(int64=0)}
Processing field: &{in_exec int %!s(int64=16) %!s(int64=0) %!s(int64=0) %!s(int64=0) %!s(int64=0)}
Processing field: &{root struct path %!s(int64=24) %!s(int64=0) %!s(int64=0) %!s(int64=0) %!s(int64=0)}
Processing field: &{pwd struct path %!s(int64=40) %!s(int64=0) %!s(int64=0) %!s(int64=0) %!s(int64=0)}
Processing Struct: fs_struct
Processing field: &{_unused [0]u8 %!s(int64=0) %!s(int64=0) %!s(int64=0) %!s(int64=0) %!s(int64=0)}
Processing Struct: fs_struct
Processing field: &{_unused [0]u8 %!s(int64=0) %!s(int64=0) %!s(int64=0) %!s(int64=0) %!s(int64=0)}
As https://github.com/volatilityfoundation/dwarf2json/blob/master/main.go#L283 erases the existing key, it seems the malformed ones are overwriting the correct structures. This affects a few ones (~15), but I haven't found the exact reason for it yet.
fwiw, this (somewhat dirty) patch seems to handle the issue:
diff --git a/main.go b/main.go
index 6910a01..f289c5c 100644
--- a/main.go
+++ b/main.go
@@ -206,6 +206,10 @@ func (doc *vtypeJson) addStruct(structType *dwarf.StructType, name, endian strin
Kind: structType.Kind,
}
+ if _, ok := doc.UserTypes[name]; ok && structType.Size() == 0 {
+ return nil
+ }
+
anonymousCount := 0
for _, field := range structType.Field {
if field == nil {
not yet sure how it affects other rust-overwritten C structs
The patch suggested by @ptrcnull worked for me in volatilityfoundation/volatility3!1238
@gcmoreira Does the linked PR resolve your issue as well?
@mkonshie yes, it works with !1238 . Thanks