Re: Fwd: How to extract linux kernel version information from a kernel image?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 9/25/2020 4:06 PM, Kayaalp, Mehmet wrote:
On 9/24/20 4:05 PM, Raphael Gianotti wrote:
Forwarding this here since the final intent here is an IMA related
change to see if anyone has any suggestions.


-------- Forwarded Message --------
Subject:        How to extract linux kernel version information from a
kernel
image?
Date:   Fri, 18 Sep 2020 12:47:13 -0700
From:   Raphael Gianotti <raphgi@xxxxxxxxxxxxxxxxxxx>
To:     linux-kernel@xxxxxxxxxxxxxxx



Hi,

I have been investigating a way to extract the version strong from a
kernel image (e.g., vmlinux). The version string I've been looking at is
essentially the linux_banner symbol.

We'll use IMA to measure the version string on the kexec system call,
providing a way for an attestation service, for instance, to attest to
what version of the kernel is running on the client.

I haven't found a way to extract the version from the image that isn't
simply searching the whole image for it. I was hoping someone here may
be able to point me to a better approach to retrieve the linux_banner
symbol value from an image or  any existing kernel code that does
similar parsing.

If that matters for any suggestions, my current focus is on ARM64 images
(if the code ends up having to be arch specific).

Thanks,

-Raphael

In Linux/x86 Boot Protocol [1], the kernel header contains a pointer to
the kernel_version string at offset 020E (2-byte value):

      # hexdump -s 0x020E -n 2 -e '/2 "%x"'
/boot/vmlinuz-5.4.0-48-generic; echo
      3900

Starting after the header (512 bytes), the string is 0x3900 bytes into
the vmlinuz file:

      # dd bs=1 skip=$((0x3900+512)) if=/boot/vmlinuz-5.4.0-48-generic
|tr -s '\000' '\n'|head -n 1
      5.4.0-48-generic (buildd@lcy01-amd64-010) #52-Ubuntu SMP Thu Sep 10
10:58:49 UTC 2020

In ARM64, the vmlinux is stripped of symbols and compressed into the
bzImage. To find the linux_banner, System.map file is needed:

      # grep ' linux_banner$' /boot/System.map-5.4.0-48-generic
      ffff800010df00d0 R linux_banner

The offset into the file can be found by subtracting the load address:

      # grep ' _head$' /boot/System.map-5.4.0-48-generic
      ffff800010080000 t _head

      # zcat /boot/vmlinuz-5.4.0-48-generic | dd bs=1
skip=$((0xffff800010df00d0-0xffff800010080000)) | tr -s '\000' '\n' |
head -n 1
      Linux version 5.4.0-48-generic (buildd@bos02-arm64-053) (gcc
version 9.3.0 (Ubuntu 9.3.0-10ubuntu2)) #52-Ubuntu SMP Thu Sep 10
11:01:50 UTC 2020 (Ubuntu 5.4.0-48.52-generic 5.4.60)

[1]: https://www.kernel.org/doc/html/latest/x86/boot.html

Mehmet

Regarding the arm64 vmlinux files, I've noticed in some, if you run the file command for them in the terminal, it does give a "not stripped" string in its result. Also, for those files, objdump does print out symbols, including linux_banner. I've found that out last Friday and I am in the process of looking at what the code for objdump to see how it finds the symbols there and see if I can get its value from the image. I wonder if I am missing something and that reported linux_banner symbol I get from objdump is not what I think it is, so do let me know if I am just wasting my time in investigating that when it comes to arm64.

Thanks,

Raphael




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux Kernel]     [Linux Kernel Hardening]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux