Now only direct netlock used for inet sockets protection. The unlocked
access to all other sockets is safe, but we could lost consistency for a
little. Since the solock() used for sockets protection, make locking
path common and use it. Make it shared because this is read-only access
to sockets data. For same reason use shared netlock while performing
inpcb tables foreach walkthrough.

Index: sys/kern/kern_sysctl.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.411
diff -u -p -r1.411 kern_sysctl.c
--- sys/kern/kern_sysctl.c      22 Jan 2023 12:05:44 -0000      1.411
+++ sys/kern/kern_sysctl.c      27 Apr 2023 10:18:01 -0000
@@ -1173,14 +1173,11 @@ fill_file(struct kinfo_file *kf, struct 
 
                if (so == NULL) {
                        so = (struct socket *)fp->f_data;
+                       solock_shared(so);
+                       locked = 1;
+               } else {
                        /* if so is passed as parameter it is already locked */
-                       switch (so->so_proto->pr_domain->dom_family) {
-                       case AF_INET:
-                       case AF_INET6:
-                               NET_LOCK();
-                               locked = 1;
-                               break;
-                       }
+                       soassertlocked(so);
                }
 
                kf->so_type = so->so_type;
@@ -1203,14 +1200,13 @@ fill_file(struct kinfo_file *kf, struct 
                        kf->so_splicelen = -1;
                if (so->so_pcb == NULL) {
                        if (locked)
-                               NET_UNLOCK();
+                               sounlock_shared(so);
                        break;
                }
                switch (kf->so_family) {
                case AF_INET: {
                        struct inpcb *inpcb = so->so_pcb;
 
-                       NET_ASSERT_LOCKED();
                        if (show_pointers)
                                kf->inp_ppcb = PTRTOINT64(inpcb->inp_ppcb);
                        kf->inp_lport = inpcb->inp_lport;
@@ -1232,7 +1228,6 @@ fill_file(struct kinfo_file *kf, struct 
                case AF_INET6: {
                        struct inpcb *inpcb = so->so_pcb;
 
-                       NET_ASSERT_LOCKED();
                        if (show_pointers)
                                kf->inp_ppcb = PTRTOINT64(inpcb->inp_ppcb);
                        kf->inp_lport = inpcb->inp_lport;
@@ -1279,7 +1274,7 @@ fill_file(struct kinfo_file *kf, struct 
                    }
                }
                if (locked)
-                       NET_UNLOCK();
+                       sounlock_shared(so);
                break;
            }
 
@@ -1375,7 +1370,7 @@ sysctl_file(int *name, u_int namelen, ch
                if (arg == DTYPE_SOCKET) {
                        struct inpcb *inp;
 
-                       NET_LOCK();
+                       NET_LOCK_SHARED();
                        mtx_enter(&tcbtable.inpt_mtx);
                        TAILQ_FOREACH(inp, &tcbtable.inpt_queue, inp_queue)
                                FILLSO(inp->inp_socket);
@@ -1395,7 +1390,7 @@ sysctl_file(int *name, u_int namelen, ch
                                FILLSO(inp->inp_socket);
                        mtx_leave(&rawin6pcbtable.inpt_mtx);
 #endif
-                       NET_UNLOCK();
+                       NET_UNLOCK_SHARED();
                }
                fp = NULL;
                while ((fp = fd_iterfile(fp, p)) != NULL) {

Reply via email to