The context is the following:
Additionally, the following rule is required in systems supporting the 32-bit syscall table (such as i686 and x86_64).
I'm trying to figure out what this means, and how I can check whether my system needs this rule. They reference the chown
and chown32
commands/(syscalls, maybe), and continue to discuss system architecture around it. I only care about Linux but I don't only care about x86.
In the output of lscpu
, you have the field for CPU op-mode
which looks like:
CPU op-mode(s): 32-bit, 64-bit
for a x86_64
processor with dual architecture support. I presume that would show 32 or 64 only on systems not capable of interpreting the other's instructions.
My dilemma is figuring this out programmatically (I'll eventually write it as Python) on a legacy system without lscpu
on it. I've examined this question where they talk about finding 64-bit compatibility, but I'm struggling to make use of these in the opposite use case.
So to summarize why this is a problem so far:
lscpu
is not the machine- I've ran
sudo find / -iregex .*lscpu.*
to make sure
- I've ran
/proc/cpuinfo
explains 64-bit compatibility through flags ending in_lm
(not 32-bit compatibility, as far as I'm aware)uname
is insufficient: it displays the primary architecture, and while it's safe to assumex86_64
undoubtedly supports 32-bit too, mapping known architectures to compatibility doesn't seem the most reliant or efficient way of solving this particular problemhwinfo
is not on the machinegetconf LONG_BIT
checks 64-bit compatibilitylshw
is not on the machine
It's possible I've overlooked something and equally possible I don't understand enough about the subject as a programmer. Could someone please help me understand how to programmatically—meaning some method of obtaining an exact or parsable output—check if my system has 32-bit compatibility?
1 Answer 1
I take it you’re following the RHEL 5 Security Technical Implementation Guide.
"Does my Linux system support the 32-bit syscall table?" is a very interesting question and, as Gilles mentions, not one which has conclusively been addressed on the site. It’s also a tough question to answer.
I’ll start by reducing it to the STIG context, i.e. "Does my Linux system support the i386 syscall table?" (We’ll revisit the more general issue later.) You can’t obtain a definitive list of supported syscalls from a running kernel, but in this case we don’t need to: all we need to do is look for the syscall entry points. The i386 entry points are conveniently named: the externally-visible functions used by both the native 32-bit calls and the 64- to 32-bit emulation layer are do_fast_syscall_32
and do_int80_syscall_32
. The best way to check for those is to look for them in /proc/kallsyms
(I’m hoping there isn’t another STIG rule which forbids that...). If they’re present, then the current kernel supports i386 system calls, and you need the lchown32
audit rule.
Reading through the other answers on this sort of topic here, you’ll gather that a typical way of testing for system call support on a running system is to try to call the system call. When auditing a system that might not be appropriate since it should trigger an audit rule. It also can result in false negatives when auditing since it typically relies both on the kernel supporting the relevant system call, and the system providing the necessary framework.
Using the results of lscpu
and other similar tools is also misleading since they report the installed CPU’s capabilities, not the system’s. For example, lscpu
hard-codes equivalencies: lm
, zarch
, or sun4[uv]
in the CPU flags tell it that 32- and 64-bit support is available, which it is from the CPU’s perspective, but lscpu
doesn’t determine whether the rest of the system supports it too (nor should it).
Revisiting the more general issue, "Does my Linux system support the 32-bit syscall table?", determining the answer will always depend on the architecture. If we try to look at system calls to determine the answer, we need to take into account the system call history on the architecture; for example, chown32
and siblings aren’t necessarily supported on 32-bit architectures. Likewise, looking for entry points is architecture-dependent.
Thus I don’t think there is a general answer to your question; answers have to take into account at least the target architecture.
-
Another subtlety here is that the 32 in
lchown32
does not mean "32-bit instruction" set, it means "32-bit user IDs", as opposed to the olderlchown
(nowlchown16
) which takes 16-bit user IDs. You can find syscall names by searching forT sys_.*
entries in/proc/kallsyms
, but what you see is the kernel function names, and I don't know how systematically they map to the syscall names for use in audit rules.Gilles 'SO- stop being evil'– Gilles 'SO- stop being evil'2018年07月18日 09:23:50 +00:00Commented Jul 18, 2018 at 9:23 -
Right, the relevance of
chown32
here is that it’s the call listed in the STIG ;-). On x86, it has the additional characteristic of only being present in the 32-bit syscall table, not the 64-bit one.sys_
entries inkallsyms
list functions implementing syscalls, as you mention, but from userspace what we’re really after is the mapping from numbers to functions, which isn’t available — so while a typical 64-bit x86 kernel does supportchown32
from 32-bit processes, that’s not visible inkallsyms
.Stephen Kitt– Stephen Kitt2018年07月18日 09:45:41 +00:00Commented Jul 18, 2018 at 9:45 -
Yes you're right that I'm referring to V-29252, 29253, and 29257. Also, I'm surprised by the level of difficulty here compared to the other rules I've encountered. Upon first glance of their implementation in XML (yes...you read that right), I thought they were merely checking 32/64-bit program capability. But, after digging deeper, I see they're actually checking an enumeration of architectures.user233770– user2337702018年07月18日 13:30:08 +00:00Commented Jul 18, 2018 at 13:30
chown
andchown32
commands/(syscalls, maybe), and continue to discuss system architecture around it. Also yes I only care about Linux but I don't only care about x86.