Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/in_mcast.c
Context not available. | |||||
inp_block_unblock_source(struct inpcb *inp, struct sockopt *sopt) | inp_block_unblock_source(struct inpcb *inp, struct sockopt *sopt) | ||||
{ | { | ||||
struct group_source_req gsr; | struct group_source_req gsr; | ||||
struct rm_priotracker in_ifa_tracker; | |||||
sockunion_t *gsa, *ssa; | sockunion_t *gsa, *ssa; | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
struct in_mfilter *imf; | struct in_mfilter *imf; | ||||
Context not available. | |||||
ssa->sin.sin_len = sizeof(struct sockaddr_in); | ssa->sin.sin_len = sizeof(struct sockaddr_in); | ||||
ssa->sin.sin_addr = mreqs.imr_sourceaddr; | ssa->sin.sin_addr = mreqs.imr_sourceaddr; | ||||
if (!in_nullhost(mreqs.imr_interface)) | if (!in_nullhost(mreqs.imr_interface)) { | ||||
IN_IFADDR_RLOCK(&in_ifa_tracker); | |||||
INADDR_TO_IFP(mreqs.imr_interface, ifp); | INADDR_TO_IFP(mreqs.imr_interface, ifp); | ||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker); | |||||
} | |||||
mav: Do I miss some other protection means or this and few below places just scream about possible… | |||||
eugen_grosbein.netAuthorUnsubmitted Done Inline ActionsYes, it does. I just want to fix that what's easy to fix to start. eugen_grosbein.net: Yes, it does. I just want to fix that what's easy to fix to start. | |||||
if (sopt->sopt_name == IP_BLOCK_SOURCE) | if (sopt->sopt_name == IP_BLOCK_SOURCE) | ||||
doblock = 1; | doblock = 1; | ||||
Context not available. | |||||
* | * | ||||
* Returns NULL if no ifp could be found. | * Returns NULL if no ifp could be found. | ||||
* | * | ||||
* SMPng: TODO: Acquire the appropriate locks for INADDR_TO_IFP. | |||||
* FUTURE: Implement IPv4 source-address selection. | * FUTURE: Implement IPv4 source-address selection. | ||||
*/ | */ | ||||
static struct ifnet * | static struct ifnet * | ||||
Context not available. | |||||
ifp = NULL; | ifp = NULL; | ||||
if (!in_nullhost(ina)) { | if (!in_nullhost(ina)) { | ||||
IN_IFADDR_RLOCK(&in_ifa_tracker); | |||||
INADDR_TO_IFP(ina, ifp); | INADDR_TO_IFP(ina, ifp); | ||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker); | |||||
} else { | } else { | ||||
fibnum = inp ? inp->inp_inc.inc_fibnum : 0; | fibnum = inp ? inp->inp_inc.inc_fibnum : 0; | ||||
if (fib4_lookup_nh_basic(fibnum, gsin->sin_addr, 0, 0, &nh4)==0) | if (fib4_lookup_nh_basic(fibnum, gsin->sin_addr, 0, 0, &nh4)==0) | ||||
Context not available. | |||||
{ | { | ||||
struct group_source_req gsr; | struct group_source_req gsr; | ||||
struct ip_mreq_source mreqs; | struct ip_mreq_source mreqs; | ||||
struct rm_priotracker in_ifa_tracker; | |||||
sockunion_t *gsa, *ssa; | sockunion_t *gsa, *ssa; | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
struct in_mfilter *imf; | struct in_mfilter *imf; | ||||
Context not available. | |||||
* XXX NOTE WELL: The RFC 3678 API is preferred because | * XXX NOTE WELL: The RFC 3678 API is preferred because | ||||
* using an IPv4 address as a key is racy. | * using an IPv4 address as a key is racy. | ||||
*/ | */ | ||||
if (!in_nullhost(mreqs.imr_interface)) | if (!in_nullhost(mreqs.imr_interface)) { | ||||
IN_IFADDR_RLOCK(&in_ifa_tracker); | |||||
INADDR_TO_IFP(mreqs.imr_interface, ifp); | INADDR_TO_IFP(mreqs.imr_interface, ifp); | ||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker); | |||||
} | |||||
CTR3(KTR_IGMPV3, "%s: imr_interface = 0x%08x, ifp = %p", | CTR3(KTR_IGMPV3, "%s: imr_interface = 0x%08x, ifp = %p", | ||||
__func__, ntohl(mreqs.imr_interface.s_addr), ifp); | __func__, ntohl(mreqs.imr_interface.s_addr), ifp); | ||||
Context not available. | |||||
static int | static int | ||||
inp_set_multicast_if(struct inpcb *inp, struct sockopt *sopt) | inp_set_multicast_if(struct inpcb *inp, struct sockopt *sopt) | ||||
{ | { | ||||
struct rm_priotracker in_ifa_tracker; | |||||
struct in_addr addr; | struct in_addr addr; | ||||
struct ip_mreqn mreqn; | struct ip_mreqn mreqn; | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
Context not available. | |||||
if (in_nullhost(addr)) { | if (in_nullhost(addr)) { | ||||
ifp = NULL; | ifp = NULL; | ||||
} else { | } else { | ||||
IN_IFADDR_RLOCK(&in_ifa_tracker); | |||||
INADDR_TO_IFP(addr, ifp); | INADDR_TO_IFP(addr, ifp); | ||||
IN_IFADDR_RUNLOCK(&in_ifa_tracker); | |||||
if (ifp == NULL) | if (ifp == NULL) | ||||
return (EADDRNOTAVAIL); | return (EADDRNOTAVAIL); | ||||
} | } | ||||
Context not available. |
Do I miss some other protection means or this and few below places just scream about possible races due to missing interface pointer pulled out of the lock without taking reference?
I suspect INADDR_TO_IFP KPI is not safe now in general.