Overflow in xl2tpd

September 11, 2007 – 6:17 pm

今天 VPN 突然连不上了,到终端启动 xl2tpd ,发现启动报错,说是无法读取配置文件:

$ sudo xl2tpd -D
xl2tpd[4344]: parse_config: line 13: data 'l parameters:' occurs with no context
xl2tpd[4344]: init: Unable to load config file

真是奇怪,我打开 /etc/xl2tpd/xl2tpd.conf 看了一下,十三行好好的嘛,只是注释而已。我甚至怀疑它打开的是什么文件,于是用 strace 跟踪了一下:

$ sudo strace xl2tpd -D
execve("/usr/sbin/xl2tpd", ["xl2tpd", "-D"], [/* 14 vars */]) = 0
brk(0)                                  = 0x8063000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fd9000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=76622, ...}) = 0
mmap2(NULL, 76622, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fc6000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/i686/cmov/libc.so.6", O_RDONLY) = 3
read(3, "\\177ELF\\1\\1\\1\\0\\0\\0\\0\\0\\0\\0\\0\\0\\3\\0\\3\\0\\1\\0\\0\\0\\260a\\1"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0644, st_size=1336100, ...}) = 0
mmap2(NULL, 1340944, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e7e000
mmap2(0xb7fc0000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x142) = 0xb7fc0000
mmap2(0xb7fc3000, 9744, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7fc3000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7e7d000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7e7d6b0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xb7fc0000, 4096, PROT_READ)   = 0
munmap(0xb7fc6000, 76622)               = 0
time(NULL)                              = 1189503420
brk(0)                                  = 0x8063000
brk(0x8084000)                          = 0x8084000
open("/etc/xl2tpd/xl2tpd.conf", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=5749, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fd8000
read(3, ";\n; Sample l2tpd configuration f"..., 1024) = 1024
getpid()                                = 4346
write(2, "xl2tpd[4346]: parse_config: line"..., 81xl2tpd[4346]: parse_config: line 13: data 'l parameters:' occurs with no context
) = 81
close(3)                                = 0
munmap(0xb7fd8000, 4096)                = 0
write(2, "xl2tpd[4346]: init: Unable to lo"..., 47xl2tpd[4346]: init: Unable to load config file
) = 47
exit_group(1)                           = ?
Process 4346 detached

可以看到它打开的确实是

/etc/xl2tpd/xl2tpd.conf

。半天都摸不着头脑,只好去 Google ,搜索出来唯一有点用的只有 l2tpd 的源码的 lxr 了。l2tpd 和 xl2tpd 应该大体上差不多吧。我找到那一行打印出错的地方,大致看了一下 parse_config 这个函数,发现它是自己手工在解析 ini 的配置文件格式,并且用 fgets 来读取一行的内容,而它的一行是多少呢?

992
char buf[STRLEN];

STRLEN 的定义是 80 。再看打印出错代码的那句代码:

1150
1151
1152
                log (LOG_WARN,
                      "parse_config: line %d: data '%s' occurs with no context\n",
                      linenum, s);

s 是读取的那一行去掉注释以后的内容。于是我再去搜索配置文件,发现确实有 “l parameters”,其实是一行注释(当然,并不是它说的那样在第 13 行):

11
; [global]                             ; Global parameters:

这下一切都明了了,它用 fgets 来读取一行,读到 “Global” 的 “l” 那里为止,下一次读的时候又读了一个尾巴,当然那不是什么有效的配置,所以就报错了,还因此把报错的行号都搞错了,因为它所谓的“一行”根本不是一行嘛。把那些超过 80 个字符的行编辑一下就可以了。

但是我比较奇怪的是这配置文件前面的一大段注释是它安装好就有的,而且我以前用都没有问题,怎么今天有好多行都就超过 80 个字符了。我今天只是用 Emacs 打开把一个 “a” 改成 “c” 了而已。要说也只有是 Emacs 自动把 tab 变成 8 个空格了,但是也没道理啊,我以前一直都是用 Emacs 改这个文件的,太奇怪了。

不过,l2tpd 那个代码也确实太不健壮了。。。 -.-bb

  1. One Response to “Overflow in xl2tpd”

  2. 看到这里,我赶忙去删掉了xl2tpd配置文件里面的注释 =.=b

    By quark on May 28, 2008

Post a Comment