The branch main has been updated by kib:

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

commit ab9b296498fe5809bbb905c320d46e700c267164
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2025-03-15 01:50:46 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2025-03-24 02:24:14 +0000

    sysctl KERN_PROC_KQUEUE: treat omitted kqfd as request to dump all kqueues
    
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D49372
---
 sys/kern/kern_event.c | 64 +++++++++++++++++++++++++++++++--------------------
 1 file changed, 39 insertions(+), 25 deletions(-)

diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 8188323bdbc9..e891cb7c094a 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -2964,8 +2964,6 @@ kern_proc_kqueues_out1(struct thread *td, struct proc *p, 
struct sbuf *s,
 {
        struct kern_proc_kqueues_out1_cb_args a;
 
-       MPASS(p == curproc);
-
        a.s = s;
        a.compat32 = compat32;
        return (fget_remote_foreach(td, p, kern_proc_kqueues_out1_cb, &a));
@@ -2987,19 +2985,39 @@ kern_proc_kqueues_out(struct proc *p, struct sbuf *sb, 
size_t maxlen,
        return (error);
 }
 
+static int
+sysctl_kern_proc_kqueue_one(struct thread *td, struct sbuf *s, struct proc *p,
+    int kq_fd, bool compat32)
+{
+       struct file *fp;
+       struct kqueue *kq;
+       int error;
+
+       error = fget_remote(td, p, kq_fd, &fp);
+       if (error == 0) {
+               if (fp->f_type != DTYPE_KQUEUE) {
+                       error = EINVAL;
+               } else {
+                       kq = fp->f_data;
+                       error = kern_proc_kqueue_report(s, p, kq_fd, kq,
+                           compat32);
+               }
+               fdrop(fp, td);
+       }
+       return (error);
+}
+
 static int
 sysctl_kern_proc_kqueue(SYSCTL_HANDLER_ARGS)
 {
        struct thread *td;
        struct proc *p;
-       struct file *fp;
-       struct kqueue *kq;
        struct sbuf *s, sm;
-       int error, error1, kq_fd, *name;
+       int error, error1, *name;
        bool compat32;
 
        name = (int *)arg1;
-       if ((u_int)arg2 != 2)
+       if ((u_int)arg2 > 2 || (u_int)arg2 == 0)
                return (EINVAL);
 
        error = pget((pid_t)name[0], PGET_HOLD | PGET_CANDEBUG, &p);
@@ -3007,36 +3025,32 @@ sysctl_kern_proc_kqueue(SYSCTL_HANDLER_ARGS)
                return (error);
 
        td = curthread;
-       kq_fd = name[1];
-       error = fget_remote(td, p, kq_fd, &fp);
-       if (error != 0)
-               goto out1;
-       if (fp->f_type != DTYPE_KQUEUE) {
-               error = EINVAL;
-               goto out2;
-       }
+#ifdef FREEBSD_COMPAT32
+       compat32 = SV_CURPROC_FLAG(SV_ILP32);
+#else
+       compat32 = false;
+#endif
 
        s = sbuf_new_for_sysctl(&sm, NULL, 0, req);
        if (s == NULL) {
                error = ENOMEM;
-               goto out2;
+               goto out;
        }
        sbuf_clear_flags(s, SBUF_INCLUDENUL);
-#ifdef FREEBSD_COMPAT32
-       compat32 = SV_CURPROC_FLAG(SV_ILP32);
-#else
-       compat32 = false;
-#endif
 
-       kq = fp->f_data;
-       error = kern_proc_kqueue_report(s, p, kq_fd, kq, compat32);
+       if ((u_int)arg2 == 1) {
+               error = kern_proc_kqueues_out1(td, p, s, compat32);
+       } else {
+               error = sysctl_kern_proc_kqueue_one(td, s, p,
+                   name[1] /* kq_fd */, compat32);
+       }
+
        error1 = sbuf_finish(s);
        if (error == 0)
                error = error1;
        sbuf_delete(s);
-out2:
-       fdrop(fp, td);
-out1:
+
+out:
        PRELE(p);
        return (error);
 }

Reply via email to