xargs の落とし穴らしきもの
Mac OS X (10.4.9 (8P135)) 上で xargs を使っていたら変な挙動をしたりいきなり segfault したりしたので「ん?これはもしや vuln ?」と思っていろいろ深入りしてしまった。
% xargs -I@ echo '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' ahoahoahoahoaho ahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoah ahoahoahoahoaho ahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoah ahoahoahoahoaho ahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoahoah xargs(1309) malloc: *** error for object 0x300250: incorrect checksum for freed object - object was probably modified after being freed, break at szone_error to debug xargs(1309) malloc: *** set a breakpoint in szone_error to debug zsh: segmentation fault xargs -I@ echo
結論から言うともう本家の方では src/usr.bin/xargs/strnsubst.c:r1.7 で直ってる模様。問題は当該リビジョンのログメッセージだ。
revision 1.7
date: 2004/10/18 15:40:47; author: cperciva; state: Exp; lines: +2 -2
Modify behaviour of `xargs -I` in order to:
- Conform to IEEE Std 1003.1-2004, which state that "Constructed arguments cannot grow larger than 255 bytes", and
- Avoid a buffer overflow.
Unfortunately the standard doesn't indicate how xargs is supposed to handle arguments which (with the appropriate substitutions) would grow larger than 255 bytes; this solution handles those by making as many substitutions as possible without overflowing the buffer.
OpenBSD's xargs resolves this in a different direction, by making all the substitutions and then silently truncating the resulting string.
Since this change may break existing scripts which rely upon the buffer overflow (255 bytes isn't really all that long...) it will not be MFCed.
src/usr.bin/xargs/strnsubstr.c:r1.7@cvs.freebsd.org
255 バイトって短すぎやしませんか?と思って「site:opengroup.org」をつけてアレしてみたら、確かに次のように書かれているページを確認できた。
xargs(1)@opengroup.org
- -I replstr
- Insert mode: utility will be executed for each line from standard input, taking the entire line as a single argument, inserting it in arguments for each occurrence of replstr. A maximum of five arguments in arguments can each contain one or more instances of replstr. Any blank characters at the beginning of each line are ignored. Constructed arguments cannot grow larger than 255 bytes. Option -x is forced on. The -I and -i options are mutually exclusive; the last one specified takes effect.
POSIX の PATH_MAX が 256 バイトだから 255 バイトに制限にしてるってわけなのかこれは??んなアホな。