Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change to f-strings introduces ValueErrors in kmsg.py #1496

Closed
cQQkie-dev opened this issue Dec 30, 2024 · 0 comments · Fixed by #1502 or #1508
Closed

Change to f-strings introduces ValueErrors in kmsg.py #1496

cQQkie-dev opened this issue Dec 30, 2024 · 0 comments · Fixed by #1502 or #1508

Comments

@cQQkie-dev
Copy link

cQQkie-dev commented Dec 30, 2024

Describe the bug
I'm trying to analyze a Linux memory dump with volatility3 on the develop branch and kmsg.py throws "ValueError: Invalid format specifier" and "ValueError: Unknown format code 'u' for object of type 'int'". The problem seems to stem from commit e708a62, that changed string formatting in "volatility3/framework/plugins/linux/kmsg.py" to f-strings and introduces problems with the format specifiers ":lu" and ":u"

Context
Volatility Version: Volatility 3 Framework 2.14.0
Operating System: Ubuntu 22.04.5 LTS (my OS)
Python Version: Python 3.10.12
Suspected Operating System: Linux version 6.8.0-48-generic (buildd@lcy02-amd64-010) (x86_64-linux-gnu-gcc-13 (Ubuntu 13.2.0-23ubuntu4) 13.2.0, GNU ld (GNU Binutils for Ubuntu) 2.42) #48-Ubuntu SMP PREEMPT_DYNAMIC Fri Sep 27 14:04:52 UTC 2024 (Ubuntu 6.8.0-48.48-generic 6.8.12) (OS of dump)
Command: (venv) vol -f memory.dump linux.kmsg

To Reproduce
Steps to reproduce the behavior:

  1. Use command vol -f memory.dump linux.kmsg
  2. Python traceback
File "/home/user/git/volatility3/volatility3/framework/plugins/linux/kmsg.py", line 152, in nsec_to_sec_str
   return f"{nsec / 1000000000:lu}.{(nsec % 1000000000) / 1000:06lu}"
ValueError: Invalid format specifier

Expected behavior
Work correctly :)
Example output from stable branch and version 2.8.0

Volatility 3 Framework 2.8.0

facility        level   timestamp       caller  line

kern    notice  0.000000        Task(0) Linux version 6.8.0-48-generic (buildd@lcy02-amd64-010) (x86_64-linux-gnu-gcc-13 (Ubuntu 13.2.0-23ubuntu4) 13.2.0, GNU ld (GNU Binutils for Ubuntu) 2.42) #48-Ubuntu SMP PREEMPT_DYNAMIC Fri Sep 27 14:04:52 UTC 2024 (Ubuntu 6.8.0-48.48-generic 6.8.12)
kern    info    0.000000        Task(0) Command line: BOOT_IMAGE=/boot/vmlinuz-6.8.0-48-generic root=UUID=904d6c42-fc5d-4d9b-ad9c-3354e16b06c2 ro quiet splash
kern    info    0.000000        Task(0) KERNEL supported cpus:
kern    info    0.000000        Task(0)   Intel GenuineIntel
kern    info    0.000000        Task(0)   AMD AuthenticAMD
kern    info    0.000000        Task(0)   Hygon HygonGenuine
kern    info    0.000000        Task(0)   Centaur CentaurHauls
kern    info    0.000000        Task(0)   zhaoxin   Shanghai  
...

Example output

(venv) vol -f memory.dump linux.kmsg
Volatility 3 Framework 2.14.0
Progress:  100.00   Stacking attempts finished                  
facility  level timestamp caller  line
Traceback (most recent call last):
  File "/home/user/git/volatility3/vol3-venv/bin/vol", line 8, in <module>
    sys.exit(main())
  File "/home/user/git/volatility3/volatility3/cli/__init__.py", line 909, in main
    CommandLine().run()
  File "/home/user/git/volatility3/volatility3/cli/__init__.py", line 501, in run
    renderer.render(grid)
  File "/home/user/git/volatility3/volatility3/cli/text_renderer.py", line 232, in render
    grid.populate(visitor, outfd)
  File "/home/user/git/volatility3/volatility3/framework/renderers/__init__.py", line 241, in populate
    for level, item in self._generator:
  File "/home/user/git/volatility3/volatility3/framework/plugins/linux/kmsg.py", line 516, in _generator
    for values in ABCKmsg.run_all(context=self.context, config=self.config):
  File "/home/user/git/volatility3/volatility3/framework/plugins/linux/kmsg.py", line 105, in run_all
    yield from kmsg_inst.run()
  File "/home/user/git/volatility3/volatility3/framework/plugins/linux/kmsg.py", line 485, in run
    facility, level, timestamp, caller = self.get_prefix(info)
  File "/home/user/git/volatility3/volatility3/framework/plugins/linux/kmsg.py", line 177, in get_prefix
    self.get_timestamp_in_sec_str(obj),
  File "/home/user/git/volatility3/volatility3/framework/plugins/linux/kmsg.py", line 156, in get_timestamp_in_sec_str
    return self.nsec_to_sec_str(obj.ts_nsec)
  File "/home/user/git/volatility3/volatility3/framework/plugins/linux/kmsg.py", line 152, in nsec_to_sec_str
    return f"{nsec / 1000000000:lu}.{(nsec % 1000000000) / 1000:06lu}"
ValueError: Invalid format specifier

After fixing this error another one exists:

(venv) vol -f memory.dump linux.kmsg
Volatility 3 Framework 2.14.0
Progress:  100.00   Stacking attempts finished         
...
File "/home/user/git/volatility3/volatility3/framework/plugins/linux/kmsg.py", line 170, in get_caller_text
    caller = f"{caller_name}({caller_id & ~0x80000000:u})"
ValueError: Unknown format code 'u' for object of type 'int'

Additional information
Either reverting to the old formatting or rewritting the two offending lines fixes the problem:

git diff of commit e708a62:

+++ b/volatility3/framework/plugins/linux/kmsg.py
@@ -149,7 +149,7 @@ class ABCKmsg(ABC):
         #   This might seem insignificant but it could cause some issues
         #   when compared with userland tool results or when used in
         #   timelines.
-        return "%lu.%06lu" % (nsec / 1000000000, (nsec % 1000000000) / 1000)
+        return f"{nsec / 1000000000:lu}.{(nsec % 1000000000) / 1000:06lu}"

My git diff after applying changes:

diff --git a/volatility3/framework/plugins/linux/kmsg.py b/volatility3/framework/plugins/linux/kmsg.py
index d66e3b9c..40c277b5 100644
--- a/volatility3/framework/plugins/linux/kmsg.py
+++ b/volatility3/framework/plugins/linux/kmsg.py
@@ -149,7 +149,7 @@ class ABCKmsg(ABC):
         #   This might seem insignificant but it could cause some issues
         #   when compared with userland tool results or when used in
         #   timelines.
-        return f"{nsec / 1000000000:lu}.{(nsec % 1000000000) / 1000:06lu}"
+        return f"{nsec // 1000000000}.{(nsec % 1000000000) // 1000:06}"
 
     def get_timestamp_in_sec_str(self, obj) -> str:
         # obj could be log, printk_log or printk_info
@@ -166,7 +166,7 @@ class ABCKmsg(ABC):
 
     def get_caller_text(self, caller_id):
         caller_name = "CPU" if caller_id & 0x80000000 else "Task"
-        caller = f"{caller_name}({caller_id & ~0x80000000:u})"
+        caller = f"{caller_name}({int(caller_id & ~0x80000000)})"
         return caller
  1. kmsg.py, line 152: '''return f"{nsec / 1000000000:lu}.{(nsec % 1000000000) / 1000:06lu}" ''' can be turned into "return f"{nsec // 1000000000}.{(nsec % 1000000000) // 1000:06}""
  2. kmsg.py, line 170: "caller = f"{caller_name}({caller_id & ~0x80000000:u})"" => remove :u specifier or cast to int

Applying these changes, the behaviour is as intended

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant