Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F141979960
D14623.id40076.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D14623.id40076.diff
View Options
Index: sys/netinet/ip_output.c
===================================================================
--- sys/netinet/ip_output.c
+++ sys/netinet/ip_output.c
@@ -1226,7 +1226,10 @@
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
case IP_IPSEC_POLICY:
if (IPSEC_ENABLED(ipv4)) {
+ INP_WLOCK(inp);
error = IPSEC_PCBCTL(ipv4, inp, sopt);
+ if (!error)
+ INP_WUNLOCK(inp);
break;
}
/* FALLTHROUGH */
@@ -1380,7 +1383,9 @@
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
case IP_IPSEC_POLICY:
if (IPSEC_ENABLED(ipv4)) {
+ INP_WLOCK(inp);
error = IPSEC_PCBCTL(ipv4, inp, sopt);
+ INP_WUNLOCK(inp);
break;
}
/* FALLTHROUGH */
Index: sys/netinet6/ip6_output.c
===================================================================
--- sys/netinet6/ip6_output.c
+++ sys/netinet6/ip6_output.c
@@ -1905,7 +1905,10 @@
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
case IPV6_IPSEC_POLICY:
if (IPSEC_ENABLED(ipv6)) {
+ INP_WLOCK(in6p);
error = IPSEC_PCBCTL(ipv6, in6p, sopt);
+ if (!error)
+ INP_WUNLOCK(in6p);
break;
}
/* FALLTHROUGH */
@@ -2140,7 +2143,9 @@
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
case IPV6_IPSEC_POLICY:
if (IPSEC_ENABLED(ipv6)) {
+ INP_RLOCK(in6p);
error = IPSEC_PCBCTL(ipv6, in6p, sopt);
+ INP_RUNLOCK(in6p);
break;
}
/* FALLTHROUGH */
Index: sys/netipsec/ipsec_pcb.c
===================================================================
--- sys/netipsec/ipsec_pcb.c
+++ sys/netipsec/ipsec_pcb.c
@@ -276,6 +276,8 @@
struct secpolicy **spp, *newsp;
int error, flags;
+ INP_WLOCK_ASSERT(inp);
+
xpl = (struct sadb_x_policy *)request;
/* Select direction. */
switch (xpl->sadb_x_policy_dir) {
@@ -332,7 +334,6 @@
return (EINVAL);
}
- INP_WLOCK(inp);
if (xpl->sadb_x_policy_dir == IPSEC_DIR_INBOUND) {
spp = &inp->inp_sp->sp_in;
flags = INP_INBOUND_POLICY;
@@ -352,7 +353,6 @@
inp->inp_sp->flags |= flags;
KEYDBG(IPSEC_DUMP, kdebug_secpolicy(newsp));
}
- INP_WUNLOCK(inp);
return (0);
}
@@ -365,7 +365,7 @@
xpl = (struct sadb_x_policy *)request;
- INP_RLOCK(inp);
+ INP_WLOCK_ASSERT(inp);
flags = inp->inp_sp->flags;
/* Select direction. */
switch (xpl->sadb_x_policy_dir) {
@@ -378,7 +378,6 @@
flags &= INP_OUTBOUND_POLICY;
break;
default:
- INP_RUNLOCK(inp);
ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__,
xpl->sadb_x_policy_dir));
return (EINVAL);
@@ -386,7 +385,6 @@
if (flags == 0) {
/* Return ENTRUST policy */
- INP_RUNLOCK(inp);
xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
xpl->sadb_x_policy_type = IPSEC_POLICY_ENTRUST;
xpl->sadb_x_policy_id = 0;
@@ -400,7 +398,6 @@
("sp is NULL, but flags is 0x%04x", inp->inp_sp->flags));
key_addref(sp);
- INP_RUNLOCK(inp);
error = key_sp2msg(sp, request, len);
key_freesp(&sp);
if (error == EINVAL)
@@ -421,30 +418,43 @@
size_t optlen;
int error;
- if (inp->inp_sp == NULL)
+ INP_WLOCK_ASSERT(inp);
+
+ if (inp->inp_sp == NULL) {
+ INP_WUNLOCK(inp);
return (ENOPROTOOPT);
+ }
/* Limit maximum request size to PAGE_SIZE */
optlen = sopt->sopt_valsize;
- if (optlen < sizeof(struct sadb_x_policy) || optlen > PAGE_SIZE)
+ if (optlen < sizeof(struct sadb_x_policy) || optlen > PAGE_SIZE) {
+ INP_WUNLOCK(inp);
return (EINVAL);
+ }
optdata = malloc(optlen, M_TEMP, sopt->sopt_td ? M_WAITOK: M_NOWAIT);
- if (optdata == NULL)
+ if (optdata == NULL) {
+ INP_WUNLOCK(inp);
return (ENOBUFS);
+ }
/*
* We need a hint from the user, what policy is requested - input
* or output? User should specify it in the buffer, even for
* setsockopt().
*/
+ INP_WUNLOCK(inp);
error = sooptcopyin(sopt, optdata, optlen, optlen);
+ INP_WLOCK(inp);
if (error == 0) {
- if (sopt->sopt_dir == SOPT_SET)
+ if (sopt->sopt_dir == SOPT_SET) {
error = ipsec_set_pcbpolicy(inp,
sopt->sopt_td ? sopt->sopt_td->td_ucred: NULL,
optdata, optlen);
- else {
+ if (error != 0)
+ INP_WUNLOCK(inp);
+ } else {
error = ipsec_get_pcbpolicy(inp, optdata, &optlen);
+ INP_WUNLOCK(inp);
if (error == 0)
error = sooptcopyout(sopt, optdata, optlen);
}
Index: sys/netipsec/ipsec_support.h
===================================================================
--- sys/netipsec/ipsec_support.h
+++ sys/netipsec/ipsec_support.h
@@ -44,6 +44,14 @@
int ipsec_delete_pcbpolicy(struct inpcb *);
int ipsec_copy_pcbpolicy(struct inpcb *, struct inpcb *);
+/*
+ * The pcbctl function has the following locking characteristics:
+ * On setting values, the inp must already be wlocked. If an error is
+ * returned, the lock must be released. If there is no error returned,
+ * then the lock must be held.
+ * On getting values, the inp must already be wlocked. The lock must be
+ * released before returning.
+ */
struct ipsec_methods {
int (*input)(struct mbuf *, int, int);
int (*check_policy)(const struct mbuf *, struct inpcb *);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jan 15, 11:35 AM (1 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27648161
Default Alt Text
D14623.id40076.diff (4 KB)
Attached To
Mode
D14623: fix locking within tcp_ipsec_pcbctl() to match ipsec4_pcbctl(), ipsec4_pcbctl()
Attached
Detach File
Event Timeline
Log In to Comment