Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.com>2018-11-01 14:04:41 +1100
committerNeilBrown <neilb@suse.com>2018-11-01 14:04:58 +1100
commite5770368ac5b21f751723c0863c87d51aaea6fa9 (patch)
tree385b2bf304dc9549680c7eff713b16e91a384c91
parent5f808572f4ccad5e1d8ed9b896a74133ecdf87b9 (diff)
race of lockd inetaddr notifiers vs nlmsvc_rqst change
(git-fixes).
-rw-r--r--patches.fixes/race-of-lockd-inetaddr-notifiers-vs-nlmsvc_rqst-chan.patch96
-rw-r--r--series.conf1
2 files changed, 97 insertions, 0 deletions
diff --git a/patches.fixes/race-of-lockd-inetaddr-notifiers-vs-nlmsvc_rqst-chan.patch b/patches.fixes/race-of-lockd-inetaddr-notifiers-vs-nlmsvc_rqst-chan.patch
new file mode 100644
index 0000000000..e1ab63885f
--- /dev/null
+++ b/patches.fixes/race-of-lockd-inetaddr-notifiers-vs-nlmsvc_rqst-chan.patch
@@ -0,0 +1,96 @@
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Fri, 10 Nov 2017 10:19:26 +0300
+Subject: [PATCH] race of lockd inetaddr notifiers vs nlmsvc_rqst change
+Git-commit: 6b18dd1c03e07262ea0866084856b2a3c5ba8d09
+Patch-mainline: v4.15
+References: git-fixes
+
+lockd_inet[6]addr_event use nlmsvc_rqst without taken nlmsvc_mutex,
+nlmsvc_rqst can be changed during execution of notifiers and crash the host.
+
+Patch enables access to nlmsvc_rqst only when it was correctly initialized
+and delays its cleanup until notifiers are no longer in use.
+
+Note that nlmsvc_rqst can be temporally set to ERR_PTR, so the "if
+(nlmsvc_rqst)" check in notifiers is insufficient on its own.
+
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Tested-by: Scott Mayhew <smayhew@redhat.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Acked-by: NeilBrown <neilb@suse.com>
+
+---
+ fs/lockd/svc.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+--- a/fs/lockd/svc.c
++++ b/fs/lockd/svc.c
+@@ -57,6 +57,9 @@ static struct task_struct *nlmsvc_task;
+ static struct svc_rqst *nlmsvc_rqst;
+ unsigned long nlmsvc_timeout;
+
++atomic_t nlm_ntf_refcnt = ATOMIC_INIT(0);
++DECLARE_WAIT_QUEUE_HEAD(nlm_ntf_wq);
++
+ unsigned int lockd_net_id;
+
+ /*
+@@ -292,7 +295,8 @@ static int lockd_inetaddr_event(struct n
+ struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
+ struct sockaddr_in sin;
+
+- if (event != NETDEV_DOWN)
++ if ((event != NETDEV_DOWN) ||
++ !atomic_inc_not_zero(&nlm_ntf_refcnt))
+ goto out;
+
+ if (nlmsvc_rqst) {
+@@ -303,6 +307,8 @@ static int lockd_inetaddr_event(struct n
+ svc_age_temp_xprts_now(nlmsvc_rqst->rq_server,
+ (struct sockaddr *)&sin);
+ }
++ atomic_dec(&nlm_ntf_refcnt);
++ wake_up(&nlm_ntf_wq);
+
+ out:
+ return NOTIFY_DONE;
+@@ -319,7 +325,8 @@ static int lockd_inet6addr_event(struct
+ struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
+ struct sockaddr_in6 sin6;
+
+- if (event != NETDEV_DOWN)
++ if ((event != NETDEV_DOWN) ||
++ !atomic_inc_not_zero(&nlm_ntf_refcnt))
+ goto out;
+
+ if (nlmsvc_rqst) {
+@@ -331,6 +338,8 @@ static int lockd_inet6addr_event(struct
+ svc_age_temp_xprts_now(nlmsvc_rqst->rq_server,
+ (struct sockaddr *)&sin6);
+ }
++ atomic_dec(&nlm_ntf_refcnt);
++ wake_up(&nlm_ntf_wq);
+
+ out:
+ return NOTIFY_DONE;
+@@ -347,10 +356,12 @@ static void lockd_unregister_notifiers(v
+ #if IS_ENABLED(CONFIG_IPV6)
+ unregister_inet6addr_notifier(&lockd_inet6addr_notifier);
+ #endif
++ wait_event(nlm_ntf_wq, atomic_read(&nlm_ntf_refcnt) == 0);
+ }
+
+ static void lockd_svc_exit_thread(void)
+ {
++ atomic_dec(&nlm_ntf_refcnt);
+ lockd_unregister_notifiers();
+ svc_exit_thread(nlmsvc_rqst);
+ }
+@@ -375,6 +386,7 @@ static int lockd_start_svc(struct svc_se
+ goto out_rqst;
+ }
+
++ atomic_inc(&nlm_ntf_refcnt);
+ svc_sock_update_bufs(serv);
+ serv->sv_maxconn = nlm_max_connections;
+
diff --git a/series.conf b/series.conf
index 0bf8138695..a47d969cfa 100644
--- a/series.conf
+++ b/series.conf
@@ -10260,6 +10260,7 @@
patches.suse/btrfs-incremental-send-fix-wrong-unlink-path-after-renaming-file.patch
patches.fixes/0004-lockd-lost-rollback-of-set_grace_period-in-lockd_dow.patch
patches.fixes/0005-nfsd-fix-panic-in-posix_unblock_lock-called-from-nfs.patch
+ patches.fixes/race-of-lockd-inetaddr-notifiers-vs-nlmsvc_rqst-chan.patch
patches.fixes/mm-memory_hotplug-do-not-back-off-draining-pcp-free-.patch
patches.fixes/mm-oom_reaper-gather-each-vma-to-prevent-leaking-TLB.patch
patches.fixes/mm-cma-fix-alloc_contig_range-ret-code-potential-lea.patch