On Thu, Apr 27, 2023 at 01:55:33PM +0300, Vitaliy Makkoveev wrote:
> 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.

This is still wrong. fill_file() is not allowed to sleep. So you can not
use a rwlock in here. fill_file is called inside a allprocess
LIST_FOREACH loop and sleeping there will blow up.
 
Maybe it is enough to grab a shared NETLOCK around the LIST_FOREACH() to
ensure that we don't sleep inside.

Please fix this properly. Right now running fstat is like playing russian
roulette.

> 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) {
> 

-- 
:wq Claudio

Reply via email to