time_second is a time_t, which we define as int64_t. The other operands used are of type uint32_t. Therefore, these checks get promoted to int64_t and the overflow being tested is undefined because it uses signed arithmetic.
I think that the below diff fixes the overflow check. However, I'm pretty tired at the moment and this is hard to do right, so review is appreciated. Index: netinet6/in6.c =================================================================== RCS file: /cvs/src/sys/netinet6/in6.c,v retrieving revision 1.183 diff -u -p -r1.183 in6.c --- netinet6/in6.c 21 Jan 2016 11:23:48 -0000 1.183 +++ netinet6/in6.c 12 Feb 2016 19:44:10 -0000 @@ -70,6 +70,7 @@ #include <sys/socket.h> #include <sys/socketvar.h> #include <sys/sockio.h> +#include <sys/stdint.h> #include <sys/mbuf.h> #include <sys/systm.h> #include <sys/time.h> @@ -348,11 +349,13 @@ in6_control(struct socket *so, u_long cm /* sanity for overflow - beware unsigned */ lt = &ifr->ifr_ifru.ifru_lifetime; if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME - && lt->ia6t_vltime + time_second < time_second) { + && (time_second > 0 + && time_second > INT64_MAX - lt->ia6t_vltime)) { return EINVAL; } if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME - && lt->ia6t_pltime + time_second < time_second) { + && (time_second > 0 + && time_second > INT64_MAX - lt->ia6t_pltime)) { return EINVAL; } break;