Bug 7364 - spamd incorrectly sets $0
Summary: spamd incorrectly sets $0
Status: RESOLVED WORKSFORME
Alias: None
Product: Spamassassin
Classification: Unclassified
Component: Libraries (show other bugs)
Version: 3.4.1
Hardware: PC Linux
: P2 minor
Target Milestone: Undefined
Assignee: SpamAssassin Developer Mailing List
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-10-26 16:10 UTC by Noah Meyerhans
Modified: 2022-04-16 06:07 UTC (History)
4 users (show)



Attachment Type Modified Status Actions Submitter/CLA Status
Patch against 3.4.1 text/plain None Noah Meyerhans [NoCLA]
demonstrataion text/x-perl None Noah Meyerhans [NoCLA]

Note You need to log in before you can comment on or make changes to this bug.
Description Noah Meyerhans 2016-10-26 16:10:02 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.
Comment 1 RW 2016-10-26 19:36:28 UTC
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)
Comment 2 Noah Meyerhans 2016-10-27 04:24:43 UTC
Created attachment 5414 [details]
demonstrataion

Sample program showing what happens when $0 is modified in various ways in a perl program.
Comment 3 Noah Meyerhans 2016-10-27 04:25:54 UTC
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.
Comment 4 Kevin A. McGrail 2018-08-26 21:26:26 UTC
Hi Noah, any comments as to this bug and bug 7295 ?
Comment 5 Henrik Krohns 2022-04-16 06:07:13 UTC
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.