32bit and 64bit syscall issues

Chris Wright chrisw at osdl.org
Sat Mar 12 01:24:02 UTC 2005


* Debora Velarde (dvelarde at us.ibm.com) wrote:
> Our current audit solution has some problems when a user tries to audit
> 32bit syscalls on x86_64 systems.  (This is a CAPP requirement.)
> Most of the problems are due to the fact that there are two unistd.h files
> on x86_64 systems.
> 64bit syscalls are defined in /usr/include/asm-x86_64/unistd.h
> 32bit syscalls are defined in /usr/include/asm-i386/unistd.h
> In these two files, the syscall numbers assigned to syscall names are not
> the same.
>       For example:
>       From /usr/include/asm-i386/unistd.h:
>             #define __NR_fork 2
>             #define __NR_open 5
>       From /usr/include/asm-x86_64/unistd.h:
>             #define __NR_open 2
>             #define __NR_fstat      5

Yes, we've touched on this a few times on calls.

> ---------------
> Problem 1:
> "auditctl -t" always translates numbers to name based on
> /usr/include/asm-x86_64/unistd.h
> (When compiled in 64bit mode on a 64bit system).
> 
> Possible Solution 1:
> Modify /usr/include/asm-i386/unistd.h and /usr/include/asm-x86_64/unistd.h
> so that the 32bit and the 64bit syscall number of any syscall are the same
> number.

This is an absolute no-go.  That would _seriously_ break any notion of
binary compatibility.  So, the syscall numbers per-arch can't change,

> Possible Solution 2:
> Modify auditctl to return both 32bit and 64bit syscall names associated
> with that number.  This will require a change in how Steve creates his
> table.
>       Example:
>             auditctl -t 2
>            Would Return:
>             32bit: fork
>             64bit: open
> 
> Possible Solution 3:
> Modify auditctl -t option to require an additional flag indicating whether
> the 32bit or the 64bit syscall number should be returned.  Could possibly
> use the "-F pers=" flag.

This makes most sense.

> ---------------
> Problem 2:
> "audictl -a" rule also always translates numbers to the syscall name found
> in /usr/include/asm-x86_64/unistd.h

Even with pers flag?

> Possible Solution 1:
> Modify /usr/include/asm-i386/unistd.h and /usr/include/asm-x86_64/unistd.h
> so that the 32bit and the 64bit syscall number of any syscall are the same
> number.

Heh, see above.

> Possible Solution 2:
> auditctl -a <l,a> -S <syscall name> should require additional flag
> indicating if 32bit, 64bit, or both syscalls should be audited.  Could
> possibly use the "pers" flag, assuming personality can determine if a
> syscall was compiled 32bit or 64bit.
> Then audit rule(s) can be added for the correct syscall number(s).
> auditctl -A, and auditctl -d rules would also need to be changed.
> 
> ---------------
> Problem 3:
> Personality is currently always 0 by default.  We can NOT assume that an
> application will manually set personality to another number.  Therefore we
> cannot currently use the "pers" flag to determine if a syscall was executed
> from a 32bit or a 64bit compiled program.

What does this mean?  It's the ELF headers that will describe how the
program is treated.  What am I missing?

> Possible Solution 1:
> Modify /usr/include/asm-i386/unistd.h and /usr/include/asm-x86_64/unistd.h
> so that the 32bit and the 64bit syscall number of any syscall are the same
> number.
> Then we would not need to filter on "pers" flag.

Again, no chance.

> Possible Solution 2:
> Fix personality so that it determines from the binary whether it was 32bit
> or 64bit.

What does this mean?

> ---------------
> Problem 4:
> Audit record does not indicate if a 32bit or a 64bit syscall was executed.
> Because of this, you are unable to determine which syscall resulted in an
> audit record.
> For example, we cannot currently determine if a record with "syscall=2"
> resulted from an __NR_open call (compiled 64bit) or a __NR_fork call
> (compiled 32bit) because
>       From /usr/include/asm-i386/unistd.h:
>             #define __NR_fork 2
>       From /usr/include/asm-x86_64/unistd.h:
>             #define __NR_open 2
> 
> Possible Solution 1:
> Modify /usr/include/asm-i386/unistd.h and /usr/include/asm-x86_64/unistd.h
> so that the 32bit and the 64bit syscall number of any syscall are the same
> number.

Again, no chance.

> Possible Solution 2:
> Fix 'pers' flag so that it can determine if it was a 32bit or 64bit
> syscall.  Currently 'pers' flag is included in the audit record if
> 'pers'!=0.

Is it not legit to assume native binary unless otherwise indicated?

> ---------------
> Problem 5:
> Some syscalls are not defined in either unistd.h file.  Therefore, auditctl
> -t is not able to translate the syscall number to a syscall name.  This is
> a usability problem for administrators.

Do you have examples?

> Possible Solution 1:
> Add these other syscalls (found in Klaus' syscalltab file, but not in
> unistd.h).
> 
> Possible Solution 2:
> Include an additional header file containing these other syscalls (found in
> Klaus' syscalltab file, but not in unistd.h) along with audit, so that
> audictl is able to translate those syscall numbers to name.

thanks,
-chris
-- 
Linux Security Modules     http://lsm.immunix.org     http://lsm.bkbits.net




More information about the Linux-audit mailing list