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