tcp_usrreq: Free allocated buffer in relock case
The disgusting macro INP_WLOCK_RECHECK may early-return. In tcp_default_ctloutput() the TCP_CCALGOOPT case allocates memory before invoking this macro, which may leak memory. Add a _CLEANUP variant that takes a code argument to perform variable cleanup in the early return path. Use it to free the 'pbuf' allocated in tcp_default_ctloutput(). I am not especially happy with this macro, but I reckon it's not any worse than INP_WLOCK_RECHECK already was. Reported by: Coverity CID: 1350286 Sponsored by: EMC / Isilon Storage Division
This commit is contained in:
parent
8bb71df062
commit
2ec16edcab
@ -1361,14 +1361,16 @@ tcp_fill_info(struct tcpcb *tp, struct tcp_info *ti)
|
||||
* has to revalidate that the connection is still valid for the socket
|
||||
* option.
|
||||
*/
|
||||
#define INP_WLOCK_RECHECK(inp) do { \
|
||||
#define INP_WLOCK_RECHECK_CLEANUP(inp, cleanup) do { \
|
||||
INP_WLOCK(inp); \
|
||||
if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) { \
|
||||
INP_WUNLOCK(inp); \
|
||||
cleanup; \
|
||||
return (ECONNRESET); \
|
||||
} \
|
||||
tp = intotcpcb(inp); \
|
||||
} while(0)
|
||||
#define INP_WLOCK_RECHECK(inp) INP_WLOCK_RECHECK_CLEANUP((inp), /* noop */)
|
||||
|
||||
int
|
||||
tcp_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
@ -1497,7 +1499,7 @@ tcp_default_ctloutput(struct socket *so, struct sockopt *sopt, struct inpcb *inp
|
||||
free(pbuf, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
INP_WLOCK_RECHECK(inp);
|
||||
INP_WLOCK_RECHECK_CLEANUP(inp, free(pbuf, M_TEMP));
|
||||
if (CC_ALGO(tp)->ctl_output != NULL)
|
||||
error = CC_ALGO(tp)->ctl_output(tp->ccv, sopt, pbuf);
|
||||
else
|
||||
@ -1838,6 +1840,7 @@ tcp_default_ctloutput(struct socket *so, struct sockopt *sopt, struct inpcb *inp
|
||||
return (error);
|
||||
}
|
||||
#undef INP_WLOCK_RECHECK
|
||||
#undef INP_WLOCK_RECHECK_CLEANUP
|
||||
|
||||
/*
|
||||
* Attach TCP protocol to socket, allocating
|
||||
|
Loading…
Reference in New Issue
Block a user