Make sure imo_membership is protected by inp's lock (solock)
This commit is contained in:
parent
549f799fbf
commit
d0c11d0872
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in_pcb.c,v 1.175 2017/02/13 04:05:58 ozaki-r Exp $ */
|
||||
/* $NetBSD: in_pcb.c,v 1.176 2017/03/02 05:29:31 ozaki-r Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -93,7 +93,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.175 2017/02/13 04:05:58 ozaki-r Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.176 2017/03/02 05:29:31 ozaki-r Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_inet.h"
|
||||
@ -722,6 +722,7 @@ in_purgeifmcast(struct ip_moptions *imo, struct ifnet *ifp)
|
||||
{
|
||||
int i, gap;
|
||||
|
||||
/* The owner of imo should be protected by solock */
|
||||
KASSERT(ifp != NULL);
|
||||
|
||||
if (imo == NULL)
|
||||
@ -755,9 +756,21 @@ in_pcbpurgeif0(struct inpcbtable *table, struct ifnet *ifp)
|
||||
|
||||
TAILQ_FOREACH_SAFE(inph, &table->inpt_queue, inph_queue, ninph) {
|
||||
struct inpcb *inp = (struct inpcb *)inph;
|
||||
bool need_unlock = false;
|
||||
|
||||
if (inp->inp_af != AF_INET)
|
||||
continue;
|
||||
|
||||
/* The caller holds either one of inps' lock */
|
||||
if (!inp_locked(inp)) {
|
||||
inp_lock(inp);
|
||||
need_unlock = true;
|
||||
}
|
||||
|
||||
in_purgeifmcast(inp->inp_moptions, ifp);
|
||||
|
||||
if (need_unlock)
|
||||
inp_unlock(inp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in_pcb.h,v 1.62 2017/02/22 07:05:04 ozaki-r Exp $ */
|
||||
/* $NetBSD: in_pcb.h,v 1.63 2017/03/02 05:29:31 ozaki-r Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -128,7 +128,9 @@ struct inpcb {
|
||||
INP_PKTINFO)
|
||||
|
||||
#define sotoinpcb(so) ((struct inpcb *)(so)->so_pcb)
|
||||
#define inplocked(inp) solocked((inp)->inp_socket)
|
||||
#define inp_lock(inp) solock((inp)->inp_socket)
|
||||
#define inp_unlock(inp) sounlock((inp)->inp_socket)
|
||||
#define inp_locked(inp) solocked((inp)->inp_socket)
|
||||
|
||||
#ifdef _KERNEL
|
||||
void in_losing(struct inpcb *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ip_output.c,v 1.273 2017/03/02 05:24:23 ozaki-r Exp $ */
|
||||
/* $NetBSD: ip_output.c,v 1.274 2017/03/02 05:29:31 ozaki-r Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -91,7 +91,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.273 2017/03/02 05:24:23 ozaki-r Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.274 2017/03/02 05:29:31 ozaki-r Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_inet.h"
|
||||
@ -1337,7 +1337,7 @@ ip_pcbopts(struct inpcb *inp, const struct sockopt *sopt)
|
||||
u_char *dp;
|
||||
int cnt;
|
||||
|
||||
KASSERT(inplocked(inp));
|
||||
KASSERT(inp_locked(inp));
|
||||
|
||||
/* Turn off any old options. */
|
||||
if (inp->inp_options) {
|
||||
@ -1587,6 +1587,8 @@ ip_add_membership(struct ip_moptions *imo, const struct sockopt *sopt)
|
||||
int i, error, bound;
|
||||
struct psref psref;
|
||||
|
||||
/* imo is protected by solock or referenced only by the caller */
|
||||
|
||||
bound = curlwp_bind();
|
||||
if (sopt->sopt_size == sizeof(struct ip_mreq))
|
||||
error = ip_get_membership(sopt, &ifp, &psref, &ia, true);
|
||||
@ -1718,6 +1720,8 @@ ip_setmoptions(struct ip_moptions **pimo, const struct sockopt *sopt)
|
||||
struct ifnet *ifp;
|
||||
int ifindex, error = 0;
|
||||
|
||||
/* The passed imo isn't NULL, it should be protected by solock */
|
||||
|
||||
if (!imo) {
|
||||
/*
|
||||
* No multicast option buffer attached to the pcb;
|
||||
@ -1880,6 +1884,8 @@ ip_freemoptions(struct ip_moptions *imo)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* The owner of imo (inp) should be protected by solock */
|
||||
|
||||
if (imo != NULL) {
|
||||
for (i = 0; i < imo->imo_num_memberships; ++i)
|
||||
in_delmulti(imo->imo_membership[i]);
|
||||
|
Loading…
Reference in New Issue
Block a user