summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorPatrick Mooney <patrick.f.mooney@gmail.com>2015-05-14 00:17:38 +0000
committerPatrick Mooney <patrick.f.mooney@gmail.com>2015-05-14 00:40:38 +0000
commit70fe4e726e40ffd9c0eabfcc9a4477c54d181a63 (patch)
tree32855a3ab17707802e16759f37ecd0886893fdd6 /usr/src
parent132f775751480e2d50bdefc4d6e7bf8eedb4183e (diff)
downloadillumos-joyent-70fe4e726e40ffd9c0eabfcc9a4477c54d181a63.tar.gz
OS-4306 lxbrand setsockopt(IP_MULTICAST_TTL) handles optlen poorly
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/socket.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/usr/src/lib/brand/lx/lx_brand/common/socket.c b/usr/src/lib/brand/lx/lx_brand/common/socket.c
index 7f64ef8813..ac5fbfe493 100644
--- a/usr/src/lib/brand/lx/lx_brand/common/socket.c
+++ b/usr/src/lib/brand/lx/lx_brand/common/socket.c
@@ -1849,8 +1849,6 @@ get_proto_opt_tbl(int level)
long
lx_setsockopt(int sockfd, int level, int optname, void *optval, int optlen)
{
- int internal_opt;
- uchar_t internal_uchar;
int r;
lx_proto_opts_t *proto_opts;
boolean_t converted = B_FALSE;
@@ -1907,21 +1905,24 @@ lx_setsockopt(int sockfd, int level, int optname, void *optval, int optlen)
* the option value to be an integer while we define it to be
* an unsigned character. To prevent the kernel from spitting
* back an error on an illegal length, verify that the option
- * value is less than UCHAR_MAX and then swizzle it.
+ * value is less than UCHAR_MAX before truncating optlen.
*/
if (optname == LX_IP_MULTICAST_TTL ||
optname == LX_IP_MULTICAST_LOOP) {
- if (optlen != sizeof (int))
+ int optcopy = 0;
+
+ if (optlen > sizeof (int) || optlen <= 0)
return (-EINVAL);
- if (uucopy(optval, &internal_opt, sizeof (int)) != 0)
+ if (uucopy(optval, &optcopy, optlen) != 0)
return (-errno);
- if (internal_opt > UCHAR_MAX)
+ if (optcopy > UCHAR_MAX)
return (-EINVAL);
- internal_uchar = (uchar_t)internal_opt;
- optval = &internal_uchar;
+ /*
+ * With optval validated, only optlen must be changed.
+ */
optlen = sizeof (uchar_t);
}
} else if (level == LX_IPPROTO_IPV6) {