lsof-org / lsof

LiSt Open Files
https://lsof.readthedocs.io
Other
414 stars 103 forks source link

[Question] Why embed the kernel version in LSOF_VSTR? #310

Closed kpcyrd closed 4 months ago

kpcyrd commented 6 months ago

Hello!

the test infrastructure for Reproducible Arch Linux has built lsof, trying to match the original binary distributed to users (in the same path, with the same compiler/library versions and noticed this difference:

│ │ ├── readelf --wide --decompress --hex-dump=.rodata {}
│ │ │ @@ -519,15 +519,15 @@
│ │ │    0x00025040 6663662d 70726f74 65637469 6f6e202d fcf-protection -
│ │ │    0x00025050 67202d66 66696c65 2d707265 6669782d g -ffile-prefix-
│ │ │    0x00025060 6d61703d 2f627569 6c642f6c 736f662f map=/build/lsof/
│ │ │    0x00025070 7372633d 2f757372 2f737263 2f646562 src=/usr/src/deb
│ │ │    0x00025080 75672f6c 736f6620 2d666c74 6f3d6175 ug/lsof -flto=au
│ │ │    0x00025090 746f202d 445f4649 4c455f4f 46465345 to -D_FILE_OFFSE
│ │ │    0x000250a0 545f4249 54533d36 34202d44 4c534f46 T_BITS=64 -DLSOF
│ │ │ -  0x000250b0 5f565354 523d2236 2e372e38 2d617263 _VSTR="6.7.8-arc
│ │ │ +  0x000250b0 5f565354 523d2236 2e372e34 2d617263 _VSTR="6.7.4-arc
│ │ │    0x000250c0 68312d31 22202d44 48415353 45435552 h1-1" -DHASSECUR
│ │ │    0x000250d0 49545920 2d444841 534e4f53 4f434b53 ITY -DHASNOSOCKS
│ │ │    0x000250e0 45435552 49545920 2d492f75 73722f69 ECURITY -I/usr/i
│ │ │    0x000250f0 6e636c75 64652f74 69727063 00000000 nclude/tirpc....
│ │ │    0x00025100 2d576c2c 2d4f3120 2d576c2c 2d2d736f -Wl,-O1 -Wl,--so
│ │ │    0x00025110 72742d63 6f6d6d6f 6e202d57 6c2c2d2d rt-common -Wl,--
│ │ │    0x00025120 61732d6e 65656465 64202d57 6c2c2d7a as-needed -Wl,-z

It seems LSOF_VSTR contains the output of $(uname -r), the kernel version number, is there a reason for this?

It seems the LSOF_VSTR string itself isn't actually embedded (used?) anywhere, but it ends up in CFLAGS which the binary records for lsof -v version output:

% lsof -v                   
lsof version information:
    revision: 4.99.3
    copyright notice: Copyright 1998 Purdue Research Foundation. All rights reserved.
    latest revision: https://github.com/lsof-org/lsof
    latest FAQ: https://github.com/lsof-org/lsof/blob/master/00FAQ
    latest (non-formatted) man page: https://github.com/lsof-org/lsof/blob/master/Lsof.8
    constructed on: x86_64-pc-linux-gnu
    compiler: gcc
    compiler version: 13.2.1 20230801 (GCC) 
    compiler flags: -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions         -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security         -fstack-clash-protection -fcf-protection -g -ffile-prefix-map=/build/lsof/src=/usr/src/debug/lsof -flto=auto -D_FILE_OFFSET_BITS=64 -DLSOF_VSTR="6.7.8-arch1-1" -DHASSECURITY -DHASNOSOCKSECURITY -I/usr/include/tirpc
    loader flags: -Wl,-O1 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now          -Wl,-z,pack-relative-relocs -flto=auto -ltirpc
    features enabled: ipv6 ptyept rpc soopt sostate tasks uxsockept
    Only root can list all files, but anyone can list socket files.
    /dev warnings are disabled.
    Kernel ID check is disabled.

Can this be set to an empty string, or maybe removed even? :)

Thanks!

jiegec commented 6 months ago

LSOF_VSTR is used in some os-specific code to validate that the runtime kernel version matches the compile-time one. That's because in some os, the data has to be read from data structures residing in kernel memory, so the data structure must not be changed between compilation and runtime, otherwise the data will be invalid.

However, since in Linux lsof reads the data from procfs, so the compatibility between lsof and different Linux kernel versions are much better. So it is not validated in Linux.