DF-2768 / fix.diff
DF-2768: enforce the MAXPTYS pty limit at the correct bound devfs_clone_bitmap_get() refuses only units strictly greater than its limit argument (sys/vfs/devfs/devfs_helper.c:224-227), so passing MAXPTYS (== the number of entries in ptis[]) allows unit == MAXPTYS through. ptyclone() then executes if ((pti = ptis[unit]) == NULL) ... /* tty_pty.c:186 OOB read */ ptis[unit] = pti; /* tty_pty.c:190 OOB write */ one element past the end of the 1000-entry ptis array (tty_pty.c:1292). The OOB read consumes uninitialized heap slack as a pt_ioctl pointer (currently NULL only because kmalloc's M_ZERO bzero happens to cover the full 8192-byte zone chunk for an 8000-byte request), and the OOB write stores a kernel heap pointer past the requested allocation size. It also creates a functional 1001st pty, bypassing the MAXPTYS guard. Fix: pass MAXPTYS-1 (the highest valid unit number). --- sys/kern/tty_pty.c.orig +++ sys/kern/tty_pty.c @@ -173,7 +173,7 @@ * If this limit is reached, we don't clone and return an error * to devfs. */ - unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(pty), MAXPTYS); + unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(pty), MAXPTYS - 1); if (unit < 0) { ap->a_dev = NULL; |