Implement decoding of linux socket filter programs

* bpf_sock_filter.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* xlat/skf_ad.in: New file.
* defs.h (decode_sock_fprog, print_sock_fprog): New prototypes.
* fetch_bpf_fprog.c (get_bpf_fprog_size): New mpers printer.
* net.c (print_getsockopt): Use decode_sock_fprog to print
socket filter programs for SO_GET_FILTER socket option.
(print_setsockopt): Use decode_sock_fprog and get_bpf_fprog_size
to print socket filter programs for SO_ATTACH_FILTER
and SO_ATTACH_REUSEPORT_CBPF socket options.
* NEWS: Mention this.
This commit is contained in:
Дмитрий Левин 2017-07-08 14:57:44 +00:00
parent e19354d350
commit bc515c7f54
7 changed files with 120 additions and 0 deletions

View File

@ -93,6 +93,7 @@ strace_SOURCES = \
bpf_filter.h \
bpf_fprog.h \
bpf_seccomp_filter.c \
bpf_sock_filter.c \
btrfs.c \
cacheflush.c \
capability.c \

2
NEWS
View File

@ -4,6 +4,8 @@ Noteworthy changes in release ?.?? (????-??-??)
* Improvements
* Enhanced decoding of optlen argument of getsockopt syscall.
* Enhanced decoding of SO_LINGER option of getsockopt and setsockopt syscalls.
* Implemented decoding of linux socket filter programs specified
for SO_ATTACH_FILTER and SO_ATTACH_REUSEPORT_CBPF socket options.
Noteworthy changes in release 4.18 (2017-07-05)
===============================================

71
bpf_sock_filter.c Normal file
View File

@ -0,0 +1,71 @@
/*
* Decoder of socket filter programs.
*
* Copyright (c) 2017 Dmitry V. Levin <ldv@altlinux.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "defs.h"
#include "bpf_filter.h"
#include <linux/filter.h>
#include "xlat/skf_ad.h"
static bool
print_sock_filter_k(const struct bpf_filter_block *const fp)
{
if (BPF_CLASS(fp->code) == BPF_LD && BPF_MODE(fp->code) == BPF_ABS) {
if (fp->k >= (unsigned int) SKF_AD_OFF) {
tprints("SKF_AD_OFF+");
printxval(skf_ad, fp->k - (unsigned int) SKF_AD_OFF,
"SKF_AD_???");
return true;
} else if (fp->k >= (unsigned int) SKF_NET_OFF) {
tprintf("%s+%u", "SKF_NET_OFF",
fp->k - (unsigned int) SKF_NET_OFF);
return true;
} else if (fp->k >= (unsigned int) SKF_LL_OFF) {
tprintf("%s+%u", "SKF_LL_OFF",
fp->k - (unsigned int) SKF_LL_OFF);
return true;
}
}
return false;
}
void
print_sock_fprog(struct tcb *const tcp, const kernel_ulong_t addr,
const unsigned short len)
{
print_bpf_fprog(tcp, addr, len, print_sock_filter_k);
}
void
decode_sock_fprog(struct tcb *const tcp, const kernel_ulong_t addr)
{
decode_bpf_fprog(tcp, addr, print_sock_filter_k);
}

6
defs.h
View File

@ -649,6 +649,12 @@ decode_seccomp_fprog(struct tcb *, kernel_ulong_t addr);
extern void
print_seccomp_fprog(struct tcb *, kernel_ulong_t addr, unsigned short len);
extern void
decode_sock_fprog(struct tcb *, kernel_ulong_t addr);
extern void
print_sock_fprog(struct tcb *, kernel_ulong_t addr, unsigned short len);
struct strace_stat;
extern void print_struct_stat(struct tcb *, const struct strace_stat *const st);

View File

@ -35,6 +35,11 @@ typedef struct sock_fprog struct_sock_fprog;
#include MPERS_DEFS
#include "bpf_fprog.h"
MPERS_PRINTER_DECL(unsigned int, get_sock_fprog_size, void)
{
return sizeof(struct_sock_fprog);
}
MPERS_PRINTER_DECL(bool, fetch_bpf_fprog, struct tcb *const tcp,
const kernel_ulong_t addr, void *const p)
{

19
net.c
View File

@ -606,6 +606,14 @@ print_getsockopt(struct tcb *const tcp, const unsigned int level,
print_ucred(tcp, addr, len);
return;
#endif
#ifdef SO_ATTACH_FILTER
case SO_ATTACH_FILTER:
if (len && (unsigned short) len == (unsigned int) len)
print_sock_fprog(tcp, addr, len);
else
printaddr(addr);
return;
#endif /* SO_ATTACH_FILTER */
}
break;
@ -799,6 +807,17 @@ print_setsockopt(struct tcb *const tcp, const unsigned int level,
case SO_LINGER:
print_set_linger(tcp, addr, len);
return;
#ifdef SO_ATTACH_FILTER
case SO_ATTACH_FILTER:
# ifdef SO_ATTACH_REUSEPORT_CBPF
case SO_ATTACH_REUSEPORT_CBPF:
# endif
if ((unsigned int) len == get_sock_fprog_size())
decode_sock_fprog(tcp, addr);
else
printaddr(addr);
return;
#endif /* SO_ATTACH_FILTER */
}
break;

16
xlat/skf_ad.in Normal file
View File

@ -0,0 +1,16 @@
SKF_AD_PROTOCOL 0
SKF_AD_PKTTYPE 4
SKF_AD_IFINDEX 8
SKF_AD_NLATTR 12
SKF_AD_NLATTR_NEST 16
SKF_AD_MARK 20
SKF_AD_QUEUE 24
SKF_AD_HATYPE 28
SKF_AD_RXHASH 32
SKF_AD_CPU 36
SKF_AD_ALU_XOR_X 40
SKF_AD_VLAN_TAG 44
SKF_AD_VLAN_TAG_PRESENT 48
SKF_AD_PAY_OFFSET 52
SKF_AD_RANDOM 56
SKF_AD_VLAN_TPID 60