Skip to content

Commit 997abed

Browse files
committed
Linux lsof: Add namespace dentry name
1 parent e76d512 commit 997abed

File tree

1 file changed

+43
-3
lines changed

1 file changed

+43
-3
lines changed

volatility3/framework/symbols/linux/__init__.py

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,30 @@ def _get_new_sock_pipe_path(cls, context, task, filp) -> str:
169169
Returns:
170170
str: Sock pipe pathname relative to the task's root directory.
171171
"""
172+
# FIXME: This function must be moved to the 'dentry' object extension
173+
# Also, the scope of this function went beyond the sock pipe path, so we need to rename this.
174+
# Once https://github.com/volatilityfoundation/volatility3/pull/1263 is merged, replace the
175+
# dentry inode getters
176+
177+
if not (filp and filp.is_readable()):
178+
return f"<invalid file pointer> {filp:x}"
179+
172180
dentry = filp.get_dentry()
181+
if not (dentry and dentry.is_readable()):
182+
return f"<invalid dentry pointer> {dentry:x}"
173183

174184
kernel_module = cls.get_module_from_volobj_type(context, dentry)
175185

176186
sym_addr = dentry.d_op.d_dname
187+
if not (sym_addr and sym_addr.is_readable()):
188+
return f"<invalid d_dname pointer> {sym_addr:x}"
189+
177190
symbs = list(kernel_module.get_symbols_by_absolute_location(sym_addr))
178191

192+
inode = dentry.d_inode
193+
if not (inode and inode.is_readable() and inode.is_valid()):
194+
return f"<invalid dentry inode> {inode:x}"
195+
179196
if len(symbs) == 1:
180197
sym = symbs[0].split(constants.BANG)[1]
181198

@@ -191,13 +208,36 @@ def _get_new_sock_pipe_path(cls, context, task, filp) -> str:
191208
elif sym == "simple_dname":
192209
pre_name = cls._get_path_file(task, filp)
193210

211+
elif sym == "ns_dname":
212+
# From Kernels 3.19
213+
214+
# In Kernels >= 6.9, see Linux kernel commit 1fa08aece42512be072351f482096d5796edf7ca
215+
# ns_common->stashed change from 'atomic64_t' to 'dentry*'
216+
try:
217+
ns_common_type = kernel_module.get_type("ns_common")
218+
stashed_template = ns_common_type.child_template("stashed")
219+
stashed_type_full_name = stashed_template.vol.type_name
220+
stashed_type_name = stashed_type_full_name.split(constants.BANG)[-1]
221+
if stashed_type_name == "atomic64_t":
222+
# 3.19 <= Kernels < 6.9
223+
ns_ops = dentry.d_fsdata.dereference().cast(
224+
"proc_ns_operations"
225+
)
226+
else:
227+
# Kernels >= 6.9
228+
ns_common = inode.i_private.dereference().cast("ns_common")
229+
ns_ops = ns_common.ops
230+
231+
pre_name = utility.pointer_to_string(ns_ops.name, 255)
232+
except IndexError:
233+
ret = "<unsupported ns_common type>"
194234
else:
195-
pre_name = f"<unsupported d_op symbol: {sym}>"
235+
pre_name = f"<unsupported d_op symbol> {sym}"
196236

197-
ret = f"{pre_name}:[{dentry.d_inode.i_ino:d}]"
237+
ret = f"{pre_name}:[{inode.i_ino:d}]"
198238

199239
else:
200-
ret = f"<invalid d_dname pointer> {sym_addr:x}"
240+
ret = f"<unknown d_dname pointer> {sym_addr:x}"
201241

202242
return ret
203243

0 commit comments

Comments
 (0)