SMACK LSM checks wrong object label during ingress network traffic
Lontke, Michael
Michael.Lontke at elektrobit.com
Thu Sep 1 08:40:35 UTC 2022
On Wed, 2022-08-31 at 07:38 -0700, Casey Schaufler wrote:
> On 8/31/2022 5:13 AM, Lontke, Michael wrote:
> > On Tue, 2022-08-30 at 07:06 -0700, Casey Schaufler wrote:
> > > On 8/30/2022 2:30 AM, Lontke, Michael wrote:
> > > > On Fri, 2022-08-26 at 09:15 -0700, Casey Schaufler wrote:
> > > > > On 8/26/2022 1:40 AM, Lontke, Michael wrote:
> > > > > > On Thu, 2022-08-25 at 08:59 -0700, Casey Schaufler wrote:
> > > > > > > On 8/25/2022 2:25 AM, Lontke, Michael wrote:
> > > > > > > > Hello Mr. Schaufler,
> > > > > > > >
> > > > > > > > we observed the following behavior of the SMACK LSM
> > > > > > > > kernel
> > > > > > > > feature.
> > > > > > > >
> > > > > > > > PROBLEM: SMACK LSM is checking the wrong label when
> > > > > > > > receiving
> > > > > > > > network
> > > > > > > > packets during high system load.
> > > > > > > >
> > > > > > > > Full Descrpition of the Problem: During a test scenario
> > > > > > > > involving
> > > > > > > > high
> > > > > > > > system load (cpu, memory and io) in combination with
> > > > > > > > ingress
> > > > > > > > tcp
> > > > > > > > network traffic, SMACK is checking wrong object labels
> > > > > > > > leading
> > > > > > > > to
> > > > > > > > denied access for valid scenarios.
> > > > > > > > In below test scenario the label 'stresstest' is only
> > > > > > > > used
> > > > > > > > for
> > > > > > > > the
> > > > > > > > application 'stress' but appears in SMACK audit logs as
> > > > > > > > object
> > > > > > > > together
> > > > > > > > with netlabels.
> > > > > > > >
> > > > > > > > This issue initially appeared on hardware with kernel
> > > > > > > > version
> > > > > > > > 4.14.237
> > > > > > > > but was also being reproduced with qemu for kernel
> > > > > > > > version
> > > > > > > > 4.14.290
> > > > > > > > and
> > > > > > > > latest 6.0-rc2. The used rootfs was generated via
> > > > > > > > buildroot
> > > > > > > > version
> > > > > > > > 2022.08-rc1.
> > > > > > > >
> > > > > > > >
> > > > > > > > KEYWORDS: smack, networking
> > > > > > > >
> > > > > > > > KERNEL INFORMATION: Linux stable kernel
> > > > > > > >
> > > > > > > > KERNEL VERSION: 4.14.237, 4.14.290, 6.0-rc2
> > > > > > > >
> > > > > > > >
> > > > > > > > KERNEL CONFIG: smack related kernel configuration
> > > > > > > >
> > > > > > > > CONFIG_NETLABEL=y
> > > > > > > >
> > > > > > > > CONFIG_SECURITY_NETWORK=y
> > > > > > > >
> > > > > > > > CONFIG_SECURITY_SMACK=y
> > > > > > > >
> > > > > > > > CONFIG_DEFAULT_SECURITY_SMACK=y
> > > > > > > >
> > > > > > > > CONFIG_DEFAULT_SECURITY="smack"
> > > > > > >
> > > > > > > What is the value for CONFIG_SECURITY_SMACK_NETFILTER ?
> > > > > >
> > > > > > # CONFIG_NETWORK_SECMARK is not set
> > > > > > therefore CONFIG_SECURITY_SMACK_NETFILTER is not set as
> > > > > > well.
> > > > > >
> > > > > > > The implementation for IPv6 is much more robust for the
> > > > > > > netfilter enabled path.
> > > > > >
> > > > > > You are stating that
> > > > > >
> > > > > > CONFIG_NETWORK_SECMARK=y
> > > > > > CONFIG_SECURITY_SMACK_NETFILTER=y
> > > > > >
> > > > > > and therefore using SMACK_IPV6_SECMARK_LABELING instead of
> > > > > > SMACK_IPV6_PORT_LABELING path in kernel code is more
> > > > > > reliable?
> > > > >
> > > > > Yes. The netfilter version is used in all known commercial
> > > > > deployments
> > > > > of Smack, and hence has gotten more attention. The port
> > > > > labeling
> > > > > code
> > > > > is a "clever hack". I hope to replace it with CALIPSO now
> > > > > that
> > > > > CALIPSO
> > > > > is supported by newlabel.
> > > > >
> > > >
> > > > Today I tested with your suggested configuration (secmark +
> > > > netfilter).
> > > > Executing the same test case I run into almost the same issue:
> > > >
> > > > [ 288.200206] audit: type=1400 audit(1661844069.376:742):
> > > > lsm=SMACK
> > > > fn=smack_socket_sock_rcv_skb action=denied subject="net_host"
> > > > object="stresstest" requested=w pid=185 comm="stress"
> > > > saddr=<host-
> > > > ipv6-
> > > > addr> src=49812 daddr=<qemu-ipv6-addr> dest=42511 netif=ens3
> > > >
> > > > Instead of defining the netlabel via /sys/fs/smackfs/ip6hosts I
> > > > added a
> > > > nehosttfilter rule to mark the package with secmark:
> > >
> > > The netfilter rule is unnecessary if you set the host label.
> > > Smack
> > > will
> > > set the secmark based on the host label. The approach you've use
> > > should
> > > work just fine. Seeing that the problem occurs in both cases will
> > > help
> > > narrow down the possibilities. With the configuration and cases
> > > you
> > > provided I am able to reproduce the problem reliably. I am
> > > working on
> > > tracking down what I think is a lack of locking issue. Any more
> > > information
> > > you can provide could be most helpful.
> >
> > I added some debug output and stack dumps:
> >
> > [ 48.056297] SMACK DEBUG: smack_sk_alloc_security:2321 -
> > sk=ffff8feb1cc3a200 - smk_in=stresstest smk_out=stresstest
> > skp=ffff8feb1cc51000
> > [ 48.056792] CPU: 0 PID: 1544 Comm: stress Not tainted 4.14.0+ #9
> > [ 48.057085] Hardware name: QEMU Standard PC (i440FX + PIIX,
> > 1996),
> > BIOS 1.10.2-1ubuntu1 04/01/2014
> > [ 48.057463] Call Trace:
> > [ 48.057600] <IRQ>
> > [ 48.057741] dump_stack+0x4d/0x71
> > [ 48.057936] smack_sk_alloc_security+0x109/0x110
> > [ 48.058165] security_sk_alloc+0x3e/0x60
> > [ 48.058364] sk_prot_alloc+0x53/0x130
> > [ 48.058553] sk_clone_lock+0x19/0x3d0
> > [ 48.058737] inet_csk_clone_lock+0x11/0xe0
> > [ 48.058953] tcp_create_openreq_child+0x1e/0x420
> > [ 48.059172] tcp_v6_syn_recv_sock+0x91/0x710
> > [ 48.059380] tcp_check_req+0x3b2/0x510
> > [ 48.059558] ? tcp_v6_inbound_md5_hash+0x54/0x1c0
> > [ 48.059782] tcp_v6_rcv+0x4c1/0x950
> > [ 48.059954] ? ip6table_mangle_hook+0x41/0x120
> > [ 48.060172] ip6_input_finish+0xb9/0x420
> > [ 48.060374] ip6_input+0x2b/0x90
> > [ 48.060535] ? ip6_rcv_finish+0xa0/0xa0
> > [ 48.060718] ip6_rcv_finish+0x41/0xa0
> > [ 48.060892] ipv6_rcv+0x31d/0x520
> > [ 48.061053] ? ip6_make_skb+0x1b0/0x1b0
> > [ 48.061240] __netif_receive_skb_core+0x33a/0xa90
> > [ 48.061490] ? ipv6_gro_receive+0x1b5/0x350
> > [ 48.061687] __netif_receive_skb+0x13/0x60
> > [ 48.061895] ? __netif_receive_skb+0x13/0x60
> > [ 48.062089] netif_receive_skb_internal+0x23/0xb0
> > [ 48.062305] napi_gro_receive+0xbd/0xe0
> > [ 48.062485] e1000_clean_rx_irq+0x1c9/0x4e0
> > [ 48.062686] e1000_clean+0x260/0x860
> > [ 48.062860] net_rx_action+0x11b/0x350
> > [ 48.063031] ? e1000_intr+0x78/0xf0
> > [ 48.063202] __do_softirq+0xcf/0x2a8
> > [ 48.063376] irq_exit+0xab/0xb0
> > [ 48.063528] do_IRQ+0x7b/0xc0
> > [ 48.063679] common_interrupt+0x90/0x90
> > [ 48.063854] </IRQ>
> > [ 48.063977] RIP: 0033:0x56307cef0baf
> > [ 48.064135] RSP: 002b:00007ffcd9734540 EFLAGS: 00000206
> > ORIG_RAX:
> > ffffffffffffffc4
> > [ 48.064466] RAX: 0000000037581fac RBX: 0000000000003a98 RCX:
> > 0000000037581fac
> > [ 48.064765] RDX: 000000003b388e7d RSI: 00007ffcd973451c RDI:
> > 00007f2023c62680
> > [ 48.065033] RBP: 0000000000000003 R08: 0000000000000000 R09:
> > 00007f2023c62024
> > [ 48.065326] R10: 0000000000000000 R11: 0000000000000246 R12:
> > 0000000000000000
> > [ 48.065625] R13: 0000000000000003 R14: 0000000000000001 R15:
> > 000056307cef2004
> > [ 48.066462] SMACK DEBUG: smack_socket_sock_rcv_skb:4057 -
> > sk=ffff8feb1cc3a200 smk_in=stresstest rc=-13
> > [ 48.066852] CPU: 0 PID: 1544 Comm: stress Not tainted 4.14.0+ #9
> > [ 48.067142] Hardware name: QEMU Standard PC (i440FX + PIIX,
> > 1996),
> > BIOS 1.10.2-1ubuntu1 04/01/2014
> > [ 48.067507] Call Trace:
> > [ 48.067620] <IRQ>
> > [ 48.067738] dump_stack+0x4d/0x71
> > [ 48.067898] smack_socket_sock_rcv_skb+0x269/0x270
> > [ 48.068109] ? default_wake_function+0xd/0x10
> > [ 48.068301] ? pollwake+0x61/0x70
> > [ 48.068464] ? wake_up_q+0x70/0x70
> > [ 48.068621] ? __wake_up_common+0x68/0x120
> > [ 48.068806] security_sock_rcv_skb+0x36/0x50
> > [ 48.068987] sk_filter_trim_cap+0x2c/0x150
> > [ 48.069156] ? tcp_v6_inbound_md5_hash+0x54/0x1c0
> > [ 48.069356] tcp_filter+0x26/0x40
> > [ 48.069510] tcp_v6_rcv+0x805/0x950
> > [ 48.069663] ? ip6table_mangle_hook+0x41/0x120
> > [ 48.069856] ip6_input_finish+0xb9/0x420
> > [ 48.070029] ip6_input+0x2b/0x90
> > [ 48.070174] ? ip6_rcv_finish+0xa0/0xa0
> > [ 48.070337] ip6_rcv_finish+0x9a/0xa0
> > [ 48.070498] ipv6_rcv+0x31d/0x520
> > [ 48.070651] ? ip6_make_skb+0x1b0/0x1b0
> > [ 48.070832] __netif_receive_skb_core+0x33a/0xa90
> > [ 48.071028] ? ipv6_gro_receive+0x1b5/0x350
> > [ 48.071214] __netif_receive_skb+0x13/0x60
> > [ 48.071396] ? __netif_receive_skb+0x13/0x60
> > [ 48.071595] netif_receive_skb_internal+0x23/0xb0
> > [ 48.071808] napi_gro_receive+0xbd/0xe0
> > [ 48.072001] e1000_clean_rx_irq+0x1c9/0x4e0
> > [ 48.072197] e1000_clean+0x260/0x860
> > [ 48.072376] net_rx_action+0x11b/0x350
> > [ 48.072542] ? e1000_intr+0x78/0xf0
> > [ 48.072709] __do_softirq+0xcf/0x2a8
> > [ 48.072881] irq_exit+0xab/0xb0
> > [ 48.073041] do_IRQ+0x7b/0xc0
> > [ 48.073232] common_interrupt+0x90/0x90
> > [ 48.073433] </IRQ>
> > [ 48.073544] RIP: 0033:0x56307cef0baf
> > [ 48.073697] RSP: 002b:00007ffcd9734540 EFLAGS: 00000206
> > ORIG_RAX:
> > ffffffffffffffc4
> > [ 48.074007] RAX: 0000000037581fac RBX: 0000000000003a98 RCX:
> > 0000000037581fac
> > [ 48.074297] RDX: 000000003b388e7d RSI: 00007ffcd973451c RDI:
> > 00007f2023c62680
> > [ 48.074580] RBP: 0000000000000003 R08: 0000000000000000 R09:
> > 00007f2023c62024
> > [ 48.074875] R10: 0000000000000000 R11: 0000000000000246 R12:
> > 0000000000000000
> > [ 48.075157] R13: 0000000000000003 R14: 0000000000000001 R15:
> > 000056307cef2004
> > [ 48.075903] SMACK DEBUG: smack_sock_graft:4185 -
> > sk=ffff8feb1cc3a200
> > - before smk_in=stresstest smk_out=stresstest
> > [ 48.076643] CPU: 0 PID: 1634 Comm: socat Not tainted 4.14.0+ #9
> > [ 48.076892] Hardware name: QEMU Standard PC (i440FX + PIIX,
> > 1996),
> > BIOS 1.10.2-1ubuntu1 04/01/2014
> > [ 48.077329] Call Trace:
> > [ 48.077485] dump_stack+0x4d/0x71
> > [ 48.077654] smack_sock_graft+0xe9/0xf0
> > [ 48.077834] security_sock_graft+0x28/0x40
> > [ 48.078024] inet_accept+0xa8/0x140
> > [ 48.078198] SYSC_accept4+0xe8/0x1e0
> > [ 48.078372] ? __audit_syscall_entry+0xba/0x100
> > [ 48.078580] ? syscall_trace_enter+0x1c3/0x2b0
> > [ 48.078781] SyS_accept+0xb/0x10
> > [ 48.078933] do_syscall_64+0x4e/0x100
> > [ 48.079105] entry_SYSCALL64_slow_path+0x25/0x25
> > [ 48.079314] RIP: 0033:0x7f8d116b85ea
> > [ 48.079465] RSP: 002b:00007fff87c2ef28 EFLAGS: 00000246
> > ORIG_RAX:
> > 000000000000002b
> > [ 48.079778] RAX: ffffffffffffffda RBX: 00007fff87c2f160 RCX:
> > 00007f8d116b85ea
> > [ 48.080063] RDX: 00007fff87c2f134 RSI: 00007fff87c2f160 RDI:
> > 0000000000000005
> > [ 48.080363] RBP: 00007fff87c2f134 R08: 00007fff87c2f134 R09:
> > 0000000000000000
> > [ 48.080648] R10: 0000000000000040 R11: 0000000000000246 R12:
> > 0000000000000005
> > [ 48.080903] R13: 00000000ffffffff R14: 00007fff87c2f160 R15:
> > 00007fff87c2f1e0
> > [ 48.081236] SMACK DEBUG: smack_sock_graft:4193 -
> > sk=ffff8feb1cc3a200
> > - after smk_in=tcp_test smk_out=tcp_test
> >
> >
> > It looks like the socket is already initialized with the wrong
> > security
> > context. It is later corrected by smack_sock_graft, but tool late
> > since
> > it is called during accept.
> >
> > We looked into smack_sk_alloc_security and thought this line could
> > be
> > the issue:
> >
> > struct smack_known *skp = smk_of_current();
> >
> > Looking at how selinux solved it, we saw it initializes with a
> > blank
> > security context and later copys the correct context within
> > security_sk_clone LSM hook.
> > At least with this patch we don't see our issue anymore:
>
> I will run the patch through my tests, but it looks reasonable.
> Assuming it passes, and I expect it will, I'll add it to the Smack
> next branch. May I add your "Signed-off-by:" ? Also, let me know
> if anyone wants to add a "Reported-by:". Thank you for tracking this
> down and contributing to Smack.
Thank you for your feedback. If your tests are successful you can add
Signed-off-by: Michael Lontke <michael.lontke at elektrobit.com>
Co-authored-by: Martin Ostertag <martin.ostertag at elektrobit.com>
to the patch.
>
> >
> > From: Lontke Michael <michael.lontke at elektrobit.com>
> > Date: Wed, 31 Aug 2022 14:03:26 +0200
> > Subject: [PATCH] SMACK: Add sk_clone_security LSM hook
> >
> > Using smk_of_current() during sk_alloc_security hook leads in rare
> > cases
> > to a faulty initialization of the security context of the created
> > socket.
> >
> > By adding the LSM hook sk_clone_security to SMACK this
> > initialization
> > fault is corrected by copying the security context of the old
> > socket
> > pointer to the newly cloned one.
> > ---
> > security/smack/smack_lsm.c | 16 ++++++++++++++++
> > 1 file changed, 16 insertions(+)
> >
> > diff --git a/security/smack/smack_lsm.c
> > b/security/smack/smack_lsm.c
> > index 286171a16ed2..8eb47396376f 100644
> > --- a/security/smack/smack_lsm.c
> > +++ b/security/smack/smack_lsm.c
> > @@ -2348,6 +2348,21 @@ static void smack_sk_free_security(struct
> > sock
> > *sk)
> > kfree(sk->sk_security);
> > }
> >
> > +/**
> > + * smack_sk_clone_security - Copy security context
> > + * @sk: the old socket
> > + * @newsk: the new socket
> > + *
> > + * Copy the security context of the old socket pointer to the
> > cloned
> > + */
> > +static void smack_sk_clone_security(const struct sock *sk, struct
> > sock
> > *newsk)
> > +{
> > + struct socket_smack *ssp_old = sk->sk_security;
> > + struct socket_smack *ssp_new = newsk->sk_security;
> > +
> > + *ssp_new = *ssp_old;
> > +}
> > +
> > /**
> > * smack_ipv4host_label - check host based restrictions
> > * @sip: the object end
> > @@ -4710,6 +4725,7 @@ static struct security_hook_list
> > smack_hooks[]
> > __lsm_ro_after_init = {
> > LSM_HOOK_INIT(socket_getpeersec_dgram,
> > smack_socket_getpeersec_dgram),
> > LSM_HOOK_INIT(sk_alloc_security, smack_sk_alloc_security),
> > LSM_HOOK_INIT(sk_free_security, smack_sk_free_security),
> > + LSM_HOOK_INIT(sk_clone_security, smack_sk_clone_security),
> > LSM_HOOK_INIT(sock_graft, smack_sock_graft),
> > LSM_HOOK_INIT(inet_conn_request, smack_inet_conn_request),
> > LSM_HOOK_INIT(inet_csk_clone, smack_inet_csk_clone),
More information about the Linux-security-module-archive
mailing list