From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Al Viro <viro@zeniv.linux.org.uk>,
"David S. Miller" <davem@davemloft.net>,
"Paul E. McKenney" <paulmck@linux.ibm.com>
Subject: [PATCH 4.19 35/52] missing barriers in some of unix_sock ->addr and ->path accesses
Date: Mon, 18 Mar 2019 10:25:32 +0100 [thread overview]
Message-ID: <20190318084017.657538834@linuxfoundation.org> (raw)
In-Reply-To: <20190318084013.532280682@linuxfoundation.org>
4.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <viro@zeniv.linux.org.uk>
[ Upstream commit ae3b564179bfd06f32d051b9e5d72ce4b2a07c37 ]
Several u->addr and u->path users are not holding any locks in
common with unix_bind(). unix_state_lock() is useless for those
purposes.
u->addr is assign-once and *(u->addr) is fully set up by the time
we set u->addr (all under unix_table_lock). u->path is also
set in the same critical area, also before setting u->addr, and
any unix_sock with ->path filled will have non-NULL ->addr.
So setting ->addr with smp_store_release() is all we need for those
"lockless" users - just have them fetch ->addr with smp_load_acquire()
and don't even bother looking at ->path if they see NULL ->addr.
Users of ->addr and ->path fall into several classes now:
1) ones that do smp_load_acquire(u->addr) and access *(u->addr)
and u->path only if smp_load_acquire() has returned non-NULL.
2) places holding unix_table_lock. These are guaranteed that
*(u->addr) is seen fully initialized. If unix_sock is in one of the
"bound" chains, so's ->path.
3) unix_sock_destructor() using ->addr is safe. All places
that set u->addr are guaranteed to have seen all stores *(u->addr)
while holding a reference to u and unix_sock_destructor() is called
when (atomic) refcount hits zero.
4) unix_release_sock() using ->path is safe. unix_bind()
is serialized wrt unix_release() (normally - by struct file
refcount), and for the instances that had ->path set by unix_bind()
unix_release_sock() comes from unix_release(), so they are fine.
Instances that had it set in unix_stream_connect() either end up
attached to a socket (in unix_accept()), in which case the call
chain to unix_release_sock() and serialization are the same as in
the previous case, or they never get accept'ed and unix_release_sock()
is called when the listener is shut down and its queue gets purged.
In that case the listener's queue lock provides the barriers needed -
unix_stream_connect() shoves our unix_sock into listener's queue
under that lock right after having set ->path and eventual
unix_release_sock() caller picks them from that queue under the
same lock right before calling unix_release_sock().
5) unix_find_other() use of ->path is pointless, but safe -
it happens with successful lookup by (abstract) name, so ->path.dentry
is guaranteed to be NULL there.
earlier-variant-reviewed-by: "Paul E. McKenney" <paulmck@linux.ibm.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/unix/af_unix.c | 57 +++++++++++++++++++++++++++++----------------------
net/unix/diag.c | 3 +-
security/lsm_audit.c | 10 +++++---
3 files changed, 41 insertions(+), 29 deletions(-)
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -888,7 +888,7 @@ retry:
addr->hash ^= sk->sk_type;
__unix_remove_socket(sk);
- u->addr = addr;
+ smp_store_release(&u->addr, addr);
__unix_insert_socket(&unix_socket_table[addr->hash], sk);
spin_unlock(&unix_table_lock);
err = 0;
@@ -1058,7 +1058,7 @@ static int unix_bind(struct socket *sock
err = 0;
__unix_remove_socket(sk);
- u->addr = addr;
+ smp_store_release(&u->addr, addr);
__unix_insert_socket(list, sk);
out_unlock:
@@ -1329,15 +1329,29 @@ restart:
RCU_INIT_POINTER(newsk->sk_wq, &newu->peer_wq);
otheru = unix_sk(other);
- /* copy address information from listening to new sock*/
- if (otheru->addr) {
- refcount_inc(&otheru->addr->refcnt);
- newu->addr = otheru->addr;
- }
+ /* copy address information from listening to new sock
+ *
+ * The contents of *(otheru->addr) and otheru->path
+ * are seen fully set up here, since we have found
+ * otheru in hash under unix_table_lock. Insertion
+ * into the hash chain we'd found it in had been done
+ * in an earlier critical area protected by unix_table_lock,
+ * the same one where we'd set *(otheru->addr) contents,
+ * as well as otheru->path and otheru->addr itself.
+ *
+ * Using smp_store_release() here to set newu->addr
+ * is enough to make those stores, as well as stores
+ * to newu->path visible to anyone who gets newu->addr
+ * by smp_load_acquire(). IOW, the same warranties
+ * as for unix_sock instances bound in unix_bind() or
+ * in unix_autobind().
+ */
if (otheru->path.dentry) {
path_get(&otheru->path);
newu->path = otheru->path;
}
+ refcount_inc(&otheru->addr->refcnt);
+ smp_store_release(&newu->addr, otheru->addr);
/* Set credentials */
copy_peercred(sk, other);
@@ -1451,7 +1465,7 @@ out:
static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int peer)
{
struct sock *sk = sock->sk;
- struct unix_sock *u;
+ struct unix_address *addr;
DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, uaddr);
int err = 0;
@@ -1466,19 +1480,15 @@ static int unix_getname(struct socket *s
sock_hold(sk);
}
- u = unix_sk(sk);
- unix_state_lock(sk);
- if (!u->addr) {
+ addr = smp_load_acquire(&unix_sk(sk)->addr);
+ if (!addr) {
sunaddr->sun_family = AF_UNIX;
sunaddr->sun_path[0] = 0;
err = sizeof(short);
} else {
- struct unix_address *addr = u->addr;
-
err = addr->len;
memcpy(sunaddr, addr->name, addr->len);
}
- unix_state_unlock(sk);
sock_put(sk);
out:
return err;
@@ -2071,11 +2081,11 @@ static int unix_seqpacket_recvmsg(struct
static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
{
- struct unix_sock *u = unix_sk(sk);
+ struct unix_address *addr = smp_load_acquire(&unix_sk(sk)->addr);
- if (u->addr) {
- msg->msg_namelen = u->addr->len;
- memcpy(msg->msg_name, u->addr->name, u->addr->len);
+ if (addr) {
+ msg->msg_namelen = addr->len;
+ memcpy(msg->msg_name, addr->name, addr->len);
}
}
@@ -2579,15 +2589,14 @@ static int unix_open_file(struct sock *s
if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
return -EPERM;
- unix_state_lock(sk);
+ if (!smp_load_acquire(&unix_sk(sk)->addr))
+ return -ENOENT;
+
path = unix_sk(sk)->path;
- if (!path.dentry) {
- unix_state_unlock(sk);
+ if (!path.dentry)
return -ENOENT;
- }
path_get(&path);
- unix_state_unlock(sk);
fd = get_unused_fd_flags(O_CLOEXEC);
if (fd < 0)
@@ -2828,7 +2837,7 @@ static int unix_seq_show(struct seq_file
(s->sk_state == TCP_ESTABLISHED ? SS_CONNECTING : SS_DISCONNECTING),
sock_i_ino(s));
- if (u->addr) {
+ if (u->addr) { // under unix_table_lock here
int i, len;
seq_putc(seq, ' ');
--- a/net/unix/diag.c
+++ b/net/unix/diag.c
@@ -10,7 +10,8 @@
static int sk_diag_dump_name(struct sock *sk, struct sk_buff *nlskb)
{
- struct unix_address *addr = unix_sk(sk)->addr;
+ /* might or might not have unix_table_lock */
+ struct unix_address *addr = smp_load_acquire(&unix_sk(sk)->addr);
if (!addr)
return 0;
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -321,6 +321,7 @@ static void dump_common_audit_data(struc
if (a->u.net->sk) {
struct sock *sk = a->u.net->sk;
struct unix_sock *u;
+ struct unix_address *addr;
int len = 0;
char *p = NULL;
@@ -351,14 +352,15 @@ static void dump_common_audit_data(struc
#endif
case AF_UNIX:
u = unix_sk(sk);
+ addr = smp_load_acquire(&u->addr);
+ if (!addr)
+ break;
if (u->path.dentry) {
audit_log_d_path(ab, " path=", &u->path);
break;
}
- if (!u->addr)
- break;
- len = u->addr->len-sizeof(short);
- p = &u->addr->name->sun_path[0];
+ len = addr->len-sizeof(short);
+ p = &addr->name->sun_path[0];
audit_log_format(ab, " path=");
if (*p)
audit_log_untrustedstring(ab, p);
next prev parent reply other threads:[~2019-03-18 9:33 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-18 9:24 [PATCH 4.19 00/52] 4.19.30-stable review Greg Kroah-Hartman
2019-03-18 9:24 ` [PATCH 4.19 01/52] connector: fix unsafe usage of ->real_parent Greg Kroah-Hartman
2019-03-18 9:24 ` [PATCH 4.19 02/52] gro_cells: make sure device is up in gro_cells_receive() Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 03/52] ipv4/route: fail early when inet dev is missing Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 04/52] l2tp: fix infoleak in l2tp_ip6_recvmsg() Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 05/52] lan743x: Fix RX Kernel Panic Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 06/52] lan743x: Fix TX Stall Issue Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 07/52] net: hsr: fix memory leak in hsr_dev_finalize() Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 08/52] net/hsr: fix possible crash in add_timer() Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 09/52] net: sit: fix UBSAN Undefined behaviour in check_6rd Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 10/52] net/x25: fix use-after-free in x25_device_event() Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 11/52] net/x25: reset state in x25_connect() Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 12/52] pptp: dst_release sk_dst_cache in pptp_sock_destruct Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 13/52] ravb: Decrease TxFIFO depth of Q3 and Q2 to one Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 14/52] route: set the deleted fnhe fnhe_daddr to 0 in ip_del_fnhe to fix a race Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 15/52] rxrpc: Fix client call queueing, waiting for channel Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 16/52] sctp: remove sched init from sctp_stream_init Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 17/52] tcp: do not report TCP_CM_INQ of 0 for closed connections Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 18/52] tcp: Dont access TCP_SKB_CB before initializing it Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 19/52] tcp: handle inet_csk_reqsk_queue_add() failures Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 20/52] vxlan: Fix GRO cells race condition between receive and link delete Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 21/52] vxlan: test dev->flags & IFF_UP before calling gro_cells_receive() Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 22/52] net/mlx4_core: Fix reset flow when in command polling mode Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 23/52] net/mlx4_core: Fix locking in SRIOV mode when switching between events and polling Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 24/52] net/mlx4_core: Fix qp mtt size calculation Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 25/52] net/x25: fix a race in x25_bind() Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 26/52] mdio_bus: Fix use-after-free on device_register fails Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 27/52] net: Set rtm_table to RT_TABLE_COMPAT for ipv6 for tables > 255 Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 28/52] ipv6: route: purge exception on removal Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 29/52] team: use operstate consistently for linkup Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 30/52] ipvlan: disallow userns cap_net_admin to change global mode/flags Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 31/52] ipv6: route: enforce RCU protection in rt6_update_exception_stamp_rt() Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 32/52] ipv6: route: enforce RCU protection in ip6_route_check_nh_onlink() Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 33/52] bonding: fix PACKET_ORIGDEV regression Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 34/52] net/smc: fix smc_poll in SMC_INIT state Greg Kroah-Hartman
2019-03-18 9:25 ` Greg Kroah-Hartman [this message]
2019-03-18 9:25 ` [PATCH 4.19 36/52] net: sched: flower: insert new filter to idr after setting its mask Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 37/52] f2fs: wait on atomic writes to count F2FS_CP_WB_DATA Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 38/52] perf/x86: Fixup typo in stub functions Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 39/52] ALSA: bebob: use more identical mod_alias for Saffire Pro 10 I/O against Liquid Saffire 56 Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 40/52] ALSA: firewire-motu: fix construction of PCM frame for capture direction Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 41/52] ALSA: hda: Extend i915 component bind timeout Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 42/52] ALSA: hda - add more quirks for HP Z2 G4 and HP Z240 Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 43/52] ALSA: hda/realtek: Enable audio jacks of ASUS UX362FA with ALC294 Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 44/52] ALSA: hda/realtek - Reduce click noise on Dell Precision 5820 headphone Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 45/52] ALSA: hda/realtek: Enable headset MIC of Acer TravelMate X514-51T with ALC255 Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 46/52] perf/x86/intel: Fix memory corruption Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 47/52] perf/x86/intel: Make dev_attr_allow_tsx_force_abort static Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 48/52] Its wrong to add len to sector_nr in raid10 reshape twice Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 49/52] drm: Block fb changes for async plane updates Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 50/52] staging: erofs: fix race when the managed cache is enabled Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 51/52] i40e: report correct statistics when XDP " Greg Kroah-Hartman
2019-03-18 9:25 ` [PATCH 4.19 52/52] vhost/vsock: fix vhost vsock cid hashing inconsistent Greg Kroah-Hartman
2019-03-18 13:42 ` [PATCH 4.19 00/52] 4.19.30-stable review kernelci.org bot
2019-03-18 17:14 ` Naresh Kamboju
2019-03-19 2:25 ` Guenter Roeck
2019-03-19 10:34 ` Jon Hunter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190318084017.657538834@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=davem@davemloft.net \
--cc=linux-kernel@vger.kernel.org \
--cc=paulmck@linux.ibm.com \
--cc=stable@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome