Cygwin: setsockopt/getsockopt: Add missing optlen checks

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2018-02-07 15:37:48 +01:00
parent 2af67d21b2
commit 51af517cab
1 changed files with 21 additions and 2 deletions

View File

@ -842,6 +842,11 @@ cygwin_setsockopt (int fd, int level, int optname, const void *optval,
SO_REUSEADDR has been set but don't call setsockopt. SO_REUSEADDR has been set but don't call setsockopt.
Instead fhandler_socket::bind sets SO_EXCLUSIVEADDRUSE if Instead fhandler_socket::bind sets SO_EXCLUSIVEADDRUSE if
the application did not set SO_REUSEADDR. */ the application did not set SO_REUSEADDR. */
if (optlen < (socklen_t) sizeof (int))
{
set_errno (EINVAL);
__leave;
}
if (fh->get_socket_type () == SOCK_STREAM) if (fh->get_socket_type () == SOCK_STREAM)
ignore = true; ignore = true;
break; break;
@ -901,7 +906,7 @@ cygwin_setsockopt (int fd, int level, int optname, const void *optval,
} }
} }
if (optlen == sizeof (int)) if (optlen == (socklen_t) sizeof (int))
debug_printf ("setsockopt optval=%x", *(int *) optval); debug_printf ("setsockopt optval=%x", *(int *) optval);
/* Postprocessing setsockopt, setting fhandler_socket members, etc. */ /* Postprocessing setsockopt, setting fhandler_socket members, etc. */
@ -966,7 +971,15 @@ cygwin_getsockopt (int fd, int level, int optname, void *optval,
case SO_PEERCRED: case SO_PEERCRED:
{ {
struct ucred *cred = (struct ucred *) optval; struct ucred *cred = (struct ucred *) optval;
if (*optlen < (socklen_t) sizeof *cred)
{
set_errno (EINVAL);
__leave;
}
res = fh->getpeereid (&cred->pid, &cred->uid, &cred->gid); res = fh->getpeereid (&cred->pid, &cred->uid, &cred->gid);
if (!res)
*optlen = (socklen_t) sizeof *cred;
__leave; __leave;
} }
break; break;
@ -974,8 +987,14 @@ cygwin_getsockopt (int fd, int level, int optname, void *optval,
case SO_REUSEADDR: case SO_REUSEADDR:
{ {
unsigned int *reuseaddr = (unsigned int *) optval; unsigned int *reuseaddr = (unsigned int *) optval;
if (*optlen < (socklen_t) sizeof *reuseaddr)
{
set_errno (EINVAL);
__leave;
}
*reuseaddr = fh->saw_reuseaddr(); *reuseaddr = fh->saw_reuseaddr();
*optlen = sizeof *reuseaddr; *optlen = (socklen_t) sizeof *reuseaddr;
ignore = true; ignore = true;
} }
break; break;