reassign 602566 libkpathsea-dev 2009-7 tags 602566 +patch stop Le vendredi 05 novembre 2010 à 23:51 +0100, Robert Millan a écrit : > Package: dvi2ps > Version: 4.1j-3 > Severity: grave > > Segfaults on mipsel when processing a trivial (attached) test.dvi. > > $ dvi2ps test.dvi > @(#)dvi2ps (j-version) 4.1j > > Prescanning Segmentation fault >
I reproduced this bug in a clean install of debian/testing with a mipsel-malta kernel running in Qemu under AMD64. The bug seems to come from libkpathsea5 and not from dvi2ps. It exists on all platforms (at least also on AMD64) but does not trigger a segfault. It comes from the kpse_set_suffixes function in the libkpathsea compatibility API which calls the kpathsea_set_suffixes function and passes to it its variable list of arguments. This operation is invalid in C. Attached is a backtrace of the segfault and two patches for texk/kpathsea/tex-file.c (inside the source package texlive-bin) that should correct this segfault (I tested them in Qemu but I have no access to a real mips computer). The first patch duplicates some code in tex-file.c (approx. 15 lines), but is smaller and simpler. The second creates a helper function which reads properly a "va_list" list of arguments. Choose your preferred one. Mathias > -- System Information: > Debian Release: squeeze/sid > APT prefers testing > APT policy: (500, 'testing'), (1, 'experimental') > Architecture: mipsel (mips64) > > Kernel: Linux 2.6.36-rc6-loongson-2f > Locale: LANG=ca_AD.UTF-8, LC_CTYPE=ca_AD.UTF-8 (charmap=UTF-8) > Shell: /bin/sh linked to /bin/dash > > Versions of packages dvi2ps depends on: > ii debconf [debconf-2.0] 1.5.36 Debian configuration management > sy > hi libc6 2.11.2-6 Embedded GNU C Library: Shared > lib > ii libfreetype6 2.4.2-1 FreeType 2 font engine, shared > lib > ii libkpathsea5 2009-7 TeX Live: path search library > for > ii texlive-binaries [tex 2009-7 Binaries for TeX Live > ii vflib3 3.6.14.dfsg-1.1+b1 Versatile Font Library > > dvi2ps recommends no packages. > > Versions of packages dvi2ps suggests: > pn dvi2ps-fontdata-ja <none> (no description available) > > -- debconf information excluded
#0 0x2ad3e09c in strlen () from /lib/libc.so.6 No symbol table info available. #1 0x2abf4380 in kpathsea_find_file_generic (kpse=0x2ac1fb00, name=0x468b18 "cmr10.jvf", format=kpse_vf_format, must_exist=1, all=0) at tex-file.c:1002 suffix_len = 1 target = 0x46ec10 ext = 0x46ec18 count = 715960972 name_len = 9 has_potential_suffix = 0 has_any_suffix = 0x468b1d ".jvf" try_std_extension_first = 0x0 use_fontmaps = 0 ret = 0x0 __PRETTY_FUNCTION__ = "kpathsea_find_file_generic" #2 0x2abf3d90 in kpathsea_find_file (kpse=0x2ac1fb00, name=0x7f8822e0 "cmr10.jvf", format=kpse_vf_format, must_exist=1) at tex-file.c:933 ret_list = 0x2aac13a8 ret = 0x0 #3 0x2abf3e44 in kpse_find_file (name=0x7f8822e0 "cmr10.jvf", format=kpse_vf_format, must_exist=1) at tex-file.c:944 No locals. #4 0x00417b3c in kpsearch_make (proto=<value optimized out>, n=0x46e510 "cmr10", format=kpse_vf_format, suffix=0x42ef24 ".jvf", acca=0x7f882780, name=0x46e634 "/fonts/vfdev/morisawa//") at kpse.c:85 path = 0x4444b4 "/fonts/vfdev/morisawa//" base = 0x0 ns = "cmr10.jvf", '\000' <repeats 1014 times> save_path = 0x0 save_orpath = 0x0 save_suffix = 0x0 spec = 0x2ac20448 filename = <value optimized out> #5 0x0040dd4c in vfty_acc (proto=0x1 <Address 0x1 out of bounds>, fe=<value optimized out>, acca=<value optimized out>, type=0x42ef20 "jvf", suffix=0x42ef24 ".jvf") at virfont.c:57 filename = <value optimized out> ok = <value optimized out> #6 0x0040ddec in jvftype_access (proto=0x1 <Address 0x1 out of bounds>, fe=0x468b20, acca=0x18) at virfont.c:44 No locals. #7 0x00409360 in init_fontinfo (fe=0x46e4f8) at fontdesc.c:1087 acca = {acc_mode = 0, rawmagfact = 1.09499967, actmagfact = 1.09544516, submag = 4619320, reqmag = 1, stepmagfact = 6.47304602e-39, pv_name = 0x46e510 "cmr10", pv_mag = 2139629576, pv_fam = 0x1 <Address 0x1 out of bounds>, pv_ds = 1, pv_jsub = 0x2aad24f0 ""} newmagfact = 1.09499967 fd = 0x468538 fs = <value optimized out> sb = 0x443b48 "\001\001" se = 0x443b88 " b@" i = <value optimized out> next = <value optimized out> advice = 0 #8 0x00406644 in first_markchar (c=69) at fontcom.c:99 No locals. #9 0x00406aac in MarkString (firstch=1) at set.c:21 c = <value optimized out> #10 0x0040c87c in scanfont (PreLoad=1, hdfip=0x7f8828d8) at scanfont.c:172 SkipMode = 0 command = 1 count = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0} k = 14 val = <value optimized out> #11 0x00404e60 in main (argc=2, argv=<value optimized out>) at dvi2.c:181 hdfontidx = 0x467eb0 fe = <value optimized out> i = <value optimized out>
--- a/texlive-bin-2009/texk/kpathsea/tex-file.c 2009-06-23 15:50:13.000000000 +0200 +++ b/texlive-bin-2009/texk/kpathsea/tex-file.c 2010-11-08 15:41:50.000000000 +0100 @@ -346,20 +346,34 @@ (*list)[count] = NULL; } - #if defined (KPSE_COMPAT_API) +/* it is impossible to pass around a list of (variable) arguments. */ void kpse_set_suffixes (kpse_file_format_type format, boolean alternate, ...) { + const_string **list; + const_string s; + int count = 0; va_list ap; + + if (alternate) { + list = &(kpse_def->format_info[format].alt_suffix); + } else { + list = &(kpse_def->format_info[format].suffix); + } + va_start (ap, alternate); - kpathsea_set_suffixes (kpse_def, format, alternate, ap); + while ((s = va_arg (ap, string)) != NULL) { + count++; + XRETALLOC (*list, count + 1, const_string); + (*list)[count - 1] = s; + } va_end (ap); + (*list)[count] = NULL; } #endif - /* The path spec we are defining, one element of the global array. */ #define FMT_INFO (kpse->format_info[format]) /* Call kpse_set_add_suffixes. */
--- a/texlive-bin-2009/texk/kpathsea/tex-file.c 2010-11-08 16:37:04.000000000 +0100 +++ b/texlive-bin-2009/texk/kpathsea/tex-file.c 2010-11-08 16:41:08.000000000 +0100 @@ -321,14 +321,13 @@ /* Some file types have more than one suffix, and sometimes it is convenient to modify the list of searched suffixes. */ -void -kpathsea_set_suffixes (kpathsea kpse, kpse_file_format_type format, - boolean alternate, ...) +static void +kpathsea_set_suffixes_va_list(kpathsea kpse, kpse_file_format_type format, + boolean alternate, va_list ap) { const_string **list; const_string s; int count = 0; - va_list ap; if (alternate) { list = &(kpse->format_info[format].alt_suffix); @@ -336,16 +335,24 @@ list = &(kpse->format_info[format].suffix); } - va_start (ap, alternate); while ((s = va_arg (ap, string)) != NULL) { count++; XRETALLOC (*list, count + 1, const_string); (*list)[count - 1] = s; } - va_end (ap); (*list)[count] = NULL; } +void +kpathsea_set_suffixes (kpathsea kpse, kpse_file_format_type format, + boolean alternate, ...) +{ + va_list ap; + va_start (ap, alternate); + kpathsea_set_suffixes_va_list (kpse, format, alternate, ap); + va_end (ap); +} + #if defined (KPSE_COMPAT_API) void @@ -354,7 +361,7 @@ { va_list ap; va_start (ap, alternate); - kpathsea_set_suffixes (kpse_def, format, alternate, ap); + kpathsea_set_suffixes_va_list (kpse_def, format, alternate, ap); va_end (ap); } #endif