Bug 1321096 - BUG: s390 socketcall() syscalls audited with wrong value in field a0
Summary: BUG: s390 socketcall() syscalls audited with wrong value in field a0
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: kernel   
(Show other bugs)
Version: 7.2
Hardware: s390x Linux
unspecified
unspecified
Target Milestone: rc
: 7.3
Assignee: Paul Moore
QA Contact: Jiri Jaburek
URL:
Whiteboard:
Keywords: Reproducer
Depends On:
Blocks: 1256920 1296594
TreeView+ depends on / blocked
 
Reported: 2016-03-24 16:17 UTC by Miroslav Vadkerti
Modified: 2017-01-06 17:48 UTC (History)
7 users (show)

Fixed In Version: kernel-3.10.0-457.el7
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2016-11-03 16:17:00 UTC
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
bz1321096_test.c (451 bytes, text/x-csrc)
2016-06-22 20:21 UTC, Paul Moore
no flags Details
01-bz1321096.patch (1.74 KB, patch)
2016-06-27 14:46 UTC, Paul Moore
no flags Details | Diff


External Trackers
Tracker ID Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2016:2574 normal SHIPPED_LIVE Important: kernel security, bug fix, and enhancement update 2016-11-03 12:06:10 UTC

Description Miroslav Vadkerti 2016-03-24 16:17:30 UTC
Description of problem:
While testing with improved network Common Criteria tests on s390x (31bit) we discovered that audit events have wrong a0 field.

[root@ibm-z-22 network]$ ausearch -ts recent -m SYSCALL
----
time->Thu Mar 24 17:05:10 2016
type=SOCKADDR msg=audit(1458835510.860:652): saddr=000AA036000000000000000000000000000000000000000100000000
type=SYSCALL msg=audit(1458835510.860:652): arch=16 syscall=102 success=yes exit=21 a0=ffffffff0000000b a1=3ff7f82e3c0 a2=3ff00000000 a3=a72028 items=0 ppid=9510 pid=9512 auid=1000 uid=0 gid=0 euid=0 suid=0 fsui
tty=pts1 ses=7 comm="do_socketcall" exe="/usr/local/eal4_testing/audit-test/utils/bin/do_socketcall" subj=system_u:system_r:unconfined_t:s0 key=(null)

[root@ibm-z-22 network]$ ausearch -ts recent -m SYSCALL -i
----
type=SOCKADDR msg=audit(03/24/2016 17:05:10.860:652) : saddr=inet6 host:::1 serv:41014 
type=SYSCALL msg=audit(03/24/2016 17:05:10.860:652) : arch=s390 syscall=socketcall success=yes exit=21 a0=conversion error(ffffffff0000000b) a1=0x3ff7f82e3c0 a2=0x3ff00000000 a3=0xa72028 items=0 ppid=9510 pid=95
oot euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts1 ses=7 comm=do_socketcall exe=/usr/local/eal4_testing/audit-test/utils/bin/do_socketcall subj=system_u:system_r:unconfined_t:s0 key=(null

------

Notice the a0=ffffffff0000000b and interpreted a0=conversion error(ffffffff0000000b)

Version-Release number of selected component (if applicable):
kernel-3.10.0-327.10.1.el7

How reproducible:
100%

Steps to Reproduce:
0. Have an s390x machine
1. Download and build with -m31
http://git.engineering.redhat.com/git/users/jjaburek/audit-test-rhel7.git/tree/audit-test/utils/bin/do_socketcall.c
2. auditctl -a exit,always -F arch=b32
3. ./do_socketcall sendto ::1 41014:4100
4. ausearch -ts recent -m SYSCALL | grep 00b 

Actual results:
field a0=ffffffff0000000b

Expected results:
field a0=b

Additional info:
This does not seem to be a regression, but we should fix it in RHEL7.3 if possible. I see this in RHEL7.1.z also and might be it is appearing on other archs also.

Comment 1 Paul Moore 2016-03-24 19:17:14 UTC
Do you happen to have the raw, unprocessed audit records available still?  If so, it would be nice to see those instead of the results from ausearch.

Comment 2 Miroslav Vadkerti 2016-03-29 08:24:49 UTC
Yes, of course. I even have the machine reserved, if you would need to access it.

Here is the rew record from audit.log:

type=SYSCALL msg=audit(1459239702.446:248): arch=16 syscall=102 success=yes exit=21 a0=ffffffff0000000b a1=3ff7f90c3d0 a2=3ff00000000 a3=426028 items=0 ppid=53322 pid=53324 auid=1000 uid=0 gid=0 euid=0 suid=0 fs
0 tty=pts1 ses=2 comm="do_socketcall" exe="/usr/local/eal4_testing/audit-test/utils/bin/do_socketcall" subj=system_u:system_r:unconfined_t:s0 key=(null)
type=SOCKADDR msg=audit(1459239702.446:248): saddr=000ACD6D000000000000000000000000000000000000000100000000

Comment 3 Paul Moore 2016-03-29 20:19:11 UTC
Thanks, it looks like we definitely have a problem sending 64-bit values for a 32/31-bit ABI.

Comment 4 Paul Moore 2016-06-07 19:38:55 UTC
It would appear that the registers passed into audit_syscall_entry() are not masked in the case of s390; compare the code in arch/s390/include/asm/syscall.h:syscall_get_arguments() with arch/390/kernel/ptrace.c:do_syscall_trace_enter().

>>>
static inline void syscall_get_arguments(struct task_struct *task,
                                         struct pt_regs *regs,
                                         unsigned int i, unsigned int n,
                                         unsigned long *args)
{
        unsigned long mask = -1UL;

        BUG_ON(i + n > 6);
#ifdef CONFIG_COMPAT
        if (test_tsk_thread_flag(task, TIF_31BIT))
                mask = 0xffffffff;
#endif
        while (n-- > 0)
                if (i + n > 0)
                        args[n] = regs->gprs[2 + i + n] & mask;
        if (i == 0)
                args[0] = regs->orig_gpr2 & mask;
}
>>>

>>>
asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
{
        long ret = 0;

        /* Do the secure computing check first. */
        if (secure_computing()) {
                /* seccomp failures shouldn't expose any additional code. */
                ret = -1;
                goto out;
        }

        /*
         * The sysc_tracesys code in entry.S stored the system
         * call number to gprs[2].
         */
        if (test_thread_flag(TIF_SYSCALL_TRACE) &&
            (tracehook_report_syscall_entry(regs) ||
             regs->gprs[2] >= NR_syscalls)) {
                /*
                 * Tracing decided this syscall should not happen or the
                 * debugger stored an invalid system call number. Skip
                 * the system call and the system call restart handling.
                 */
                clear_pt_regs_flag(regs, PIF_SYSCALL);
                ret = -1;
        }

        if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
                trace_sys_enter(regs, regs->gprs[2]);

        audit_syscall_entry(regs->gprs[2], regs->orig_gpr2,
                            regs->gprs[3], regs->gprs[4],
                            regs->gprs[5]);
out:
        return ret ?: regs->gprs[2];
}
>>>

Comment 5 Paul Moore 2016-06-07 19:51:12 UTC
Completely untested and unsubmitted code:

>>>
commit 72715d6884c24ac0d3438ab718e09736a7acadf7
Author: Paul Moore <paul@paul-moore.com>
Date:   Tue Jun 7 15:41:38 2016 -0400

    s390: ensure that syscall arguments are properly masked on s390
    
    When executing s390 code on s390x the syscall arguments are not
    properly masked, leading to some malformed audit records.
    
    Signed-off-by: Paul Moore <paul@paul-moore.com>

diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 49b1c13..ac1dc74 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -822,6 +822,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
 {
        long ret = 0;
+       unsigned long mask = -1UL;
 
        /* Do the secure computing check first. */
        if (secure_computing()) {
@@ -849,9 +850,13 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
        if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
                trace_sys_enter(regs, regs->gprs[2]);
 
-       audit_syscall_entry(regs->gprs[2], regs->orig_gpr2,
-                           regs->gprs[3], regs->gprs[4],
-                           regs->gprs[5]);
+#ifdef CONFIG_COMPAT
+        if (test_thread_flag(TIF_31BIT))
+                mask = 0xffffffff;
+#endif
+       audit_syscall_entry(regs->gprs[2], regs->orig_gpr2 & mask,
+                           regs->gprs[3] & mask, regs->gprs[4] & mask,
+                           regs->gprs[5] & mask);
 out:
        return ret ?: regs->gprs[2];
 }
>>>

Comment 8 Murphy Zhou 2016-06-17 09:11:05 UTC
Has the patch been merged into upstream yet?

Comment 9 Paul Moore 2016-06-17 12:45:38 UTC
(In reply to xzhou from comment #8)
> Has the patch been merged into upstream yet?

No, the patch in comment #5 is still completely untested.  I'm hoping to be able to test it soon, but if you have access to a s390x system and are able to test it that would be very helpful.

Comment 10 Murphy Zhou 2016-06-20 01:55:21 UTC
(In reply to Paul Moore from comment #9)
> (In reply to xzhou from comment #8)
> > Has the patch been merged into upstream yet?
> 
> No, the patch in comment #5 is still completely untested.  I'm hoping to be
> able to test it soon, but if you have access to a s390x system and are able
> to test it that would be very helpful.

Sorry i can't reproduce this issue.

Comment 12 Paul Moore 2016-06-22 20:21 UTC
Created attachment 1171074 [details]
bz1321096_test.c

Simplified test tool that doesn't require the full audit-test harness to be installed.

Download and compile the test tool source:

  # gcc -o bz1321096_test -g -O0 -m31 bz1321096_test.c

Run the test:

  # auditctl -D
  # auditctl -a exit,always -F arch=b32
  # ./bz1321096_test
  RHBZ #1321096: starting test ...
  RHBZ #1321096: result = -1
  # ausearch -i -ts recent -m SYSCALL | grep syscall=socketcall
  type=SYSCALL msg=audit(06/22/2016 16:14:55.674:242) : arch=s390   
    syscall=socketcall(socket) success=no exit=EFAULT(Bad address) a0=socket 
    a1=0x2 a2=0x3 a3=0x4 items=0 ppid=10272 pid=10498 auid=root uid=root gid=root 
    euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts1 ses=8 
    comm=bz1321096_test exe=/root/sources/bz1321096/bz1321096_test 
    subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)

Comment 13 Paul Moore 2016-06-22 20:23:35 UTC
Using the patch in comment #5 and the test in comment #12, it appears that this problem is fixed.  I'll post the fix upstream today and then we can backport it to RHEL-7.x once we have basic acceptance upstream.

Comment 14 Paul Moore 2016-06-22 20:46:25 UTC
Patch posted upstream:

 * https://www.redhat.com/archives/linux-audit/2016-June/msg00051.html

Comment 17 Miroslav Vadkerti 2016-06-23 06:52:10 UTC
We can provide automatic test coverage for this issue. Setting myself as QA contact.

Comment 20 Murphy Zhou 2016-06-23 10:29:13 UTC
(In reply to Miroslav Vadkerti from comment #17)
> We can provide automatic test coverage for this issue. Setting myself as QA
> contact.

Thank you very much!

Comment 23 Paul Moore 2016-06-27 14:46 UTC
Created attachment 1172907 [details]
01-bz1321096.patch

Comment 27 Rafael Aquini 2016-06-30 15:32:10 UTC
Patch(es) committed on kernel repository and an interim kernel build is undergoing testing

Comment 29 Rafael Aquini 2016-07-01 14:30:29 UTC
Patch(es) available on kernel-3.10.0-457.el7

Comment 36 errata-xmlrpc 2016-11-03 16:17:00 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://rhn.redhat.com/errata/RHSA-2016-2574.html


Note You need to log in before you can comment on or make changes to this bug.