compat_sys_[gs]etsockopt need to check for level
Subsystems (2)
PATCH 1/1 compat_sys_[gs]etsockopt need to check for level
The 32bit emulation functions for setsockopt/getsockopt try to catch a few special cases by looking at the option name, without checking for the option level. This breaks IPV6_V6ONLY and probably a few others.
The bug was found by Marcus Meissner.
I hope I got the level for IPT_SO_SET_REPLACE right (I think it's SOL_IP). I would appreciate if someone could double-check.
Cheers,
Olaf
Signature · 3 lines
Olaf Kirch | The Hardware Gods hate me. [email protected] | ---------------+
net/compat.c renamed from net/compat.c.orig +6 -4
@@ -457,13 +457,14 @@asmlinkage long compat_sys_setsockopt (int fd,int level,int optname,char *optval,int optlen) { -if (optname ==IPT_SO_SET_REPLACE ) +if (level ==SOL_IP && optname ==IPT_SO_SET_REPLACE )return do_netfilter_replace (fd, level, optname, optval, optlen); -if (optname ==SO_ATTACH_FILTER ) +if (level ==SOL_SOCKET && optname ==SO_ATTACH_FILTER )return do_set_attach_filter (fd, level, optname, optval, optlen); -if (optname ==SO_RCVTIMEO || optname ==SO_SNDTIMEO ) +if (level ==SOL_SOCKET && + (optname ==SO_RCVTIMEO || optname ==SO_SNDTIMEO ))return do_set_sock_timeout (fd, level, optname, optval, optlen);return sys_setsockopt (fd, level, optname, optval, optlen);
@@ -500,7 +501,8 @@asmlinkage long compat_sys_getsockopt (int fd,int level,int optname,char *optval,int *optlen) { -if (optname ==SO_RCVTIMEO || optname ==SO_SNDTIMEO ) +if (level ==SOL_SOCKET && + (optname ==SO_RCVTIMEO || optname ==SO_SNDTIMEO ))return do_get_sock_timeout (fd, level, optname, optval, optlen);return sys_getsockopt (fd, level, optname, optval, optlen); }