From 7154ea2925240a29017bb134d74353fccc3f6f88 Mon Sep 17 00:00:00 2001 From: Nachiketa Prachanda Date: Mon, 1 Mar 2021 12:26:40 -0800 Subject: [PATCH] npf: use rcu safe null check for sentry se_sen field in struct session may be NULL in two cases for newly created sessions not yet added to sentry hash list, or after sesssion removed from sentry hash list during reclaim in session gc. This causes the following segmentaion fault infrequently. [Current thread is 1 (Thread 0x7ff5c3fff700 (LWP 30235))] #0 0x000055ce31a8978d in csync_get_session_from_init_sentry ( cse=, cs=, sp=0x7ff5f004ef36) at ../src/npf/csync/csync_session_unpack.c:38 #1 csync_session_unpack_update (csu=0x7ff5f004ef2e) at ../src/npf/csync/csync_session_unpack.c:71 #2 csync_unpack_session (size=, msg=0x7ff5f004ef26) at ../src/npf/csync/csync_session_unpack.c:421 #3 csync_recv_session_update (frame=) at ../src/npf/csync/csync_session_unpack.c:501 #4 0x000055ce31b2d57d in csync_restore_sessions (n=, flist=) at ../src/csync/csync_transfer.c:218 #5 csync_pull_batch (info=0x7ff58400b880) at ../src/csync/csync_transfer.c:506 #6 csync_xfer_backup (pipe=0x7ff58400b8e0, arg=0x7ff58400b880) at ../src/csync/csync_transfer.c:301 #7 0x00007ff6629618d3 in ?? () from /usr/lib/x86_64-linux-gnu/libczmq.so.4 #8 0x00007ff6611ad4a4 in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0 #9 0x00007ff660eefd0f in clone () from /lib/x86_64-linux-gnu/libc.so.6 Fixed by doing a safe derefernce and checking for NULL. VRVDR-54586 (cherry picked from commit 5605da330608977aff774f0392a5223684982da2) --- src/npf/npf_pack.c | 9 +++++++-- src/npf/npf_unpack.c | 8 ++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/npf/npf_pack.c b/src/npf/npf_pack.c index 9de5c0ca..f8e524ea 100644 --- a/src/npf/npf_pack.c +++ b/src/npf/npf_pack.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, AT&T Intellectual Property. All rights reserved. + * Copyright (c) 2019-2021, AT&T Intellectual Property. All rights reserved. * * SPDX-License-Identifier: LGPL-2.1-only */ @@ -298,6 +298,7 @@ static int npf_pack_session_pack_new(struct session *s, struct npf_pack_session_new *csn_peer; struct session *s_peer = NULL; struct npf_session *se_peer = NULL; + struct sentry *sen; npf_session_t *se; int rc; @@ -306,7 +307,11 @@ static int npf_pack_session_pack_new(struct session *s, if (!s || !csn) return -EINVAL; - se = session_feature_get(s, s->se_sen->sen_ifindex, + sen = rcu_dereference(s->se_sen); + if (!sen) + return -ENOENT; + + se = session_feature_get(s, sen->sen_ifindex, SESSION_FEATURE_NPF); if (!se) return -ENOENT; diff --git a/src/npf/npf_unpack.c b/src/npf/npf_unpack.c index 62a21627..4933758b 100644 --- a/src/npf/npf_unpack.c +++ b/src/npf/npf_unpack.c @@ -25,6 +25,7 @@ static int npf_pack_get_session_from_init_sentry(struct sentry_packet *sp, { struct npf_session *se; struct session *s; + struct sentry *sen; bool forw; int rc; @@ -35,8 +36,11 @@ static int npf_pack_get_session_from_init_sentry(struct sentry_packet *sp, if (rc) return rc; - se = session_feature_get(s, s->se_sen->sen_ifindex, - SESSION_FEATURE_NPF); + sen = rcu_dereference(s->se_sen); + if (!sen) + return -ENOENT; + + se = session_feature_get(s, sen->sen_ifindex, SESSION_FEATURE_NPF); if (!se) return -ENOENT;