SA Bugzilla – Bug 7364
spamd incorrectly sets $0
Last modified: 2022-04-16 06:07:13 UTC
Created attachment 5413 [details] Patch against 3.4.1 (Forwarded from https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=715014) Spamd modifies its command-line ($0) in a couple of places: ctrl:spamassassin-3.4.1$ grep -n '$0 =' spamd/spamd.raw 1384: $0 = 'spamd child'; 2962: $0 = join (' ', $ORIG_ARG0, @ORIG_ARGV) unless would_log("dbg"); However, it does not do so in accordance with the documented specification for the format of ARGV. From the proc(5) man page on linux: /proc/[pid]/cmdline This read-only file holds the complete command line for the process, unless the process is a zombie. In the latter case, there is nothing in this file: that is, a read on this file will return 0 characters. The command-line arguments appear in this file as a set of strings separated by null bytes ('\0'), with a fur‐ ther null byte after the last string. So spamd should be using NULL characters to separate the fields in $0. I've attached a patch against 3.4.1 to correct this. Tests still pass, and I'm currently running with this patch in production. It will likely be included in the next upload to Debian.
In FreeBSD ps doesn't display the spamd arguments anymore after this patch the processes used to display as ... /usr/local/bin/spamd -x -c -p ... (perl) ... spamd child (perl) ... spamd child (perl) now they display as ... /usr/local/bin/spamd (perl) ... spamd (perl) ... spamd (perl)
Created attachment 5414 [details] demonstrataion Sample program showing what happens when $0 is modified in various ways in a perl program.
Indeed, it doesn't work as I thought on Linux either, as demonstrated by the attached small program that modifies $0 as currently done by spamd, and as proposed in my patch. Neither case results in what I think is correct behavior. When run with command-line arguments of "foo", "bar", and "baz", the output is as follows. The "Original" output is the value of $0 and /proc/self/cmdline before we modify it, and hexdump shows that proc contains the null delimited command line as documented. Modifying $0 as a null-delimited string, however, doesn't leave us with a null-delimited string in /proc/self/cmdline, so 'ps' output does not contain the complete command line listing. Modifying $0 as a space-delimited string (current spamd behavior) results in improperly structured data in proc, but the 'ps' listing happens to look right. Original $0: /tmp/perl-test.pl Original /proc/self/cmdline: 00000000 2f 75 73 72 2f 62 69 6e 2f 70 65 72 6c 00 2f 74 |/usr/bin/perl./t| 00000010 6d 70 2f 70 65 72 6c 2d 74 65 73 74 2e 70 6c 00 |mp/perl-test.pl.| 00000020 66 6f 6f 00 62 61 72 00 62 61 7a 00 |foo.bar.baz.| 0000002c null-separated $0: test-programfoobarbaz null-separated /proc/self/cmdline: 00000000 74 65 73 74 2d 70 72 6f 67 72 61 6d |test-program| 0000000c space-separated $0: test-program foo bar baz space-separated /proc/self/cmdline: 00000000 74 65 73 74 2d 70 72 6f 67 72 61 6d 20 66 6f 6f |test-program foo| 00000010 20 62 61 72 20 62 61 7a | bar baz| 00000018 The complete argument list is: foo bar baz So I'm not sure what the right way to modify $0 is in this case, or even if there is a right way.
Hi Noah, any comments as to this bug and bug 7295 ?
Main spamd $0 setting was already removed in Bug 7594. I don't think having "spamd child" is a problem as "pgrep -x spamd" finds the main process. You can always do a "pgrep -f spamd" or pgrep -x "spamd child" for children. Closing.