untrusted comment: verify with openbsd-75-base.pub
RWRGj1pRpprAfpd9ovli7/bzDrZB0aIvCbHHcGfRAta9tmqBVIlIq88UiniWW/iAgUVMIJ0evCjmAtWdktuDfkJFyP3lI4HyZQ0=

OpenBSD 7.5 errata 009, September 17, 2024:

In readdir name validation exclude any '/' to avoid unexpected
directory traversal on untrusted file systems.

Apply by doing:
   signify -Vep /etc/signify/openbsd-75-base.pub -x 009_readdir.patch.sig \
       -m - | (cd /usr/src && patch -p0)

And then rebuild and install a new kernel:
   KK=`sysctl -n kern.osversion | cut -d# -f1`
   cd /usr/src/sys/arch/`machine`/compile/$KK
   make obj
   make config
   make
   make install

Index: sys/isofs/cd9660/cd9660_vnops.c
===================================================================
RCS file: /cvs/src/sys/isofs/cd9660/cd9660_vnops.c,v
diff -u -p -r1.95 cd9660_vnops.c
--- sys/isofs/cd9660/cd9660_vnops.c     8 Sep 2023 20:00:28 -0000       1.95
+++ sys/isofs/cd9660/cd9660_vnops.c     14 Sep 2024 22:06:06 -0000
@@ -317,6 +317,11 @@ iso_uiodir(struct isoreaddir *idp, struc
       dp->d_name[dp->d_namlen] = 0;
       dp->d_reclen = DIRENT_SIZE(dp);

+       if (memchr(dp->d_name, '/', dp->d_namlen) != NULL) {
+               /* illegal file name */
+               return (EINVAL);
+       }
+
       if (idp->uio->uio_resid < dp->d_reclen) {
               idp->eofflag = 0;
               return (-1);
Index: sys/isofs/udf/udf_vnops.c
===================================================================
RCS file: /cvs/src/sys/isofs/udf/udf_vnops.c,v
diff -u -p -r1.70 udf_vnops.c
--- sys/isofs/udf/udf_vnops.c   13 Apr 2023 02:19:05 -0000      1.70
+++ sys/isofs/udf/udf_vnops.c   14 Sep 2024 22:06:07 -0000
@@ -548,6 +548,12 @@ udf_uiodir(struct udf_uiodir *uiodir, st
       uiodir->dirent->d_off = off;
       uiodir->dirent->d_reclen = de_size;

+       if (memchr(uiodir->dirent->d_name, '/',
+           uiodir->dirent->d_namlen) != NULL) {
+               /* illegal file name */
+               return (EINVAL);
+       }
+
       return (uiomove(uiodir->dirent, de_size, uio));
}

Index: sys/miscfs/fuse/fuse_vnops.c
===================================================================
RCS file: /cvs/src/sys/miscfs/fuse/fuse_vnops.c,v
diff -u -p -r1.67 fuse_vnops.c
--- sys/miscfs/fuse/fuse_vnops.c        8 Sep 2023 20:00:28 -0000       1.67
+++ sys/miscfs/fuse/fuse_vnops.c        14 Sep 2024 22:06:07 -0000
@@ -762,6 +762,8 @@ fusefs_readdir(void *v)
       struct fusefs_node *ip;
       struct fusefs_mnt *fmp;
       struct fusebuf *fbuf;
+       struct dirent *dp;
+       char *edp;
       struct vnode *vp;
       struct proc *p;
       struct uio *uio;
@@ -812,6 +814,35 @@ fusefs_readdir(void *v)
               /* ack end of readdir */
               if (fbuf->fb_len == 0) {
                       eofflag = 1;
+                       fb_delete(fbuf);
+                       break;
+               }
+
+               /* validate the returned dirents */
+               dp = (struct dirent *)fbuf->fb_dat;
+               edp = fbuf->fb_dat + fbuf->fb_len;
+               while ((char *)dp < edp) {
+                       if ((char *)dp + offsetof(struct dirent, d_name) >= edp
+                           || dp->d_reclen <= offsetof(struct dirent, d_name)
+                           || (char *)dp + dp->d_reclen > edp) {
+                               error = EINVAL;
+                               break;
+                       }
+                       if (dp->d_namlen + offsetof(struct dirent, d_name) >=
+                           dp->d_reclen) {
+                               error = EINVAL;
+                               break;
+                       }
+                       memset(dp->d_name + dp->d_namlen, 0, dp->d_reclen -
+                           dp->d_namlen - offsetof(struct dirent, d_name));
+
+                       if (memchr(dp->d_name, '/', dp->d_namlen) != NULL) {
+                               error = EINVAL;
+                               break;
+                       }
+                       dp = (struct dirent *)((char *)dp + dp->d_reclen);
+               }
+               if (error) {
                       fb_delete(fbuf);
                       break;
               }
Index: sys/msdosfs/msdosfs_conv.c
===================================================================
RCS file: /cvs/src/sys/msdosfs/msdosfs_conv.c,v
diff -u -p -r1.20 msdosfs_conv.c
--- sys/msdosfs/msdosfs_conv.c  4 Sep 2019 14:40:22 -0000       1.20
+++ sys/msdosfs/msdosfs_conv.c  14 Sep 2024 22:06:07 -0000
@@ -274,7 +274,7 @@ dos2unix[256] = {
       0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, /* 10-17 */
       0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, /* 18-1f */
       0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 20-27 */
-       0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 28-2f */
+       0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x3f, /* 28-2f */
       0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 30-37 */
       0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 38-3f */
       0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 40-47 */
@@ -310,7 +310,7 @@ u2l[256] = {
       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 10-17 */
       0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 18-1f */
       0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 20-27 */
-       0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 28-2f */
+       0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x3f, /* 28-2f */
       0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 30-37 */
       0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 38-3f */
       0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 40-47 */
Index: sys/nfs/nfs_vnops.c
===================================================================
RCS file: /cvs/src/sys/nfs/nfs_vnops.c,v
diff -u -p -r1.193 nfs_vnops.c
--- sys/nfs/nfs_vnops.c 26 Apr 2023 10:00:37 -0000      1.193
+++ sys/nfs/nfs_vnops.c 14 Sep 2024 22:06:06 -0000
@@ -2116,6 +2116,11 @@ nfs_readdir(void *v)
                       dp->d_reclen -= NFS_DIRENT_OVERHEAD;
                       dp->d_off = fxdr_hyper(&ndp->cookie[0]);

+                       if (memchr(dp->d_name, '/', dp->d_namlen) != NULL) {
+                               error = EBADRPC;
+                               break;
+                       }
+
                       if (uio->uio_resid < dp->d_reclen) {
                               eof = 0;
                               done = 1;
Index: sys/ntfs/ntfs_vnops.c
===================================================================
RCS file: /cvs/src/sys/ntfs/ntfs_vnops.c,v
diff -u -p -r1.47 ntfs_vnops.c
--- sys/ntfs/ntfs_vnops.c       15 Oct 2021 06:30:06 -0000      1.47
+++ sys/ntfs/ntfs_vnops.c       14 Sep 2024 22:06:07 -0000
@@ -489,6 +489,10 @@ ntfs_readdir(void *v)
                           "flag: %u, ",
                           num, cde.d_name, iep->ie_fnametype, iep->ie_flag);
                       cde.d_namlen = fname - (char *) cde.d_name;
+                       if (memchr(cde.d_name, '/', cde.d_namlen) != NULL) {
+                               error = EINVAL;
+                               goto out;
+                       }
                       cde.d_fileno = iep->ie_number;
                       cde.d_type = (iep->ie_fflag & NTFS_FFLAG_DIR) ? DT_DIR : DT_REG;
                       cde.d_reclen = sizeof(struct dirent);
Index: sys/tmpfs/tmpfs_subr.c
===================================================================
RCS file: /cvs/src/sys/tmpfs/tmpfs_subr.c,v
diff -u -p -r1.26 tmpfs_subr.c
--- sys/tmpfs/tmpfs_subr.c      15 Nov 2022 17:16:44 -0000      1.26
+++ sys/tmpfs/tmpfs_subr.c      14 Sep 2024 22:06:07 -0000
@@ -820,6 +820,11 @@ tmpfs_dir_getdents(tmpfs_node_t *node, s
               dent.d_name[de->td_namelen] = '\0';
               dent.d_reclen = DIRENT_SIZE(&dent);

+               if (memchr(dent.d_name, '/', dent.d_namlen) != NULL) {
+                       error = EINVAL;
+                       break;
+               }
+
               next_de = TAILQ_NEXT(de, td_entries);
               if (next_de == NULL)
                       dent.d_off = TMPFS_DIRSEQ_EOF;
Index: sys/ufs/ext2fs/ext2fs_lookup.c
===================================================================
RCS file: /cvs/src/sys/ufs/ext2fs/ext2fs_lookup.c,v
diff -u -p -r1.46 ext2fs_lookup.c
--- sys/ufs/ext2fs/ext2fs_lookup.c      11 Jan 2022 03:13:59 -0000      1.46
+++ sys/ufs/ext2fs/ext2fs_lookup.c      14 Sep 2024 22:06:07 -0000
@@ -173,7 +173,11 @@ ext2fs_readdir(void *v)
                               break;
                       }
                       ext2fs_dirconv2ffs(dp, &dstd);
-                       if(dstd.d_reclen > uio->uio_resid) {
+                       if (memchr(dstd.d_name, '/', dstd.d_namlen) != NULL) {
+                               error = EINVAL;
+                               break;
+                       }
+                       if (dstd.d_reclen > uio->uio_resid) {
                               break;
                       }
                       dstd.d_off = off + e2d_reclen;
Index: sys/ufs/ufs/ufs_vnops.c
===================================================================
RCS file: /cvs/src/sys/ufs/ufs/ufs_vnops.c,v
diff -u -p -r1.160 ufs_vnops.c
--- sys/ufs/ufs/ufs_vnops.c     3 Feb 2024 18:51:59 -0000       1.160
+++ sys/ufs/ufs/ufs_vnops.c     14 Sep 2024 22:06:07 -0000
@@ -1410,6 +1410,11 @@ ufs_readdir(void *v)
               memset(u.dn.d_name + u.dn.d_namlen, 0, u.dn.d_reclen
                   - u.dn.d_namlen - offsetof(struct dirent, d_name));

+               if (memchr(u.dn.d_name, '/', u.dn.d_namlen) != NULL) {
+                       error = EINVAL;
+                       break;
+               }
+
               error = uiomove(&u.dn, u.dn.d_reclen, uio);
               dp = (struct direct *)((char *)dp + dp->d_reclen);
       }