The branch main has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=a306ed50ecd57f060a549c14bc53a60b34aaa6bb

commit a306ed50ecd57f060a549c14bc53a60b34aaa6bb
Author:     Mark Johnston <ma...@freebsd.org>
AuthorDate: 2023-05-30 19:15:48 +0000
Commit:     Mark Johnston <ma...@freebsd.org>
CommitDate: 2023-05-30 19:15:48 +0000

    inpcb: Restore missing validation of local addresses for jailed sockets
    
    When looking up a listening socket, the SMR-protected lookup routine may
    return a jailed socket with no local address.  This happens when using
    classic jails with more than one IP address; in a single-IP classic
    jail, a bound socket's local address is always rewritten to be that of
    the jail.
    
    After commit 7b92493ab1d4, the lookup path failed to check whether the
    jail corresponding to a matched wildcard socket actually owns the
    address, and would return the match regardless.  Restore the omitted
    checks.
    
    Fixes:          7b92493ab1d4 ("inpcb: Avoid inp_cred dereferences in 
SMR-protected lookup")
    Reported by:    peter
    Reviewed by:    bz
    Differential Revision:  https://reviews.freebsd.org/D40268
---
 sys/netinet/in_pcb.c   | 6 ++++--
 sys/netinet6/in6_pcb.c | 6 ++++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 350d08360105..5fddff89dd0a 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -2254,8 +2254,10 @@ in_pcblookup_hash_wild_smr(struct inpcbinfo *pcbinfo, 
struct in_addr faddr,
                        continue;
 
                if (__predict_true(inp_smr_lock(inp, lockflags))) {
-                       if (__predict_true(in_pcblookup_wild_match(inp, laddr,
-                           lport) != INPLOOKUP_MATCH_NONE))
+                       match = in_pcblookup_wild_match(inp, laddr, lport);
+                       if (match != INPLOOKUP_MATCH_NONE &&
+                           prison_check_ip4_locked(inp->inp_cred->cr_prison,
+                           &laddr) == 0)
                                return (inp);
                        inp_unlock(inp, lockflags);
                }
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index da7ed5ca79e0..43f567461598 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -1021,8 +1021,10 @@ in6_pcblookup_hash_wild_smr(struct inpcbinfo *pcbinfo,
                        continue;
 
                if (__predict_true(inp_smr_lock(inp, lockflags))) {
-                       if (__predict_true(in6_pcblookup_wild_match(inp, laddr,
-                           lport) != INPLOOKUP_MATCH_NONE))
+                       match = in6_pcblookup_wild_match(inp, laddr, lport);
+                       if (match != INPLOOKUP_MATCH_NONE &&
+                           prison_check_ip6_locked(inp->inp_cred->cr_prison,
+                           laddr) == 0)
                                return (inp);
                        inp_unlock(inp, lockflags);
                }

Reply via email to