[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#607041: linux-image-2.6.32-5-openvz-amd64: amd64 ip6tables broken in OpenVZ VE



Package: linux-image-2.6.32-5-openvz-amd64
Version: 2.6.32-29

Hi,

I noticed that on kernel 2.6.32-5-openvz-amd64 (Debian 2.6.32-29), the amd64 build of ip6tables does not work at all in an OpenVZ VE, but the i386 build does. Within the OpenVZ host itself though (VE0), both versions work. So I'm inclined to say this is more likely a kernel/OpenVZ bug than a bug in ip6tables.

IPv4 iptables works fine in all cases.

I tested this within a OpenVZ VE, which is an amd64 Debian lenny install, with an i386 chroot inside of it:


# dpkg-query -Wf '${Package}-${Version}_${Architecture}\n' iptables
iptables-1.4.2-6_amd64

# ip6tables -L
FATAL: Could not load /lib/modules/2.6.32-5-openvz-amd64/modules.dep: No such file or directory ip6tables v1.4.2: can't initialize ip6tables table `filter': Permission denied (you must be root)
Perhaps ip6tables or your kernel needs to be upgraded.


# chroot lenny-i386/ dpkg-query -Wf '${Package}-${Version}_${Architecture}\n' iptables
iptables-1.4.2-6_i386

# chroot lenny-i386/ ip6tables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
...


I believe this strace of the amd64 version shows where the problem occurs:

socket(PF_INET6, SOCK_RAW, IPPROTO_RAW) = 3
getsockopt(3, SOL_IPV6, 0x40 /* IPV6_??? */, 0x7fff508e34d0, 0x7fff508e3538) = -1 EPERM (Operation not permitted)


After that, ip6tables seems to think some kernel modules must be missing, so it tries to load them, except that's not correct for OpenVZ and that leads to the errors visible on stderr.

The same getsockopt() call succeeds in the i386 version:

socket(PF_INET6, SOCK_RAW, IPPROTO_RAW) = 3
getsockopt(3, SOL_IPV6, 0x40 /* IPV6_??? */, "filter\0\377\241\372\3\201\377\377\377\377\6\0\0\0\0\0\0\0Q\367\0\201\377\377\377\377\16"..., [84]) = 0


After an exhaustive search of kernel source I think maybe this is the source of that -1 EPERM return value:

static int
compat_do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
{
        int ret;

        if (!capable(CAP_VE_NET_ADMIN))
                return -EPERM;

static int
do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
{
        int ret;

        if (!capable(CAP_NET_ADMIN))
                return -EPERM;

It looks like the OpenVZ patch changed CAP_NET_ADMIN to CAP_VE_NET_ADMIN for compat_do_ip6t_{get,set}_ctl but not for the native functions ip6t_{get,set}_ctl.

However, the equivalent IPv4 functions have something slightly different, for all four functions (get and set, compat and native):

if (capable(CAP_NET_ADMIN) && !capable(CAP_VE_NET_ADMIN))

In all honesty I don't know what this means -- I don't know if there are security implications if I changed this. Or maybe it would break ip6tables in the host system (VE0). I may try fiddling with this sometime if I get the chance to reboot the machine (a production system, unfortunately, such is the way of things...).

Thanks,
Regards,
--
Steven Chamberlain
steven@pyro.eu.org



Reply to: