Page MenuHomeFreeBSD

D2901.id6444.diff
No OneTemporary

D2901.id6444.diff

Index: sys/conf/files
===================================================================
--- sys/conf/files
+++ sys/conf/files
@@ -3456,6 +3456,7 @@
netinet/in_mcast.c optional inet
netinet/in_pcb.c optional inet | inet6
netinet/in_pcbgroup.c optional inet pcbgroup | inet6 pcbgroup
+netinet/in_prot.c optional inet | inet6
netinet/in_proto.c optional inet | inet6
netinet/in_rmx.c optional inet
netinet/in_rss.c optional inet rss
Index: sys/kern/kern_prot.c
===================================================================
--- sys/kern/kern_prot.c
+++ sys/kern/kern_prot.c
@@ -76,11 +76,6 @@
"Kernel support for interfaces necessary for regression testing (SECURITY RISK!)");
#endif
-#if defined(INET) || defined(INET6)
-#include <netinet/in.h>
-#include <netinet/in_pcb.h>
-#endif
-
#include <security/audit/audit.h>
#include <security/mac/mac_framework.h>
@@ -1343,8 +1338,8 @@
* References: *u1 and *u2 must not change during the call
* u1 may equal u2, in which case only one reference is required
*/
-static int
-cr_seeotheruids(struct ucred *u1, struct ucred *u2)
+int
+cr_canseeotheruids(struct ucred *u1, struct ucred *u2)
{
if (!see_other_uids && u1->cr_ruid != u2->cr_ruid) {
@@ -1373,8 +1368,8 @@
* References: *u1 and *u2 must not change during the call
* u1 may equal u2, in which case only one reference is required
*/
-static int
-cr_seeothergids(struct ucred *u1, struct ucred *u2)
+int
+cr_canseeothergids(struct ucred *u1, struct ucred *u2)
{
int i, match;
@@ -1412,9 +1407,9 @@
if ((error = mac_cred_check_visible(u1, u2)))
return (error);
#endif
- if ((error = cr_seeotheruids(u1, u2)))
+ if ((error = cr_canseeotheruids(u1, u2)))
return (error);
- if ((error = cr_seeothergids(u1, u2)))
+ if ((error = cr_canseeothergids(u1, u2)))
return (error);
return (0);
}
@@ -1473,9 +1468,9 @@
if ((error = mac_proc_check_signal(cred, proc, signum)))
return (error);
#endif
- if ((error = cr_seeotheruids(cred, proc->p_ucred)))
+ if ((error = cr_canseeotheruids(cred, proc->p_ucred)))
return (error);
- if ((error = cr_seeothergids(cred, proc->p_ucred)))
+ if ((error = cr_canseeothergids(cred, proc->p_ucred)))
return (error);
/*
@@ -1590,9 +1585,9 @@
if ((error = mac_proc_check_sched(td->td_ucred, p)))
return (error);
#endif
- if ((error = cr_seeotheruids(td->td_ucred, p->p_ucred)))
+ if ((error = cr_canseeotheruids(td->td_ucred, p->p_ucred)))
return (error);
- if ((error = cr_seeothergids(td->td_ucred, p->p_ucred)))
+ if ((error = cr_canseeothergids(td->td_ucred, p->p_ucred)))
return (error);
if (td->td_ucred->cr_ruid != p->p_ucred->cr_ruid &&
td->td_ucred->cr_uid != p->p_ucred->cr_ruid) {
@@ -1647,9 +1642,9 @@
if ((error = mac_proc_check_debug(td->td_ucred, p)))
return (error);
#endif
- if ((error = cr_seeotheruids(td->td_ucred, p->p_ucred)))
+ if ((error = cr_canseeotheruids(td->td_ucred, p->p_ucred)))
return (error);
- if ((error = cr_seeothergids(td->td_ucred, p->p_ucred)))
+ if ((error = cr_canseeothergids(td->td_ucred, p->p_ucred)))
return (error);
/*
@@ -1741,42 +1736,14 @@
if (error)
return (error);
#endif
- if (cr_seeotheruids(cred, so->so_cred))
+ if (cr_canseeotheruids(cred, so->so_cred))
return (ENOENT);
- if (cr_seeothergids(cred, so->so_cred))
+ if (cr_canseeothergids(cred, so->so_cred))
return (ENOENT);
return (0);
}
-#if defined(INET) || defined(INET6)
-/*-
- * Determine whether the subject represented by cred can "see" a socket.
- * Returns: 0 for permitted, ENOENT otherwise.
- */
-int
-cr_canseeinpcb(struct ucred *cred, struct inpcb *inp)
-{
- int error;
-
- error = prison_check(cred, inp->inp_cred);
- if (error)
- return (ENOENT);
-#ifdef MAC
- INP_LOCK_ASSERT(inp);
- error = mac_inpcb_check_visible(cred, inp);
- if (error)
- return (error);
-#endif
- if (cr_seeotheruids(cred, inp->inp_cred))
- return (ENOENT);
- if (cr_seeothergids(cred, inp->inp_cred))
- return (ENOENT);
-
- return (0);
-}
-#endif
-
/*-
* Determine whether td can wait for the exit of p.
* Returns: 0 for permitted, an errno value otherwise
@@ -1801,7 +1768,7 @@
#endif
#if 0
/* XXXMAC: This could have odd effects on some shells. */
- if ((error = cr_seeotheruids(td->td_ucred, p->p_ucred)))
+ if ((error = cr_canseeotheruids(td->td_ucred, p->p_ucred)))
return (error);
#endif
Index: sys/kern/sys_socket.c
===================================================================
--- sys/kern/sys_socket.c
+++ sys/kern/sys_socket.c
@@ -1,6 +1,8 @@
/*-
* Copyright (c) 1982, 1986, 1990, 1993
* The Regents of the University of California. All rights reserved.
+ * Copyright (c) 2012, 2013, 2015, Juniper Networks, Inc.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,7 +39,10 @@
#include <sys/domain.h>
#include <sys/file.h>
#include <sys/filedesc.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
#include <sys/malloc.h>
+#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/sigio.h>
@@ -89,6 +94,73 @@
.fo_flags = DFLAG_PASSABLE
};
+static struct socket_iocgroup *so_iocgroups;
+static int so_iocgroup_init_status;
+static struct mtx soiocg_mtx;
+MTX_SYSINIT(soiocg, &soiocg_mtx, "socket ioctl groups", MTX_DEF);
+
+static void so_iocgroupinit(void *);
+SYSINIT(so_iocgroup, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY, so_iocgroupinit,
+ NULL);
+
+static void so_iocgroupfinalize(void *);
+SYSINIT(so_iocgroupfin, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_FIRST,
+ so_iocgroupfinalize, NULL);
+
+void
+so_iocgroup_add(void *data)
+{
+ struct socket_iocgroup *gp;
+
+ gp = (struct socket_iocgroup *)data;
+ mtx_lock(&soiocg_mtx);
+ gp->soiocg_next = so_iocgroups;
+ so_iocgroups = gp;
+
+ KASSERT(so_iocgroup_init_status >= 1,
+ ("attempt to so_iocgroup_add(%c) before so_iocgroupinit()",
+ gp->soiocg_group));
+#ifndef INVARIANTS
+ if (so_iocgroup_init_status < 1)
+ printf("WARNING: attempt to so_iocgroup_add(%c) before "
+ "so_iocgroupinit()\n", gp->soiocg_group);
+#endif
+#ifdef notyet
+ KASSERT(so_iocgroup_init_status < 2,
+ ("attempt to so_iocgroup_add(%c) after so_iocgroupfinalize()",
+ gp->soiocg_group));
+#else
+ if (so_iocgroup_init_status >= 2)
+ printf("WARNING: attempt to so_iocgroup_add(%c) after "
+ "so_iocgroupfinalize()\n", gp->soiocg_group);
+#endif
+ mtx_unlock(&soiocg_mtx);
+}
+
+/* ARGSUSED*/
+static void
+so_iocgroupinit(void *dummy)
+{
+
+ mtx_lock(&soiocg_mtx);
+ KASSERT(so_iocgroup_init_status == 0,
+ ("so_iocgroupinit called too late!"));
+ so_iocgroup_init_status = 1;
+ mtx_unlock(&soiocg_mtx);
+}
+
+/* ARGSUSED*/
+static void
+so_iocgroupfinalize(void *dummy)
+{
+
+ mtx_lock(&soiocg_mtx);
+ KASSERT(so_iocgroup_init_status == 1,
+ ("so_iocgroupfinalize called too late!"));
+ so_iocgroup_init_status = 2;
+ mtx_unlock(&soiocg_mtx);
+}
+
static int
soo_read(struct file *fp, struct uio *uio, struct ucred *active_cred,
int flags, struct thread *td)
@@ -131,6 +203,7 @@
struct thread *td)
{
struct socket *so = fp->f_data;
+ struct socket_iocgroup *soiocg;
int error = 0;
switch (cmd) {
@@ -218,13 +291,13 @@
* routing ioctls should have a different entry since a
* socket is unnecessary.
*/
- if (IOCGROUP(cmd) == 'i')
- error = ifioctl(so, cmd, data, td);
- else if (IOCGROUP(cmd) == 'r') {
- CURVNET_SET(so->so_vnet);
- error = rtioctl_fib(cmd, data, so->so_fibnum);
- CURVNET_RESTORE();
- } else {
+ for (soiocg = so_iocgroups; soiocg;
+ soiocg = soiocg->soiocg_next)
+ if (soiocg->soiocg_group == IOCGROUP(cmd))
+ break;
+ if (soiocg && soiocg->soiocg_ioctl)
+ error = ((*soiocg->soiocg_ioctl)(so, cmd, data, td));
+ else {
CURVNET_SET(so->so_vnet);
error = ((*so->so_proto->pr_usrreqs->pru_control)
(so, cmd, data, 0, td));
Index: sys/net/if.c
===================================================================
--- sys/net/if.c
+++ sys/net/if.c
@@ -120,6 +120,12 @@
static MALLOC_DEFINE(M_IFDESCR, "ifdescr", "ifnet descriptions");
+static struct socket_iocgroup ifiocgroup = {
+ .soiocg_group = 'i',
+ .soiocg_ioctl = ifioctl
+};
+SO_IOCGROUP_SET(if);
+
/* global sx for non-critical path ifdescr */
static struct sx ifdescr_sx;
SX_SYSINIT(ifdescr_sx, &ifdescr_sx, "ifnet descr");
Index: sys/net/route.c
===================================================================
--- sys/net/route.c
+++ sys/net/route.c
@@ -46,6 +46,7 @@
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
+#include <sys/socketvar.h>
#include <sys/sysctl.h>
#include <sys/syslog.h>
#include <sys/sysproto.h>
@@ -147,6 +148,14 @@
};
static int if_updatemtu_cb(struct radix_node *, void *);
+static int rtioctl_socket(struct socket *, u_long, caddr_t,
+ struct thread *);
+
+static struct socket_iocgroup rtiocgroup = {
+ .soiocg_group = 'r',
+ .soiocg_ioctl = rtioctl_socket
+};
+SO_IOCGROUP_SET(rt);
/*
* handler for net.my_fibnum
@@ -702,6 +711,20 @@
#endif /* INET */
}
+
+static int
+rtioctl_socket(struct socket *so, u_long cmd, caddr_t data,
+ struct thread *td __unused)
+{
+ int error;
+
+ CURVNET_SET(so->so_vnet);
+ error = rtioctl_fib(cmd, data, so->so_fibnum);
+ CURVNET_RESTORE();
+
+ return (error);
+}
+
struct ifaddr *
ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway,
u_int fibnum)
Index: sys/netinet/in_prot.c
===================================================================
--- /dev/null
+++ sys/netinet/in_prot.c
@@ -0,0 +1,90 @@
+/*-
+ * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
+ * The Regents of the University of California.
+ * (c) UNIX System Laboratories, Inc.
+ * Copyright (c) 2000-2001 Robert N. M. Watson.
+ * All rights reserved.
+ *
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)kern_prot.c 8.6 (Berkeley) 1/21/94
+ */
+
+/*
+ * System calls related to processes and protection
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_compat.h"
+#include "opt_inet.h"
+#include "opt_inet6.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/jail.h>
+
+#include <netinet/in.h>
+#include <netinet/in_pcb.h>
+#include <netinet/in_systm.h>
+
+#include <security/audit/audit.h>
+#include <security/mac/mac_framework.h>
+
+/*-
+ * Determine whether the subject represented by cred can "see" a socket.
+ * Returns: 0 for permitted, ENOENT otherwise.
+ */
+int
+cr_canseeinpcb(struct ucred *cred, struct inpcb *inp)
+{
+ int error;
+
+ error = prison_check(cred, inp->inp_cred);
+ if (error)
+ return (ENOENT);
+#ifdef MAC
+ INP_LOCK_ASSERT(inp);
+ error = mac_inpcb_check_visible(cred, inp);
+ if (error)
+ return (error);
+#endif
+ if (cr_canseeotheruids(cred, inp->inp_cred))
+ return (ENOENT);
+ if (cr_canseeothergids(cred, inp->inp_cred))
+ return (ENOENT);
+
+ return (0);
+}
Index: sys/netinet/in_systm.h
===================================================================
--- sys/netinet/in_systm.h
+++ sys/netinet/in_systm.h
@@ -55,6 +55,11 @@
typedef u_int32_t n_time; /* ms since 00:00 UTC, byte rev */
#ifdef _KERNEL
+struct inpcb;
+struct ucred;
+
+int cr_canseeinpcb(struct ucred *cred, struct inpcb *inp);
+
uint32_t iptime(void);
#endif
Index: sys/netinet6/ip6_forward.c
===================================================================
--- sys/netinet6/ip6_forward.c
+++ sys/netinet6/ip6_forward.c
@@ -104,9 +104,6 @@
#ifdef IPSEC
struct secpolicy *sp = NULL;
#endif
-#ifdef SCTP
- int sw_csum;
-#endif
struct m_tag *fwd_tag;
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
Index: sys/sys/socketvar.h
===================================================================
--- sys/sys/socketvar.h
+++ sys/sys/socketvar.h
@@ -130,6 +130,17 @@
uint32_t so_user_cookie;
};
+struct socket_iocgroup {
+ char soiocg_group;
+ int (*soiocg_ioctl)(struct socket *, u_long, caddr_t,
+ struct thread *);
+ struct socket_iocgroup *soiocg_next;
+};
+
+#define SO_IOCGROUP_SET(name) \
+ SYSINIT(so_iocgroup_add_ ## name, SI_SUB_PROTO_DOMAIN, \
+ SI_ORDER_FIRST, so_iocgroup_add, & name ## iocgroup)
+
/*
* Global accept mutex to serialize access to accept queues and
* fields associated with multiple sockets. This allows us to
@@ -334,6 +345,8 @@
#define SU_OK 0
#define SU_ISCONNECTED 1
+void so_iocgroup_add(void *);
+
/*
* From uipc_socket and friends
*/
Index: sys/sys/systm.h
===================================================================
--- sys/sys/systm.h
+++ sys/sys/systm.h
@@ -307,7 +307,8 @@
int cr_cansee(struct ucred *u1, struct ucred *u2);
int cr_canseesocket(struct ucred *cred, struct socket *so);
-int cr_canseeinpcb(struct ucred *cred, struct inpcb *inp);
+int cr_canseeothergids(struct ucred *u1, struct ucred *u2);
+int cr_canseeotheruids(struct ucred *u1, struct ucred *u2);
char *kern_getenv(const char *name);
void freeenv(char *env);

File Metadata

Mime Type
text/plain
Expires
Tue, Nov 25, 9:26 AM (3 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26107609
Default Alt Text
D2901.id6444.diff (14 KB)

Event Timeline