From f1446f13d8678020887da93760cdbb59ed90e124 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Sun, 27 Oct 2013 19:00:36 +0100 Subject: net->user_ns is available starting from 3.8, add compatibility checking Reported by Jan Engelhardt --- configure.ac | 10 ++++++++++ kernel/include/linux/netfilter/ipset/ip_set_compat.h.in | 1 + kernel/net/netfilter/ipset/ip_set_core.c | 4 ++++ 3 files changed, 15 insertions(+) diff --git a/configure.ac b/configure.ac index d56328c..c5f3770 100644 --- a/configure.ac +++ b/configure.ac @@ -303,6 +303,16 @@ else AC_SUBST(HAVE_NET_OPS_ID, undef) fi +AC_MSG_CHECKING([kernel source for user_ns in struct net]) +if test -f $ksourcedir/include/net/net_namespace.h && \ + $AWK '/^struct net \{/ {for(i=1; i<=20; i++) {getline; print}}' $ksourcedir/include/net/net_namespace.h | $GREP -q 'user_ns'; then + AC_MSG_RESULT(yes) + AC_SUBST(HAVE_USER_NS_IN_STRUCT_NET, define) +else + AC_MSG_RESULT(no) + AC_SUBST(HAVE_USER_NS_IN_STRUCT_NET, undef) +fi + AC_MSG_CHECKING([kernel source for struct net_generic]) if test -f $ksourcedir/include/net/netns/generic.h && \ $GREP -q 'struct net_generic' $ksourcedir/include/net/netns/generic.h; then diff --git a/kernel/include/linux/netfilter/ipset/ip_set_compat.h.in b/kernel/include/linux/netfilter/ipset/ip_set_compat.h.in index ce4d922..4a076f8 100644 --- a/kernel/include/linux/netfilter/ipset/ip_set_compat.h.in +++ b/kernel/include/linux/netfilter/ipset/ip_set_compat.h.in @@ -22,6 +22,7 @@ #@HAVE_CHECKENTRY_BOOL@ HAVE_CHECKENTRY_BOOL #@HAVE_XT_TARGET_PARAM@ HAVE_XT_TARGET_PARAM #@HAVE_NET_OPS_ID@ HAVE_NET_OPS_ID +#@HAVE_USER_NS_IN_STRUCT_NET@ HAVE_USER_NS_IN_STRUCT_NET /* Not everything could be moved here. Compatibility stuffs can be found in * xt_set.c, ip_set_core.c, ip_set_getport.c, pfxlen.c too. diff --git a/kernel/net/netfilter/ipset/ip_set_core.c b/kernel/net/netfilter/ipset/ip_set_core.c index c1989d9..e43d7db 100644 --- a/kernel/net/netfilter/ipset/ip_set_core.c +++ b/kernel/net/netfilter/ipset/ip_set_core.c @@ -1864,7 +1864,11 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len) struct net *net = sock_net(sk); struct ip_set_net *inst = ip_set_pernet(net); +#ifdef HAVE_USER_NS_IN_STRUCT_NET if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) +#else + if (!capable(CAP_NET_ADMIN)) +#endif return -EPERM; if (optval != SO_IP_SET) return -EBADF; -- cgit v1.2.3