32-bit socketcalls were not being logged by audit on x86_64 systems. Log them. This is basically a duplicate of the call from net/socket.c:sys_socketcall(), but it addresses the impedance mismatch between 32-bit userspace process and 64-bit kernel audit. See: https://github.com/linux-audit/audit-kernel/issues/14
Unified · Split
| @@ -387,6 +387,20 @@ static inline int audit_socketcall(int nargs, unsigned long *args) · 386 unmodified lines | |||
| 387 | return __audit_socketcall(nargs, args); | 387 | return __audit_socketcall(nargs, args); |
| 388 | return 0; | 388 | return 0; |
| 389 | } | 389 | } |
| 390 | |||
| 391 | static inline int audit_socketcall_compat(int nargs, u32 *args) | ||
| 392 | { | ||
| 393 | unsigned long a[AUDITSC_ARGS]; | ||
| 394 | int i; | ||
| 395 | |||
| 396 | if (audit_dummy_context()) | ||
| 397 | return 0; | ||
| 398 | |||
| 399 | for (i = 0; i < nargs; i++) | ||
| 400 | a[i] = (unsigned long)args[i]; | ||
| 401 | return __audit_socketcall(nargs, a); | ||
| 402 | } | ||
| 403 | |||
| 390 | static inline int audit_sockaddr(int len, void *addr) | 404 | static inline int audit_sockaddr(int len, void *addr) |
| 391 | { | 405 | { |
| 392 | if (unlikely(!audit_dummy_context())) | 406 | if (unlikely(!audit_dummy_context())) |
| @@ -513,6 +527,12 @@ static inline int audit_socketcall(int nargs, unsigned long *args) · 120 unmodified lines | |||
| 513 | { | 527 | { |
| 514 | return 0; | 528 | return 0; |
| 515 | } | 529 | } |
| 530 | |||
| 531 | static inline int audit_socketcall_compat(int nargs, u32 *args) | ||
| 532 | { | ||
| 533 | return 0; | ||
| 534 | } | ||
| 535 | |||
| 516 | static inline void audit_fd_pair(int fd1, int fd2) | 536 | static inline void audit_fd_pair(int fd1, int fd2) |
| 517 | { } | 537 | { } |
| 518 | static inline int audit_sockaddr(int len, void *addr) | 538 | static inline int audit_sockaddr(int len, void *addr) |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | |||
| 22 | #include <linux/filter.h> | 22 | #include <linux/filter.h> |
| 23 | #include <linux/compat.h> | 23 | #include <linux/compat.h> |
| 24 | #include <linux/security.h> | 24 | #include <linux/security.h> |
| 25 | #include <linux/audit.h> | ||
| 25 | #include <linux/export.h> | 26 | #include <linux/export.h> |
| 26 | 27 | ||
| 27 | #include <net/scm.h> | 28 | #include <net/scm.h> |
| @@ -781,14 +782,24 @@ COMPAT_SYSCALL_DEFINE5(recvmmsg, int, fd, struct compat_mmsghdr __user *, mmsg, · 753 unmodified lines | |||
| 781 | 782 | ||
| 782 | COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) | 783 | COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) |
| 783 | { | 784 | { |
| 784 | int ret; | 785 | u32 a[AUDITSC_ARGS]; |
| 785 | u32 a[6]; | 786 | unsigned int len; |
| 786 | u32 a0, a1; | 787 | u32 a0, a1; |
| 788 | int ret; | ||
| 787 | 789 | ||
| 788 | if (call < SYS_SOCKET || call > SYS_SENDMMSG) | 790 | if (call < SYS_SOCKET || call > SYS_SENDMMSG) |
| 789 | return -EINVAL; | 791 | return -EINVAL; |
| 790 | if (copy_from_user(a, args, nas[call])) | 792 | len = nas[call]; |
| 793 | if (len > sizeof(a)) | ||
| 794 | return -EINVAL; | ||
| 795 | |||
| 796 | if (copy_from_user(a, args, len)) | ||
| 791 | return -EFAULT; | 797 | return -EFAULT; |
| 798 | |||
| 799 | ret = audit_socketcall_compat(len / sizeof(a[0]), a); | ||
| 800 | if (ret) | ||
| 801 | return ret; | ||
| 802 | |||
| 792 | a0 = a[0]; | 803 | a0 = a[0]; |
| 793 | a1 = a[1]; | 804 | a1 = a[1]; |
| 794 | 805 | ||