Start working through inpcb locking for ip_ctloutput() by cleaning up
modifications to the inpcb IP options mbuf: - Lock the inpcb before passing it into ip_pcbopts() in order to prevent simulatenous reads and read-modify-writes that could result in races. - Pass the inpcb reference into ip_pcbopts() instead of the option chain pointer in the inpcb. - Assert the inpcb lock in ip_pcbots. - Convert one or two uses of a pointer as a boolean or an integer comparison to a comparison with NULL for readability.
This commit is contained in:
parent
176119c455
commit
993d9505d4
@ -99,7 +99,7 @@ static void ip_mloopback
|
||||
(struct ifnet *, struct mbuf *, struct sockaddr_in *, int);
|
||||
static int ip_getmoptions
|
||||
(struct sockopt *, struct ip_moptions *);
|
||||
static int ip_pcbopts(int, struct mbuf **, struct mbuf *);
|
||||
static int ip_pcbopts(struct inpcb *, int, struct mbuf *);
|
||||
static int ip_setmoptions
|
||||
(struct sockopt *, struct ip_moptions **);
|
||||
|
||||
@ -1175,9 +1175,10 @@ ip_ctloutput(so, sopt)
|
||||
m->m_len = sopt->sopt_valsize;
|
||||
error = sooptcopyin(sopt, mtod(m, char *), m->m_len,
|
||||
m->m_len);
|
||||
|
||||
return (ip_pcbopts(sopt->sopt_name, &inp->inp_options,
|
||||
m));
|
||||
INP_LOCK(inp);
|
||||
error = ip_pcbopts(inp, sopt->sopt_name, m);
|
||||
INP_UNLOCK(inp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
case IP_TOS:
|
||||
@ -1430,24 +1431,26 @@ ip_ctloutput(so, sopt)
|
||||
* with destination address if source routed.
|
||||
*/
|
||||
static int
|
||||
ip_pcbopts(optname, pcbopt, m)
|
||||
int optname;
|
||||
struct mbuf **pcbopt;
|
||||
register struct mbuf *m;
|
||||
ip_pcbopts(struct inpcb *inp, int optname, struct mbuf *m)
|
||||
{
|
||||
register int cnt, optlen;
|
||||
register u_char *cp;
|
||||
struct mbuf **pcbopt;
|
||||
u_char opt;
|
||||
|
||||
INP_LOCK_ASSERT(inp);
|
||||
|
||||
pcbopt = &inp->inp_options;
|
||||
|
||||
/* turn off any old options */
|
||||
if (*pcbopt)
|
||||
(void)m_free(*pcbopt);
|
||||
*pcbopt = 0;
|
||||
if (m == (struct mbuf *)0 || m->m_len == 0) {
|
||||
if (m == NULL || m->m_len == 0) {
|
||||
/*
|
||||
* Only turning off any previous options.
|
||||
*/
|
||||
if (m)
|
||||
if (m != NULL)
|
||||
(void)m_free(m);
|
||||
return (0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user