ipfilter: Support only jails in VNET

Jails without VNET have complete access to the ipfilter rules, NAT,
pools and logs. This is insecure. Only allow jails to manipulate
ipfilter rules, NAT tables and ippools if the jail has its own VNET.
Otherwise a jail can affect the global system.

This patch brings ipfilter in line with ipfw's support of VNET jails and
non-support of non-VNET jails.

MFC after:	1 week
This commit is contained in:
Cy Schubert 2022-03-17 11:05:05 -07:00
parent 70b56f4b92
commit c47db49ba4
4 changed files with 31 additions and 1 deletions

View File

@ -17,7 +17,7 @@ typedef struct {
static ipf_error_entry_t *find_error(int);
#define IPF_NUM_ERRORS 475
#define IPF_NUM_ERRORS 477
/*
* NO REUSE OF NUMBERS!
@ -355,6 +355,7 @@ log" },
{ 60073, "unknown lookup group for next address (ipv6)" },
{ 60074, "unknown next address type (ipv6)" },
{ 60075, "one object at a time must be copied" },
{ 60076, "NAT ioctl denied in jail without VNET" },
/* -------------------------------------------------------------------------- */
{ 70001, "incorrect object size to get pool stats" },
{ 70002, "could not malloc memory for new pool node" },
@ -516,6 +517,7 @@ log" },
{ 130015, "ipf_init_all failed" },
{ 130016, "finding pfil head failed" },
{ 130017, "ipfilter is already initialised and running" },
{ 130018, "ioctl denied in jail without VNET" },
};

View File

@ -47,6 +47,7 @@ static const char rcsid[] = "@(#)$Id$";
#include <net/route/nhop.h>
#include <netinet/in.h>
#include <netinet/in_fib.h>
#include <netinet/in_pcb.h>
#include <netinet/in_var.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
@ -281,6 +282,12 @@ ipfioctl(struct cdev *dev, ioctlcmd_t cmd, caddr_t data,
return (EPERM);
}
if (jailed_without_vnet(p->p_cred)) {
V_ipfmain.ipf_interror = 130018;
CURVNET_RESTORE();
return (EOPNOTSUPP);
}
unit = GET_MINOR(dev);
if ((IPL_LOGMAX < unit) || (unit < 0)) {
V_ipfmain.ipf_interror = 130002;

View File

@ -42,6 +42,9 @@ struct file;
#include <sys/socket.h>
#if defined(_KERNEL)
# include <sys/systm.h>
# if defined(__FreeBSD__)
# include <sys/jail.h>
# endif
# if !defined(__SVR4)
# include <sys/mbuf.h>
# endif
@ -999,6 +1002,12 @@ ipf_nat_ioctl(ipf_main_softc_t *softc, caddr_t data, ioctlcmd_t cmd,
IPFERROR(60001);
return (EPERM);
}
# if defined(__FreeBSD__)
if (jailed_without_vnet(curthread->td_ucred)) {
IPFERROR(60076);
return (EOPNOTSUPP);
}
# endif
#endif
getlock = (mode & NAT_LOCKHELD) ? 0 : 1;

View File

@ -377,6 +377,9 @@ sysctl_error:
static int
sysctl_ipf_int_nat ( SYSCTL_HANDLER_ARGS )
{
if (jailed_without_vnet(curthread->td_ucred))
return (0);
ipf_nat_softc_t *nat_softc;
nat_softc = V_ipfmain.ipf_nat_soft;
@ -388,6 +391,9 @@ sysctl_ipf_int_nat ( SYSCTL_HANDLER_ARGS )
static int
sysctl_ipf_int_state ( SYSCTL_HANDLER_ARGS )
{
if (jailed_without_vnet(curthread->td_ucred))
return (0);
ipf_state_softc_t *state_softc;
state_softc = V_ipfmain.ipf_state_soft;
@ -399,6 +405,9 @@ sysctl_ipf_int_state ( SYSCTL_HANDLER_ARGS )
static int
sysctl_ipf_int_auth ( SYSCTL_HANDLER_ARGS )
{
if (jailed_without_vnet(curthread->td_ucred))
return (0);
ipf_auth_softc_t *auth_softc;
auth_softc = V_ipfmain.ipf_auth_soft;
@ -410,6 +419,9 @@ sysctl_ipf_int_auth ( SYSCTL_HANDLER_ARGS )
static int
sysctl_ipf_int_frag ( SYSCTL_HANDLER_ARGS )
{
if (jailed_without_vnet(curthread->td_ucred))
return (0);
ipf_frag_softc_t *frag_softc;
frag_softc = V_ipfmain.ipf_frag_soft;