aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Watson <rwatson@FreeBSD.org>2008-04-20 00:21:54 +0000
committerRobert Watson <rwatson@FreeBSD.org>2008-04-20 00:21:54 +0000
commitfdd9b0723ec178e5ac97e5ffb4dde526dcc353cb (patch)
tree1fcfbb3ee5c99f57f95b033d08da73ca3b91e11d
parent42018dcf7b584c7d1355b6ead04c06931b4175cb (diff)
downloadsrc-fdd9b0723ec178e5ac97e5ffb4dde526dcc353cb.tar.gz
src-fdd9b0723ec178e5ac97e5ffb4dde526dcc353cb.zip
Teach pf and ipfw to use read locks in inpcbs write than write locks
when reading credential data from sockets. Teach pf to unlock the pcbinfo more quickly once it has acquired an inpcb lock, as the inpcb lock is sufficient to protect the reference. Assert locks, rather than read locks or write locks, on inpcbs in subroutines--this is necessary as the inpcb may be passed down with a write lock from the protocol, or may be passed down with a read lock from the firewall lookup routine, and either is sufficient. MFC after: 3 months
Notes
Notes: svn path=/head/; revision=178325
-rw-r--r--sys/contrib/pf/net/pf.c11
-rw-r--r--sys/netinet/ip_fw2.c6
2 files changed, 8 insertions, 9 deletions
diff --git a/sys/contrib/pf/net/pf.c b/sys/contrib/pf/net/pf.c
index 69fe3de830fc..96bf2de789e9 100644
--- a/sys/contrib/pf/net/pf.c
+++ b/sys/contrib/pf/net/pf.c
@@ -2915,7 +2915,7 @@ pf_socket_lookup(int direction, struct pf_pdesc *pd)
pd->lookup.pid = NO_PID; /* XXX: revisit */
#ifdef __FreeBSD__
if (inp_arg != NULL) {
- INP_WLOCK_ASSERT(inp_arg);
+ INP_LOCK_ASSERT(inp_arg);
if (inp_arg->inp_socket) {
pd->lookup.uid = inp_arg->inp_socket->so_cred->cr_uid;
pd->lookup.gid =
@@ -3018,16 +3018,15 @@ pf_socket_lookup(int direction, struct pf_pdesc *pd)
return (-1);
}
#ifdef __FreeBSD__
- INP_WLOCK(inp);
+ INP_RLOCK(inp);
+ INP_INFO_RUNLOCK(pi);
if ((inp->inp_socket == NULL) || (inp->inp_socket->so_cred == NULL)) {
- INP_WUNLOCK(inp);
- INP_INFO_RUNLOCK(pi);
+ INP_RUNLOCK(inp);
return (-1);
}
pd->lookup.uid = inp->inp_socket->so_cred->cr_uid;
pd->lookup.gid = inp->inp_socket->so_cred->cr_groups[0];
- INP_WUNLOCK(inp);
- INP_INFO_RUNLOCK(pi);
+ INP_RUNLOCK(inp);
#else
pd->lookup.uid = inp->inp_socket->so_euid;
pd->lookup.gid = inp->inp_socket->so_egid;
diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c
index 428a18249d78..39baa71ebce7 100644
--- a/sys/netinet/ip_fw2.c
+++ b/sys/netinet/ip_fw2.c
@@ -1974,7 +1974,7 @@ check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
* up the PCB, we can use the one that was supplied.
*/
if (inp && *lookup == 0) {
- INP_WLOCK_ASSERT(inp);
+ INP_LOCK_ASSERT(inp);
if (inp->inp_socket != NULL) {
fill_ugid_cache(inp, ugp);
*lookup = 1;
@@ -2008,12 +2008,12 @@ check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
dst_ip, htons(dst_port),
wildcard, NULL);
if (pcb != NULL) {
- INP_WLOCK(pcb);
+ INP_RLOCK(pcb);
if (pcb->inp_socket != NULL) {
fill_ugid_cache(pcb, ugp);
*lookup = 1;
}
- INP_WUNLOCK(pcb);
+ INP_RUNLOCK(pcb);
}
INP_INFO_RUNLOCK(pi);
if (*lookup == 0) {