From: bluhm Date: Thu, 11 Jan 2024 14:15:11 +0000 (+0000) Subject: Use domain name for socket lock. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=66bd633ef3ceac8f520e69ac0537c92cf7c0b2e7;p=openbsd Use domain name for socket lock. Syzkaller with witness complains about lock ordering of pf lock with socket lock. Socket lock for inet is taken before pf lock. Pf lock is taken before socket lock for route. This is a false positive as route and inet socket locks are distinct. Witness does not know this. Name the socket lock like the domain of the socket, then rwlock name is used in witness lo_name subtype. Make domain names more consistent for locking, they were not used anyway. Regardless of witness problem, unique lock name for each socket type make sense. Reported-by: syzbot+34d22dcbf20d76629c5a@syzkaller.appspotmail.com Reported-by: syzbot+fde8d07ba74b69d0adfe@syzkaller.appspotmail.com OK mvs@ --- diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c index 78ae0900a00..da73a54b672 100644 --- a/sys/kern/uipc_domain.c +++ b/sys/kern/uipc_domain.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_domain.c,v 1.64 2023/05/18 10:23:19 mvs Exp $ */ +/* $OpenBSD: uipc_domain.c,v 1.65 2024/01/11 14:15:11 bluhm Exp $ */ /* $NetBSD: uipc_domain.c,v 1.14 1996/02/09 19:00:44 christos Exp $ */ /* @@ -62,7 +62,6 @@ const struct domain *const domains[] = { void pffasttimo(void *); void pfslowtimo(void *); -const struct domain * pffinddomain(int); void domaininit(void) diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 5005fef0932..913649f1f81 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket.c,v 1.312 2023/12/19 21:34:22 bluhm Exp $ */ +/* $OpenBSD: uipc_socket.c,v 1.313 2024/01/11 14:15:11 bluhm Exp $ */ /* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */ /* @@ -148,7 +148,7 @@ soinit(void) } struct socket * -soalloc(int wait) +soalloc(const struct domain *dp, int wait) { struct socket *so; @@ -156,7 +156,7 @@ soalloc(int wait) PR_ZERO); if (so == NULL) return (NULL); - rw_init_flags(&so->so_lock, "solock", RWL_DUPOK); + rw_init_flags(&so->so_lock, dp->dom_name, RWL_DUPOK); refcnt_init(&so->so_refcnt); klist_init(&so->so_rcv.sb_klist, &socket_klistops, so); klist_init(&so->so_snd.sb_klist, &socket_klistops, so); @@ -190,7 +190,7 @@ socreate(int dom, struct socket **aso, int type, int proto) return (EPROTONOSUPPORT); if (prp->pr_type != type) return (EPROTOTYPE); - so = soalloc(M_WAIT); + so = soalloc(pffinddomain(dom), M_WAIT); so->so_type = type; if (suser(p) == 0) so->so_state = SS_PRIV; diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index 18f7746f611..5b55090dd71 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket2.c,v 1.139 2023/12/18 13:11:20 bluhm Exp $ */ +/* $OpenBSD: uipc_socket2.c,v 1.140 2024/01/11 14:15:11 bluhm Exp $ */ /* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */ /* @@ -188,7 +188,7 @@ sonewconn(struct socket *head, int connstatus, int wait) return (NULL); if (head->so_qlen + head->so_q0len > head->so_qlimit * 3) return (NULL); - so = soalloc(wait); + so = soalloc(head->so_proto->pr_domain, wait); if (so == NULL) return (NULL); so->so_type = head->so_type; diff --git a/sys/net/pfkeyv2.c b/sys/net/pfkeyv2.c index 6916810af94..a6a1648e991 100644 --- a/sys/net/pfkeyv2.c +++ b/sys/net/pfkeyv2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkeyv2.c,v 1.259 2023/10/11 22:13:16 tobhe Exp $ */ +/* $OpenBSD: pfkeyv2.c,v 1.260 2024/01/11 14:15:11 bluhm Exp $ */ /* * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995 @@ -225,7 +225,7 @@ const struct protosw pfkeysw[] = { const struct domain pfkeydomain = { .dom_family = PF_KEY, - .dom_name = "PF_KEY", + .dom_name = "pfkey", .dom_init = pfkey_init, .dom_protosw = pfkeysw, .dom_protoswNPROTOSW = &pfkeysw[nitems(pfkeysw)], diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c index d2e67c61aae..9748baff7e0 100644 --- a/sys/netinet/in_proto.c +++ b/sys/netinet/in_proto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in_proto.c,v 1.102 2023/07/06 04:55:05 dlg Exp $ */ +/* $OpenBSD: in_proto.c,v 1.103 2024/01/11 14:15:12 bluhm Exp $ */ /* $NetBSD: in_proto.c,v 1.14 1996/02/18 18:58:32 christos Exp $ */ /* @@ -387,7 +387,7 @@ const struct protosw inetsw[] = { const struct domain inetdomain = { .dom_family = AF_INET, - .dom_name = "internet", + .dom_name = "inet", .dom_init = in_init, .dom_protosw = inetsw, .dom_protoswNPROTOSW = &inetsw[nitems(inetsw)], diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index 4e48a1e45b5..db218af06c4 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_proto.c,v 1.112 2022/11/23 14:48:28 kn Exp $ */ +/* $OpenBSD: in6_proto.c,v 1.113 2024/01/11 14:15:12 bluhm Exp $ */ /* $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $ */ /* @@ -332,7 +332,7 @@ const struct protosw inet6sw[] = { const struct domain inet6domain = { .dom_family = AF_INET6, - .dom_name = "internet6", + .dom_name = "inet6", .dom_protosw = inet6sw, .dom_protoswNPROTOSW = &inet6sw[nitems(inet6sw)], .dom_sasize = sizeof(struct sockaddr_in6), diff --git a/sys/sys/domain.h b/sys/sys/domain.h index 478bc193d7a..87d662a6aa4 100644 --- a/sys/sys/domain.h +++ b/sys/sys/domain.h @@ -1,4 +1,4 @@ -/* $OpenBSD: domain.h,v 1.23 2022/11/23 14:50:59 kn Exp $ */ +/* $OpenBSD: domain.h,v 1.24 2024/01/11 14:15:12 bluhm Exp $ */ /* $NetBSD: domain.h,v 1.10 1996/02/09 18:25:07 christos Exp $ */ /* @@ -49,7 +49,7 @@ struct ifnet; struct domain { int dom_family; /* AF_xxx */ - char *dom_name; + const char *dom_name; void (*dom_init)(void); /* initialize domain data structures */ /* externalize access rights */ int (*dom_externalize)(struct mbuf *, socklen_t, int); diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h index 78b439b7b88..03ade942c03 100644 --- a/sys/sys/protosw.h +++ b/sys/sys/protosw.h @@ -1,4 +1,4 @@ -/* $OpenBSD: protosw.h,v 1.63 2023/12/18 13:11:20 bluhm Exp $ */ +/* $OpenBSD: protosw.h,v 1.64 2024/01/11 14:15:12 bluhm Exp $ */ /* $NetBSD: protosw.h,v 1.10 1996/04/09 20:55:32 cgd Exp $ */ /*- @@ -259,6 +259,7 @@ struct ifnet; struct sockaddr; const struct protosw *pffindproto(int, int, int); const struct protosw *pffindtype(int, int); +const struct domain *pffinddomain(int); void pfctlinput(int, struct sockaddr *); extern u_char ip_protox[]; diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h index 0290d643780..41403c00da1 100644 --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: socketvar.h,v 1.120 2023/07/04 22:28:24 mvs Exp $ */ +/* $OpenBSD: socketvar.h,v 1.121 2024/01/11 14:15:12 bluhm Exp $ */ /* $NetBSD: socketvar.h,v 1.18 1996/02/09 18:25:38 christos Exp $ */ /*- @@ -346,7 +346,7 @@ int soconnect(struct socket *, struct mbuf *); int soconnect2(struct socket *, struct socket *); int socreate(int, struct socket **, int, int); int sodisconnect(struct socket *); -struct socket *soalloc(int); +struct socket *soalloc(const struct domain *, int); void sofree(struct socket *, int); int sogetopt(struct socket *, int, int, struct mbuf *); void sohasoutofband(struct socket *);