aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/uipc_syscalls.c
diff options
context:
space:
mode:
authorHiren Panchasara <hiren@FreeBSD.org>2016-10-21 18:27:30 +0000
committerHiren Panchasara <hiren@FreeBSD.org>2016-10-21 18:27:30 +0000
commit9d71a3975e55e1fbc9ec7c09bdabc9e496c638a9 (patch)
tree8bf37ea39096952cc1773438b73c778914e32d82 /sys/kern/uipc_syscalls.c
parent1c32eff59bbe4757d96c0ddbe003f8cd074de2a4 (diff)
downloadsrc-9d71a3975e55e1fbc9ec7c09bdabc9e496c638a9.tar.gz
src-9d71a3975e55e1fbc9ec7c09bdabc9e496c638a9.zip
Rework r306337.
In sendit(), if mp->msg_control is present, then in sockargs() we are allocating mbuf to store mp->msg_control. Later in kern_sendit(), call to getsock_cap(), will check validity of file pointer passed, if this fails EBADF is returned but mbuf allocated in sockargs() is not freed. Made code changes to free the same. Since freeing control mbuf in sendit() after checking (control != NULL) may lead to double freeing of control mbuf in sendit(), we can free control mbuf in kern_sendit() if there are any errors in the routine. Submitted by: Lohith Bellad <lohith.bellad@me.com> Reviewed by: glebius MFC after: 3 weeks Differential Revision: https://reviews.freebsd.org/D8152
Notes
Notes: svn path=/head/; revision=307745
Diffstat (limited to 'sys/kern/uipc_syscalls.c')
-rw-r--r--sys/kern/uipc_syscalls.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index e282665f75e5..98f6957e0ae6 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -762,8 +762,10 @@ kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
cap_rights_set(&rights, CAP_CONNECT);
}
error = getsock_cap(td, s, &rights, &fp, NULL, NULL);
- if (error != 0)
+ if (error != 0) {
+ m_freem(control);
return (error);
+ }
so = (struct socket *)fp->f_data;
#ifdef KTRACE
@@ -774,12 +776,16 @@ kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
if (mp->msg_name != NULL) {
error = mac_socket_check_connect(td->td_ucred, so,
mp->msg_name);
- if (error != 0)
+ if (error != 0) {
+ m_freem(control);
goto bad;
+ }
}
error = mac_socket_check_send(td->td_ucred, so);
- if (error != 0)
+ if (error != 0) {
+ m_freem(control);
goto bad;
+ }
#endif
auio.uio_iov = mp->msg_iov;
@@ -793,6 +799,7 @@ kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
for (i = 0; i < mp->msg_iovlen; i++, iov++) {
if ((auio.uio_resid += iov->iov_len) < 0) {
error = EINVAL;
+ m_freem(control);
goto bad;
}
}