diff --git a/sys/vfs/procfs/procfs_map.c b/sys/vfs/procfs/procfs_map.c --- a/sys/vfs/procfs/procfs_map.c +++ b/sys/vfs/procfs/procfs_map.c @@ -58,6 +58,7 @@ struct uio *uio) { struct proc *p = lp->lwp_proc; +#define PROCFS_MAP_MAXBUF (1U << 20) /* 1 MiB, ample for one read */ ssize_t buflen = uio->uio_offset + uio->uio_resid; struct vnode *vp; char *fullpath, *freepath; @@ -74,6 +75,14 @@ if (uio->uio_offset < 0 || uio->uio_resid < 0 || buflen >= INT_MAX) return EINVAL; + /* + * The output is positionally truncated by uiomove_frombuf below, so + * the buffer only needs to hold one read's worth of formatted output. + * Cap it so a hostile read() length cannot force a multi-GiB up-front + * kmalloc in sbuf_new (DF-0924). 1 MiB is ample for any single read. + */ + if (buflen > PROCFS_MAP_MAXBUF) + buflen = PROCFS_MAP_MAXBUF; sb = sbuf_new (sb, NULL, buflen+1, 0); if (sb == NULL) return EIO;