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:
Robert Watson 2004-12-05 19:11:09 +00:00
parent 176119c455
commit 993d9505d4

View File

@ -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);
}