Lift artificial limit on output file names in -ff mode

Starting with commit v4.5.19~88 strace imposed an artificial limit
on output file names in -ff mode, leading to the following absurd
behaviour:

$ strace -ff -o"$(perl -e 'print "/" x 510')/$PWD/log" /bin/true
strace: Can't fopen '////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////.12345': Permission denied

* strace.c (newoutf): Raise buffer size to PATH_MAX.
(init) <followfork >= 2>: Check output file name prefix length.
* tests/options-syntax.test: Check it.
This commit is contained in:
Дмитрий Левин 2018-01-04 10:52:07 +00:00
parent 2216f14499
commit 9cbb505f9f
2 changed files with 8 additions and 2 deletions

View File

@ -673,8 +673,8 @@ newoutf(struct tcb *tcp)
{
tcp->outf = shared_log; /* if not -ff mode, the same file is for all */
if (followfork >= 2) {
char name[520 + sizeof(int) * 3];
sprintf(name, "%.512s.%u", outfname, tcp->pid);
char name[PATH_MAX];
sprintf(name, "%s.%u", outfname, tcp->pid);
tcp->outf = strace_fopen(name);
}
}
@ -1831,6 +1831,9 @@ init(int argc, char *argv[])
shared_log = strace_popen(outfname + 1);
} else if (followfork < 2) {
shared_log = strace_fopen(outfname);
} else if (strlen(outfname) >= PATH_MAX - sizeof(int) * 3) {
errno = ENAMETOOLONG;
perror_msg_and_die("%s", outfname);
}
} else {
/* -ff without -o FILE is the same as single -f */

View File

@ -67,6 +67,9 @@ check_e_using_grep 'regcomp: \[id: [[:alpha:]].+' -e trace='/[id'
check_e_using_grep 'exec: File *name too long' "$(printf '%4096s' ' ')"
ff_name="$(printf '%4084s' ' ')"
check_e_using_grep "$ff_name: File *name too long" -ff -o "$ff_name" true
check_h 'must have PROG [ARGS] or -p PID'
check_h 'PROG [ARGS] must be specified with -D' -D -p $$
check_h '-c and -C are mutually exclusive' -c -C true