View Issue Details

IDProjectCategoryView StatusLast Update
0006104CentOS-6kernelpublic2013-03-13 20:58
ReporterZykov Ilya 
PrioritynormalSeveritycrashReproducibilityalways
Status resolvedResolutionfixed 
PlatformLinuxOSCentosOS Version6
Product Version6.3 
Target VersionFixed in Version6.4 
Summary0006104: tty: tty_flip_buffer NULL pointer dereference
DescriptionThe root of problem it use carelessly buffer flushing, then another thread can write to it.
This patch resolve this problem.
-------------------------------------------------------------------------
diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c
index ded3a77..53fdcf2 100644
--- a/drivers/char/tty_buffer.c
+++ b/drivers/char/tty_buffer.c
@@ -114,11 +114,14 @@ static void __tty_buffer_flush(struct tty_struct *tty)
 {
     struct tty_buffer *thead;
 
- while ((thead = tty->buf.head) != NULL) {
- tty->buf.head = thead->next;
- tty_buffer_free(tty, thead);
+ if (tty->buf.head == NULL)
+ return;
+ while ((thead = tty->buf.head->next) != NULL) {
+ tty_buffer_free(tty, tty->buf.head);
+ tty->buf.head = thead;
     }
- tty->buf.tail = NULL;
+ WARN_ON(tty->buf.head != tty->buf.tail);
+ tty->buf.head->read = tty->buf.head->commit;
 }
 
 /**
Steps To ReproduceMaybe need SMP.
---------------------------------------------
!!!! Not execute on important systems !!!!
---------------------------------------------
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <stdlib.h>

#define BUF_SIZE 512
#define ERROR_EXIT_CODE 1
#define parent child_id

static int
mfd=-1, sfd=-1, parent=1;

static char
pty_name[24];

static void
pty_exit(int ret, char * exit_message){
    if (sfd >= 0) close(sfd);
    if (mfd >= 0) close(mfd);
    printf("%s %s exit. \n %s",ret?"Error":"Normal", parent?"parent":"child",
            exit_message?exit_message:"");
    exit(ret);
}

static void
pty_init(void){
    int ptn;
    if( (mfd=open("/dev/ptmx", O_RDWR )) < 0 )
        pty_exit(ERROR_EXIT_CODE,"Couldn't open /dev/ptmx. \n");
    if (ioctl(mfd, TIOCGPTN, &ptn) < 0 )
        pty_exit(ERROR_EXIT_CODE,"Couldn't get pty number. \n");
    snprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
    printf("Slave pty name = %s.\n",pty_name);
    ptn=0;
    if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0 )
        pty_exit(ERROR_EXIT_CODE,"Couldn't unlock pty slave. \n");
    if ( (sfd=open(pty_name, O_RDWR )) < 0 )
        pty_exit(ERROR_EXIT_CODE, "Couldn't open pty slave. \n");
}

int main(int argc,char *argv[]) {
    pty_init();
    char buf[]={ [0 ... BUF_SIZE-1]='1' };

    child_id=fork();
do {
    if(parent) {
        if ( write(mfd, buf, BUF_SIZE) < 0 )
            pty_exit(ERROR_EXIT_CODE, "Parent's write() error.\n");
    } else { //Child
        if ( tcflush(sfd, TCIFLUSH) < 0 )
            pty_exit(ERROR_EXIT_CODE, "Child's tcflush() error.\n");
    }
} while(1);
    return 0; //Never
}

Additional InformationBUG: unable to handle kernel NULL pointer dereference at 0000000000000018
IP: [<ffffffff8131e87e>] tty_insert_flip_string+0x6e/0xd0
PGD 11792b067 PUD 117117067 PMD 0
Oops: 0000 [#1] SMP
last sysfs file: /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
CPU 1

..... ......

Process tty_flip_buffer (pid: 3139, threadinfo ffff880112778000, task ffff880117b4c040)
Stack:
 ffff880117a7fc00 0000000000000200 ffff880117a7fc00 ffff880129f15800
<d> ffff88011a41d000 0000000000000200 ffff880117a7fc00 ffff880129f15cd0
<d> ffff880112779de8 ffffffff8131f539 ffff88011273c800 ffff880129f15800
Call Trace:
 [<ffffffff8131f539>] pty_write+0x39/0x80
 [<ffffffff8131980c>] n_tty_write+0x33c/0x460
 [<ffffffff810602c0>] ? default_wake_function+0x0/0x20
 [<ffffffff81316431>] tty_write+0x1b1/0x2a0
 [<ffffffff813194d0>] ? n_tty_write+0x0/0x460
 [<ffffffff8117b698>] vfs_write+0xb8/0x1a0
 [<ffffffff8117c0b1>] sys_write+0x51/0x90
 [<ffffffff8100b0f2>] system_call_fastpath+0x16/0x1b
Code: 00 07 00 00 48 0f 47 f0 48 63 f6 e8 6d fc ff ff 85 c0 41 89 c4 49 8b 9e 88 01 00 00 74 3c 48 98 48 8b 75 c0 45 01 e5 48 89 45 c8 <48> 63 7b 18 48 89 c2 48 03 7b 08 e8 12 fd f5 ff 48 63 7b 18 48
RIP [<ffffffff8131e87e>] tty_insert_flip_string+0x6e/0xd0
 RSP <ffff880112779d78>
CR2: 0000000000000018

crash> bt
PID: 3139 TASK: ffff880117b4c040 CPU: 1 COMMAND: "tty_flip_buffer"
 #0 [ffff880112779940] machine_kexec at ffffffff8103284b
 #1 [ffff8801127799a0] crash_kexec at ffffffff810ba982
 #2 [ffff880112779a70] oops_end at ffffffff81501b00
 #3 [ffff880112779aa0] no_context at ffffffff81043bfb
 #4 [ffff880112779af0] __bad_area_nosemaphore at ffffffff81043e85
 #5 [ffff880112779b40] bad_area at ffffffff81043fae
 #6 [ffff880112779b70] __do_page_fault at ffffffff81044760
 #7 [ffff880112779c90] do_page_fault at ffffffff81503ade
 #8 [ffff880112779cc0] page_fault at ffffffff81500e95
    [exception RIP: tty_insert_flip_string+110]
    RIP: ffffffff8131e87e RSP: ffff880112779d78 RFLAGS: 00010206
    RAX: 0000000000000200 RBX: 0000000000000000 RCX: 0000000000000200
    RDX: ffff88011a41d178 RSI: ffff880117a7fc00 RDI: 0000000000000246
    RBP: ffff880112779db8 R8: 0000000000000046 R9: 0000000000000000
    R10: 000000000000000c R11: 0000000000000000 R12: 0000000000000200
    R13: 0000000000000200 R14: ffff88011a41d000 R15: 0000000000000200
    ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
 #9 [ffff880112779dc0] pty_write at ffffffff8131f539
#10 [ffff880112779df0] n_tty_write at ffffffff8131980c
#11 [ffff880112779e80] tty_write at ffffffff81316431
#12 [ffff880112779ef0] vfs_write at ffffffff8117b698
#13 [ffff880112779f30] sys_write at ffffffff8117c0b1
#14 [ffff880112779f80] system_call_fastpath at ffffffff8100b0f2
    RIP: 00000035266dae60 RSP: 00007fffcfda2630 RFLAGS: 00010206
    RAX: 0000000000000001 RBX: ffffffff8100b0f2 RCX: 00000000004003f4
    RDX: 0000000000000200 RSI: 00007fffcfda2830 RDI: 0000000000000003
    RBP: 00007fffcfda2a40 R8: 00007f82f57fa700 R9: 0000000000000000
    R10: 00007fffcfda25a0 R11: 0000000000000246 R12: 00007fffcfda2b20
    R13: 0000000000400620 R14: 0000000000400b80 R15: 0000000000400620
    ORIG_RAX: 0000000000000001 CS: 0033 SS: 002b

Tags6.3, centos, kernel, kernel panic

Activities

Zykov Ilya

Zykov Ilya

2012-11-28 18:14

reporter  

tty_flip_buffer_bug.c (1,398 bytes)
toracat

toracat

2012-11-28 22:10

manager   ~0016091

It is possible to apply kernel patches to the centosplus kernel (but not the distro kernel). However, I see that you marked the patch "CANCEL" on lkml:

https://lkml.org/lkml/2012/11/27/599

Is this patch still regarded 'safe' ?
Zykov Ilya

Zykov Ilya

2012-11-28 22:35

reporter   ~0016092

It patch more right then:
https://lkml.org/lkml/2012/3/14/552
therefore, I market other patch CANCEL.
Maybe I did anything incorrectly if you don't undestand me?
I am newbie on lkml.org.
toracat

toracat

2012-11-28 22:51

manager   ~0016093

Sorry, I misinterpreted your post. Let's wait and see if your patch gets accepted upstream (kernel.org).
Zykov Ilya

Zykov Ilya

2013-03-04 18:56

reporter   ~0016594

You can include this patch, in centosplus, for improve stability,
because it would be merged in upstream 3.9-rc1.
Thank you.
Ilya.


https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/tty/tty_buffer.c?id=64325a3be08d364a62ee8f84b2cf86934bc2544a
toracat

toracat

2013-03-04 19:06

manager   ~0016595

Thank you for the update. I will attempt to include the patch in the next release of the cplus kernel.
toracat

toracat

2013-03-12 20:10

manager   ~0016682

kernel-2.6.32-358.2.1.el6 was released upstream. The patch applied to the cplus kernel.

Issue History

Date Modified Username Field Change
2012-11-28 18:14 Zykov Ilya New Issue
2012-11-28 18:14 Zykov Ilya File Added: tty_flip_buffer_bug.c
2012-11-28 18:19 Zykov Ilya Tag Attached: 6.3
2012-11-28 18:19 Zykov Ilya Tag Attached: centos
2012-11-28 18:19 Zykov Ilya Tag Attached: kernel
2012-11-28 18:19 Zykov Ilya Tag Attached: kernel panic
2012-11-28 22:10 toracat Note Added: 0016091
2012-11-28 22:11 toracat Status new => feedback
2012-11-28 22:35 Zykov Ilya Note Added: 0016092
2012-11-28 22:35 Zykov Ilya Status feedback => assigned
2012-11-28 22:51 toracat Note Added: 0016093
2013-03-04 18:56 Zykov Ilya Note Added: 0016594
2013-03-04 19:06 toracat Note Added: 0016595
2013-03-12 20:10 toracat Note Added: 0016682
2013-03-13 20:58 toracat Status assigned => resolved
2013-03-13 20:58 toracat Resolution open => fixed
2013-03-13 20:58 toracat Fixed in Version => 6.4