From 255716b90ac7fb45c92e06e7f377e25890a93f9c Mon Sep 17 00:00:00 2001 From: Christian Boltz Date: Sun, 24 Oct 2021 14:19:10 +0200 Subject: [PATCH] Add support for reading s390x and aarch64 wtmp file Both aarch64 and s390x have a bigger wtmp record size (16 bytes more than x86_64, 400 bytes total). The byte position of the timestamp is also different on each architecture. To make things even more interesting, s390x is big endian. Fixes: https://bugzilla.opensuse.org/show_bug.cgi?id=1181155 --- utils/apparmor/notify.py | 46 ++++++++++++++++-- utils/test/test-notify.py | 5 ++ utils/test/wtmp-examples/wtmp-aarch64 | Bin 0 -> 800 bytes .../wtmp-aarch64-expected-output | 5 ++ utils/test/wtmp-examples/wtmp-s390x | Bin 0 -> 15200 bytes .../wtmp-examples/wtmp-s390x-expected-output | 13 +++++ 6 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 utils/test/wtmp-examples/wtmp-aarch64 create mode 100644 utils/test/wtmp-examples/wtmp-aarch64-expected-output create mode 100644 utils/test/wtmp-examples/wtmp-s390x create mode 100644 utils/test/wtmp-examples/wtmp-s390x-expected-output diff --git a/utils/apparmor/notify.py b/utils/apparmor/notify.py index 81d702972..1101a2934 100644 --- a/utils/apparmor/notify.py +++ b/utils/apparmor/notify.py @@ -22,6 +22,16 @@ from apparmor.common import AppArmorBug, DebugLogger debug_logger = DebugLogger('apparmor.notify') +def sane_timestamp(timestamp): + ''' Check if the given timestamp is in a date range that makes sense for a wtmp file ''' + + if timestamp < 946681200: # 2000-01-01 + return False + elif timestamp > 2524604400: # 2050-01-01 + return False + + return True + def get_last_login_timestamp(username, filename='/var/log/wtmp'): '''Directly read wtmp and get last login for user as epoch timestamp''' timestamp = 0 @@ -33,11 +43,37 @@ def get_last_login_timestamp(username, filename='/var/log/wtmp'): offset = 0 wtmp_filesize = os.path.getsize(filename) debug_logger.debug('WTMP filesize: {}'.format(wtmp_filesize)) + + if wtmp_filesize < 356: + return 0 # (nearly) empty wtmp file, no entries + + # detect architecture based on utmp format differences + wtmp_file.seek(340) # first possible timestamp position + timestamp_x86_64 = struct.unpack("L", wtmp_file.read(4))[0] + debug_logger.debug('WTMP timestamps: x86_64 %s, aarch64 %s, s390x %s' % (timestamp_x86_64, timestamp_aarch64, timestamp_s390x)) + + if sane_timestamp(timestamp_x86_64): + endianness = '<' # little endian + extra_offset_before = 0 + extra_offset_after = 0 + elif sane_timestamp(timestamp_aarch64): + endianness = '<' # little endian + extra_offset_before = 4 + extra_offset_after = 12 + elif sane_timestamp(timestamp_s390x): + endianness = '>' # big endian + extra_offset_before = 8 + extra_offset_after = 8 + else: + raise AppArmorBug('Your /var/log/wtmp is broken or has an unknown format. Please open a bugreport with /var/log/wtmp and the output of "last" attached!') + while offset < wtmp_filesize: wtmp_file.seek(offset) - offset += 384 # Increment for next entry + offset += 384 + extra_offset_before + extra_offset_after # Increment for next entry - type = struct.unpack(" zL?McFi!M>!gN{L`DCm-hjqMUa2)!S>j^i@#`yWRSI=j!@VbD$BZA9ost=J!8?zA}1vWGK=%K&*kn`Bs6@_~i;qjX(uCp2o95bwr)mj5j zz5MyS%;N*TpmHA2=ku`24Cn3eDD7XBctozghGTFZ(DN=FGpvpdkJ9IlGLLJ|U`aR+ zXukxG8CFM!M`^#k%%gK0mW21CG^8IjoXO{U2k!QJ#a8_&w=%2idGz`#w?%NYHT~L@ z>etf!k_Y_VUjO2kfPmYyHT_z}gQ!e+M48xo5~tmw3y#=+qOqv@Q38#8n~X&|#o^J8 z? z_bbi=st?5j<`J|$p!GxXfO!O6KbFY)p#B~Xm0Rj(EKwKd`RdHFbV}KQ->)DZsy@o1 z$zB8SVEw3lA5}j}rm=rJsgEOUR^4KYzkZaQhySZlGYF3+rb6{f9jpeckEY4ZsE?Cz z(`qB%R?4*Ecn1c))a~YI7n^^uYi_7Hdvh|+_I#x|u>E#94{03bP@#ZbJa&o?elG3W zR=89Su=+UqelzMLl`>(`e@#d)W?wUztuEN)rVVX!s8zs**%{1S0BxWjEDP7>IhN5F5cnY jrK(0*`_&1@>%)}sK>l7-)rTW1{f+R5@R27`v_Ad=&1z#R literal 0 HcmV?d00001 diff --git a/utils/test/wtmp-examples/wtmp-s390x-expected-output b/utils/test/wtmp-examples/wtmp-s390x-expected-output new file mode 100644 index 000000000..de4d5fff6 --- /dev/null +++ b/utils/test/wtmp-examples/wtmp-s390x-expected-output @@ -0,0 +1,13 @@ +linux1@opensuse03:~> last +linux1 pts/0 77.21.253.246 Thu Jul 15 13:06 still logged in +root pts/0 77.21.253.246 Thu Jul 15 13:06 - 13:06 (00:00) +linux1 pts/0 77.21.253.246 Thu Jul 15 13:01 - 13:05 (00:04) +linux1 pts/0 94.134.117.140 Thu Jul 15 08:15 - 08:16 (00:01) +linux1 pts/0 10.6.22.160 Tue Jul 13 07:42 - 07:42 (00:00) +reboot system boot 5.3.18-24.67-def Tue Jul 13 07:41 still running +linux1 pts/0 10.6.22.160 Tue Jul 13 07:41 - 07:41 (00:00) +linux1 pts/0 10.6.22.160 Tue Jul 13 07:37 - 07:41 (00:03) +reboot system boot 5.3.18-24.64-def Tue Jul 13 07:30 - 07:41 (00:11) + +wtmp beginnt Tue Jul 13 07:30:36 2021 +linux1@opensuse03:~>