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
  • /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 assume x86_64 undoubtedly supports 32-bit too, mapping known architectures to compatibility doesn't seem the most reliant or efficient way of solving this particular problem
  • hwinfo is not on the machine
  • getconf LONG_BIT checks 64-bit compatibility
  • lshw 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?

  • What do you need to know exactly? What do you mean precisely by “Does the system support the 32-bit syscall table?” Note that whatever you mean, you are on an XY path because what the CPU supports and what the OS supports are very different questions. Do you care only about Linux? Do you care only about x86? – Gilles 'SO- stop being evil' Jul 17 '18 at 19:28
  • Recommended reading: unix.stackexchange.com/questions/134391/… – Gilles 'SO- stop being evil' Jul 17 '18 at 19:30
  • The full unaltered quote is this: "Additionally, the following rule is required in systems supporting the 32-bit syscall table (such as i686 and x86_64)." They reference the chown and chown32 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. – Joshua Detwiler Jul 17 '18 at 19:34
  • I don't think it is a dupe and some users in chat thought it was an interesting question, so I undeleted to give them a chance that answer. – terdon Jul 17 '18 at 21:58
  • This is not covered by any question I know of on this site. I don't even know if there is an architecture-agnostic way to answer this and if there is a syscall-independent way to answer this: different architectures have different syscall histories, three may be multiple variants of one syscall on an architecture (not necessarily just 32-bit/64-bit) but not on another. – Gilles 'SO- stop being evil' Jul 17 '18 at 22:07

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.

| improve this answer | |
  • 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 older lchown (now lchown16) which takes 16-bit user IDs. You can find syscall names by searching for T 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' Jul 18 '18 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 in kallsyms 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 support chown32 from 32-bit processes, that’s not visible in kallsyms. – Stephen Kitt Jul 18 '18 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. – Joshua Detwiler Jul 18 '18 at 13:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.