git: fa8fdd80dff9 - main - sysctl KERN_PROC_KQUEUE: implement compat32
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 24 Mar 2025 02:24:50 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=fa8fdd80dff94dc848b449282080a5d85a3e6012
commit fa8fdd80dff94dc848b449282080a5d85a3e6012
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-03-13 23:05:21 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-03-24 02:24:14 +0000
sysctl KERN_PROC_KQUEUE: implement compat32
Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D49372
---
sys/compat/freebsd32/freebsd32.h | 18 +++++++++++++
sys/compat/freebsd32/freebsd32_misc.c | 50 +++++++++++++++++++++++++++++++++++
sys/compat/freebsd32/freebsd32_util.h | 5 ++++
sys/kern/kern_event.c | 38 +++++++++++++++++---------
4 files changed, 98 insertions(+), 13 deletions(-)
diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h
index 3dbf1b5a876d..2db154a8155c 100644
--- a/sys/compat/freebsd32/freebsd32.h
+++ b/sys/compat/freebsd32/freebsd32.h
@@ -446,6 +446,24 @@ struct kinfo_vm_layout32 {
uint32_t kvm_spare[12];
};
+struct kinfo_knote32 {
+ int knt_kq_fd;
+ struct kevent32 knt_event;
+ int knt_status;
+ int knt_extdata;
+ union {
+ struct {
+ int knt_vnode_type;
+ uint32_t knt_vnode_fsid[2];
+ uint32_t knt_vnode_fileid[2];
+ char knt_vnode_fullpath[PATH_MAX];
+ } knt_vnode;
+ struct {
+ uint32_t knt_pipe_ino[2];
+ } knt_pipe;
+ };
+};
+
struct kld_file_stat_1_32 {
int version; /* set to sizeof(struct kld_file_stat_1) */
char name[MAXPATHLEN];
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index d54e268f0930..e10f5782c10f 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -709,6 +709,56 @@ freebsd32_kevent_to_kevent32(const struct kevent *kevp, struct kevent32 *ks32)
}
}
+void
+freebsd32_kinfo_knote_to_32(const struct kinfo_knote *kin,
+ struct kinfo_knote32 *kin32)
+{
+ memset(kin32, 0, sizeof(*kin32));
+ CP(*kin, *kin32, knt_kq_fd);
+ freebsd32_kevent_to_kevent32(&kin->knt_event, &kin32->knt_event);
+ CP(*kin, *kin32, knt_status);
+ CP(*kin, *kin32, knt_extdata);
+ switch (kin->knt_extdata) {
+ case KNOTE_EXTDATA_NONE:
+ break;
+ case KNOTE_EXTDATA_VNODE:
+ CP(*kin, *kin32, knt_vnode.knt_vnode_type);
+#if BYTE_ORDER == LITTLE_ENDIAN
+ kin32->knt_vnode.knt_vnode_fsid[0] = kin->knt_vnode.
+ knt_vnode_fsid;
+ kin32->knt_vnode.knt_vnode_fsid[1] = kin->knt_vnode.
+ knt_vnode_fsid >> 32;
+ kin32->knt_vnode.knt_vnode_fileid[0] = kin->knt_vnode.
+ knt_vnode_fileid;
+ kin32->knt_vnode.knt_vnode_fileid[1] = kin->knt_vnode.
+ knt_vnode_fileid >> 32;
+#else
+ kin32->knt_vnode.knt_vnode_fsid[1] = kin->knt_vnode.
+ knt_vnode_fsid;
+ kin32->knt_vnode.knt_vnode_fsid[0] = kin->knt_vnode.
+ knt_vnode_fsid >> 32;
+ kin32->knt_vnode.knt_vnode_fileid[1] = kin->knt_vnode.
+ knt_vnode_fileid;
+ kin32->knt_vnode.knt_vnode_fileid[0] = kin->knt_vnode.
+ knt_vnode_fileid >> 32;
+#endif
+ memcpy(kin32->knt_vnode.knt_vnode_fullpath,
+ kin->knt_vnode.knt_vnode_fullpath, PATH_MAX);
+ break;
+ case KNOTE_EXTDATA_PIPE:
+#if BYTE_ORDER == LITTLE_ENDIAN
+ kin32->knt_pipe.knt_pipe_ino[0] = kin->knt_pipe.knt_pipe_ino;
+ kin32->knt_pipe.knt_pipe_ino[1] = kin->knt_pipe.
+ knt_pipe_ino >> 32;
+#else
+ kin32->knt_pipe.knt_pipe_ino[1] = kin->knt_pipe.knt_pipe_ino;
+ kin32->knt_pipe.knt_pipe_ino[0] = kin->knt_pipe.
+ knt_pipe_ino >> 32;
+#endif
+ break;
+ }
+}
+
/*
* Copy 'count' items into the destination list pointed to by uap->eventlist.
*/
diff --git a/sys/compat/freebsd32/freebsd32_util.h b/sys/compat/freebsd32/freebsd32_util.h
index dca61da714f0..4ac314f4391e 100644
--- a/sys/compat/freebsd32/freebsd32_util.h
+++ b/sys/compat/freebsd32/freebsd32_util.h
@@ -122,6 +122,11 @@ struct image_args;
int freebsd32_exec_copyin_args(struct image_args *args, const char *fname,
enum uio_seg segflg, uint32_t *argv, uint32_t *envv);
+struct kinfo_knote;
+struct kinfo_knote32;
+void freebsd32_kinfo_knote_to_32(const struct kinfo_knote *kin,
+ struct kinfo_knote32 *kin32);
+
extern int compat_freebsd_32bit;
#endif /* !_COMPAT_FREEBSD32_FREEBSD32_UTIL_H_ */
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index e9808e3c6e19..c7260f6bb267 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -75,6 +75,10 @@
#include <sys/ktrace.h>
#endif
#include <machine/atomic.h>
+#ifdef COMPAT_FREEBSD32
+#include <compat/freebsd32/freebsd32.h>
+#include <compat/freebsd32/freebsd32_util.h>
+#endif
#include <vm/uma.h>
@@ -2873,9 +2877,12 @@ knote_status_export(int kn_status)
static int
kern_proc_kqueue_report_one(struct sbuf *s, struct proc *p,
- int kq_fd, struct kqueue *kq, struct knote *kn)
+ int kq_fd, struct kqueue *kq, struct knote *kn, bool compat32 __unused)
{
struct kinfo_knote kin;
+#ifdef COMPAT_FREEBSD32
+ struct kinfo_knote32 kin32;
+#endif
int error;
if (kn->kn_status == KN_MARKER)
@@ -2889,7 +2896,13 @@ kern_proc_kqueue_report_one(struct sbuf *s, struct proc *p,
KQ_UNLOCK_FLUX(kq);
if (kn->kn_fop->f_userdump != NULL)
(void)kn->kn_fop->f_userdump(p, kn, &kin);
- error = sbuf_bcat(s, &kin, sizeof(kin));
+#ifdef COMPAT_FREEBSD32
+ if (compat32) {
+ freebsd32_kinfo_knote_to_32(&kin, &kin32);
+ error = sbuf_bcat(s, &kin32, sizeof(kin32));
+ } else
+#endif
+ error = sbuf_bcat(s, &kin, sizeof(kin));
KQ_LOCK(kq);
kn_leave_flux(kn);
return (error);
@@ -2897,7 +2910,7 @@ kern_proc_kqueue_report_one(struct sbuf *s, struct proc *p,
static int
kern_proc_kqueue_report(struct sbuf *s, struct proc *p, int kq_fd,
- struct kqueue *kq)
+ struct kqueue *kq, bool compat32)
{
struct knote *kn;
int error, i;
@@ -2907,7 +2920,7 @@ kern_proc_kqueue_report(struct sbuf *s, struct proc *p, int kq_fd,
for (i = 0; i < kq->kq_knlistsize; i++) {
SLIST_FOREACH(kn, &kq->kq_knlist[i], kn_link) {
error = kern_proc_kqueue_report_one(s, p, kq_fd,
- kq, kn);
+ kq, kn, compat32);
if (error != 0)
goto out;
}
@@ -2917,7 +2930,7 @@ kern_proc_kqueue_report(struct sbuf *s, struct proc *p, int kq_fd,
for (i = 0; i <= kq->kq_knhashmask; i++) {
SLIST_FOREACH(kn, &kq->kq_knhash[i], kn_link) {
error = kern_proc_kqueue_report_one(s, p, kq_fd,
- kq, kn);
+ kq, kn, compat32);
if (error != 0)
goto out;
}
@@ -2936,6 +2949,7 @@ sysctl_kern_proc_kqueue(SYSCTL_HANDLER_ARGS)
struct kqueue *kq;
struct sbuf *s, sm;
int error, error1, kq_fd, *name;
+ bool compat32;
name = (int *)arg1;
if ((u_int)arg2 != 2)
@@ -2944,13 +2958,6 @@ sysctl_kern_proc_kqueue(SYSCTL_HANDLER_ARGS)
error = pget((pid_t)name[0], PGET_HOLD | PGET_CANDEBUG, &p);
if (error != 0)
return (error);
-#ifdef COMPAT_FREEBSD32
- if (SV_CURPROC_FLAG(SV_ILP32)) {
- /* XXXKIB */
- error = EOPNOTSUPP;
- goto out1;
- }
-#endif
td = curthread;
kq_fd = name[1];
@@ -2968,9 +2975,14 @@ sysctl_kern_proc_kqueue(SYSCTL_HANDLER_ARGS)
goto out2;
}
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);
+ error = kern_proc_kqueue_report(s, p, kq_fd, kq, compat32);
error1 = sbuf_finish(s);
if (error == 0)
error = error1;