Message ID | 20220225033456.63578-1-xiaoshoukui@ruijie.com.cn |
---|---|
State | Changes Requested |
Headers | show |
Series | [1/1] Add pty06 test for use-after-free in con_shutdown() | expand |
Hi! First of all the coding style is wrong, please run 'make check-pty06' and fix all the warnings and errors. > diff --git a/testcases/kernel/pty/pty06.c b/testcases/kernel/pty/pty06.c > new file mode 100644 > index 000000000..9fcd341e6 > --- /dev/null > +++ b/testcases/kernel/pty/pty06.c > @@ -0,0 +1,78 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * Copyright (c) 2022 xiaoshoukui <xiaoshoukui@ruijie.com.cn> > + * > + * Test based on Syzkaller reproducer: > + * https://syzkaller.appspot.com/bug?extid=522643ab5729b0421998 > + * > + * The VT_DISALLOCATE ioctl can free a virtual console while tty_release() > + * is still running, causing a use-after-free in con_shutdown(). This > + * occurs because VT_DISALLOCATE only considers a virtual console to be > + * in-use if it has a tty_struct with count > 0. But actually when > + * count == 0, the tty is still in the process of being closed. > + * > + * Fixed by commit ca4463bf8438: > + * "vt: vt_ioctl: fix VT_DISALLOCATE freeing in-use virtual console" > + * > + */ Plese convert this into a docparse comment. We do have a system that collects documentation from tests and renders a nice documentation: http://linux-test-project.github.io/metadata/metadata.asciidoctor.html The docparse comment starts with: /*\ * [Description] * And is assciidoc formatted. > +#define _GNU_SOURCE > + > +#include <stdlib.h> > +#include <stdio.h> > +#include <errno.h> > +#include <termios.h> > +#include <linux/vt.h> > +#include "lapi/ioctl.h" > + > +#include "tst_test.h" > +#include "tst_safe_stdio.h" > +#include "tst_fuzzy_sync.h" > + > +#define BUF_SIZE 256 > +static char tty_path_a[BUF_SIZE]; > +static char tty_path_b[BUF_SIZE]; > +static int tst_tty_port = 8; > +static struct tst_fzsync_pair fzp; > + > +static void *open_close(void *unused) { > + sprintf(tty_path_b, "/dev/tty%d", tst_tty_port); > + while (tst_fzsync_run_b(&fzp)) { > + tst_fzsync_start_race_b(&fzp); > + int fd = SAFE_OPEN(tty_path_b, O_RDWR); > + SAFE_CLOSE(fd); > + tst_fzsync_end_race_b(&fzp); > + } > + return unused; > +} > + > +static void do_test(void) { > + sprintf(tty_path_a, "/dev/tty%d", tst_tty_port + 1); > + int fd = SAFE_OPEN(tty_path_a, O_RDWR); > + tst_fzsync_pair_reset(&fzp, open_close); > + while (tst_fzsync_run_a(&fzp)) { > + tst_fzsync_start_race_a(&fzp); > + ioctl(fd, VT_DISALLOCATE, tst_tty_port); > + tst_fzsync_end_race_a(&fzp); > + } > + tst_res(TPASS, "Did not crash with VT_DISALLOCATE"); > +} > + > +static void setup(void) { > + tst_fzsync_pair_init(&fzp); > +} > + > +static void cleanup(void) { > + tst_fzsync_pair_cleanup(&fzp); > +} > + > +static struct tst_test test = { > + .test_all = do_test, > + .setup = setup, > + .cleanup = cleanup, > + .needs_root = 1, > + .tags = (const struct tst_tag[]) { > + {"linux-git", "ca4463bf8438"}, > + {} > + } > +}; > -- > 2.20.1 > > > -- > Mailing list info: https://lists.linux.it/listinfo/ltp
diff --git a/testcases/kernel/pty/Makefile b/testcases/kernel/pty/Makefile index d4c6c87f0..51b7356c2 100644 --- a/testcases/kernel/pty/Makefile +++ b/testcases/kernel/pty/Makefile @@ -6,7 +6,7 @@ top_srcdir ?= ../../.. include $(top_srcdir)/include/mk/testcases.mk -pty03 pty05: CFLAGS += -pthread -pty03 pty05: LDLIBS += -lrt +pty03 pty05 pty06: CFLAGS += -pthread +pty03 pty05 pty06: LDLIBS += -lrt include $(top_srcdir)/include/mk/generic_leaf_target.mk diff --git a/testcases/kernel/pty/pty06.c b/testcases/kernel/pty/pty06.c new file mode 100644 index 000000000..9fcd341e6 --- /dev/null +++ b/testcases/kernel/pty/pty06.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 xiaoshoukui <xiaoshoukui@ruijie.com.cn> + * + * Test based on Syzkaller reproducer: + * https://syzkaller.appspot.com/bug?extid=522643ab5729b0421998 + * + * The VT_DISALLOCATE ioctl can free a virtual console while tty_release() + * is still running, causing a use-after-free in con_shutdown(). This + * occurs because VT_DISALLOCATE only considers a virtual console to be + * in-use if it has a tty_struct with count > 0. But actually when + * count == 0, the tty is still in the process of being closed. + * + * Fixed by commit ca4463bf8438: + * "vt: vt_ioctl: fix VT_DISALLOCATE freeing in-use virtual console" + * + */ + +#define _GNU_SOURCE + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <termios.h> +#include <linux/vt.h> +#include "lapi/ioctl.h" + +#include "tst_test.h" +#include "tst_safe_stdio.h" +#include "tst_fuzzy_sync.h" + +#define BUF_SIZE 256 +static char tty_path_a[BUF_SIZE]; +static char tty_path_b[BUF_SIZE]; +static int tst_tty_port = 8; +static struct tst_fzsync_pair fzp; + +static void *open_close(void *unused) { + sprintf(tty_path_b, "/dev/tty%d", tst_tty_port); + while (tst_fzsync_run_b(&fzp)) { + tst_fzsync_start_race_b(&fzp); + int fd = SAFE_OPEN(tty_path_b, O_RDWR); + SAFE_CLOSE(fd); + tst_fzsync_end_race_b(&fzp); + } + return unused; +} + +static void do_test(void) { + sprintf(tty_path_a, "/dev/tty%d", tst_tty_port + 1); + int fd = SAFE_OPEN(tty_path_a, O_RDWR); + tst_fzsync_pair_reset(&fzp, open_close); + while (tst_fzsync_run_a(&fzp)) { + tst_fzsync_start_race_a(&fzp); + ioctl(fd, VT_DISALLOCATE, tst_tty_port); + tst_fzsync_end_race_a(&fzp); + } + tst_res(TPASS, "Did not crash with VT_DISALLOCATE"); +} + +static void setup(void) { + tst_fzsync_pair_init(&fzp); +} + +static void cleanup(void) { + tst_fzsync_pair_cleanup(&fzp); +} + +static struct tst_test test = { + .test_all = do_test, + .setup = setup, + .cleanup = cleanup, + .needs_root = 1, + .tags = (const struct tst_tag[]) { + {"linux-git", "ca4463bf8438"}, + {} + } +};
Signed-off-by: xiaoshoukui <xiaoshoukui@ruijie.com.cn> --- testcases/kernel/pty/Makefile | 4 +- testcases/kernel/pty/pty06.c | 78 +++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 testcases/kernel/pty/pty06.c