Module Name: src Committed By: nia Date: Fri Oct 9 10:41:53 UTC 2020
Modified Files: src/sys/compat/common: tty_43.c Log Message: tty_43: Check a bitset from userspace is valid before shifting it Passing a negative value to these legacy compat ioctls results in left shift on a negative value which is undefined behaviour and results in the tty (at least, possibly other things) locking up. The argument to the ioctl should always be > 0. Return EINVAL otherwise. While here, adjustments to code style to match current guidelines. Found by UBSan. Reported-by: syzbot+39cd551a05298b222...@syzkaller.appspotmail.com To generate a diff of this commit: cvs rdiff -u -r1.37 -r1.38 src/sys/compat/common/tty_43.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/compat/common/tty_43.c diff -u src/sys/compat/common/tty_43.c:1.37 src/sys/compat/common/tty_43.c:1.38 --- src/sys/compat/common/tty_43.c:1.37 Sat Aug 8 19:04:58 2020 +++ src/sys/compat/common/tty_43.c Fri Oct 9 10:41:53 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: tty_43.c,v 1.37 2020/08/08 19:04:58 christos Exp $ */ +/* $NetBSD: tty_43.c,v 1.38 2020/10/09 10:41:53 nia Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tty_43.c,v 1.37 2020/08/08 19:04:58 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tty_43.c,v 1.38 2020/10/09 10:41:53 nia Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -220,20 +220,24 @@ compat_43_ttioctl(struct tty *tp, u_long case TIOCLBIC: case TIOCLSET: { struct termios term; - int flags; + int argbits, flags; + + argbits = *(int *)data; + if (argbits < 0) + return EINVAL; mutex_spin_enter(&tty_lock); term = tp->t_termios; flags = ttcompatgetflags(tp); switch (com) { case TIOCLSET: - tp->t_flags = (flags&0xffff) | (*(int *)data<<16); + tp->t_flags = (flags & 0xffff) | (argbits << 16); break; case TIOCLBIS: - tp->t_flags = flags | (*(int *)data<<16); + tp->t_flags = flags | (argbits << 16); break; case TIOCLBIC: - tp->t_flags = flags & ~(*(int *)data<<16); + tp->t_flags = flags & ~(argbits << 16); break; } ttcompatsetlflags(tp, &term);