From owner-freebsd-arch Tue Jun 19 0:27: 7 2001 Delivered-To: freebsd-arch@freebsd.org Received: from area51.v-wave.com (area51.v-wave.com [24.108.173.252]) by hub.freebsd.org (Postfix) with SMTP id 28BC037B403 for ; Tue, 19 Jun 2001 00:26:59 -0700 (PDT) (envelope-from flatline@area51.v-wave.com) Received: (qmail 53623 invoked by uid 1001); 19 Jun 2001 07:26:58 -0000 Date: Tue, 19 Jun 2001 01:26:58 -0600 From: Chris Wasser To: arch@FreeBSD.org Subject: changes to /etc/rc* Message-ID: <20010619012658.A53486@skunkworks.arpa.mil> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i X-Operating-System: FreeBSD 4.2-STABLE i386 X-Subliminal: On the count of 3, you will bark like a dog. 1.. 2.. 3.. Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Ok, since there is a lot for me to cover here, I'm going to answer everyone in one big related email so please bear with me (it's a long read to various parties). I will only be sending this to -arch so if someone feels others should receive this, then please forward it to the appropiate parties. Everyone else is more then welcome to put their two cents into what I have to say :) (original message from lukem@wasabisystems.com has remained unabridged) >Date: Tue, 19 Jun 2001 10:23:06 +1000 >From: Luke Mewburn >To: Chris Wasser >Subject: Re: NetBSD /etc/rc.subr diff >Cc: Sheldon Hearn >Reply-To: Luke Mewburn > >>On Mon, Jun 18, 2001 at 02:15:24PM -0600, Chris Wasser wrote: >> Hi, >> >> Attached is a diff to /etc/rc.subr for NetBSD (and recently imported >> into FreeBSD) which is designed to reduce the potential for false >> positive hits in gathering process information for the rc init >> system. >> >> Please note the diff is applied against the rc.subr in FreeBSD's >> tag=HEAD rather then the actual NetBSD /etc/rc.subr, however the >> differences between the two are very minor and should have no >> problems merging this diff. >> >> I'm interested to hear any comments, suggestions or just general >> questions you may have on this diff and would be happy to answer any >> posed. > >Hi Chris. > >I'm not sure which version of rc.subr was used in the FreeBSD import, >but it looks a little old, because in rev 1.30 in NetBSD I changed >that particular code to use "case" instead of "if", etc. I based my diff off the rc.subr (v1.28) found at: http://www.FreeBSD.org/cgi/cvsweb.cgi/src/etc/rc.subr?only_with_tag=HEAD Again, I noted this diff was made against rc.subr that I found in the FreeBSD cvs tree. > >Other comments: > > - There's no need to check if a command matches > "*/$_procnamebn" > because $_procnamebn is the basename of $_procname > (that's that > _procnamebn=${_procname##*/} > does) > In this I disagree entirely. Not that in $_procnamebn isn't a valid match-term, but that searching for */$_procnamebn is also perfectly valid, and can reduce the potential for false matches, consider the following processes 'qmail-smtpd' and 'cron': /root# ps -ax -o pid,command | grep cron 24404 /usr/sbin/cron 53287 grep cron /root# ps -ax -o pid,command | grep qmail-smtpd 53289 grep qmail-smtpd As you can see, cron is found, but only grep is displayed for qmail-smtpd, this matching system would fail to discover the process id for qmail-smtpd which indeed is running using my calling and matching scheme for process checks: /root# ps -axwww -o pid,command | grep cron 24404 /usr/sbin/cron 53293 grep cron /root# ps -axwww -o pid,command | grep qmail-smtpd 53373 grep qmail-smtpd 328 /usr/local/bin/tcpserver -v -R -x/etc/tcp.smtp.cdb -u82 -g81 0 smtp /usr/local/bin/fixcrio /usr/local/bin/rblsmtpd -b -rrelays.mail-abuse.org /var/qmail/bin/qmail-smtpd By matching for leading / (and thus, indicative of absolute pathed execution) it's quite easy to find the correct PID of the process in question. Almost all the services started from FreeBSD (unsure about NetBSD, I imagine it's the same) rc are absolutely pathed when they're executed [if that's the correct term] for example, sshd in which I've only configured sshd_flags and sshd_enable in /etc/rc.conf: /root# ps -axwww -o pid,command | grep sshd 25063 /usr/sbin/sshd -p 22 53375 grep sshd Which in turn is set up initially from /etc/default/rc.conf: /root# grep sshd /etc/defaults/rc.conf sshd_enable="NO" # Enable sshd sshd_program="/usr/sbin/sshd" # path to sshd, if you want a different one. sshd_flags="" # Additional flags for sshd. So matching for a leading / is not only a good thing, but can produce results faster and more accurately (because search 'term' has been increased, more characters to match is a better match no?) I have tested your theory about not needing this matching, and removing the relevant section of shellcode which preforms the check against */_procnamebn fails to find qmail-smtpd in the above example, thus rc will fail to find the process, or mark it as down or handle it however it chooses. You can find a shellscript designed to preform this same check @ http://plaza.v-wave.com/cwasser/proc-read.sh (see script for details) to test this theory yourself. > - I use the test for pid == "PID" to skip the first entry > which is the header line from ps because > a) there's no valid PID called "PID", so my test isn't > going to get a false match > b) tail and sort are in /usr/bin, which may not be > mounted when this code runs. > c) the current code (using case not if) is fast > > > - I'm not sure why you call "ps -www ...", and also check all > the command arguments of the process for matching process names > to find a PID. > What's the rationale here? By using sort and tail, this check for pid == "PID" is uneccessary as unneeded information is weeded out before it's processed by the shellcode. Not only does it remove the need to check for ps(1) headers, but it also sorts the output in a manner most efficient to producing matches, what I mean by this is the same matches /etc/rc.subr is trying to make: $_procname|$_procnamebn|${_procnamebn}:|"(${_procnamebn})" Are logically sorted to the top of the list after tail and sort are finished, producing matches on these somewhat ambigious matches (a good example is sendmail, or tcpserver) which use setproctitle(3) and again, I re-iterate, it's my feeling that adding another match-term for absolute pathed process entries will also produce faster, more accurate results (to some extent): For example (I will show only relevant sections as they appear): /root# ps -axwww -o pid,command | tail +2 | sort +1 4 (bufdaemon) 2 (pagedaemon) 53396 (sh) 388 -csh (csh) 440 -csh (csh) 470 ./irc -p 6667 TDF irc.powersurfr.com 24404 /usr/sbin/cron 300 /usr/sbin/moused -3 -F 200 -r high -p /dev/psm0 210 /usr/sbin/portmap 25063 /usr/sbin/sshd -p 22 381 /usr/sbin/syslogd -ss 53514 ps -axwww -o pid,command 325 qmail-clean 17173 sshd: flatline (sshd) 34624 sshd: flatline (sshd) However, seeing as how sort and tail may not be available for usage due to unmounted filesystem, the logical choice then is instead of matching against _npid one could match against _arg0 as a measure to removing irrelevant information. For example: NetBSD cvsweb directory for /etc/rc.subr (v1.37): http://cvsweb.netbsd.org/bsdweb.cgi/basesrc/etc/rc.subr?only_with_tag=HEAD In check_process() and check_pidfile() you use similar checks: case "$_npid" in PID) continue ;; esac case "$_arg0" in $_procname|$_procnamebn|${_procnamebn}:|"(${_procnamebn})") echo $_npid return ;; esac This would be more efficient if you matched COMMAND in $_arg0 case-select, for example: case "$_arg0" in COMMAND) continue ;; $_procname|$_procnamebn ... ... ... esac Unless 'ps -ax ...' on other platforms produce different headers then on say x86, I don't see this creating a problem or adding to false-positive matches since COMMAND is also a invalid pid like PID is, and thus it's more efficient to remove it in one check rather then two independant case-select's. As for the rationale behind using 'ps -axwww ...' it's quite simple, without it, it's impossible to match examples like qmail-smtpd above, if the method I proposed fails to match any valid likelies in _arg0 then _argv is parsed by word matching against the same values as _arg0 was, producing a valid and relative match, using 'www' ensures that full path is displayed, producing more text to match against for each process being parsed. >I strongly suggest ensuring that you're working with rc.subr from >NetBSD-current, because I've made significant portability, performance >and functionality enhancements to it since NetBSD 1.5. In this I agree that the case-select used in v1.30+ for both check_process() and check_pidfile() is better then the if-then used in the FreeBSD-current /etc/rc.subr (v1.28) and the NetBSD 1.5 /etc/rc.subr (v1.20.2.4) for both functions. >By the way, I'm going to be at USENIX next week talking about rc.d. If >you (or any other FreeBSD developer who is going to be there) wants to >chat about this stuff then, feel free to find me and bend my ear! > >Luke. It should be noted that I foolishly emailed Luke instead of keeping this in -arch so I apologize to Luke (and those who got annoyed by me doing this) for stepping on whatever and whomever's toes. I feel these are valid reasons for the various changes I've proposed in order what I know will be a ongoing problem until a specialized tool is written to handle this properly. David O'Brien also mentioned that some people might say that the two extra pipes used in filtering out the unwanted data in the ps report might slow things down (as NetBSD runs on some slow, older hardware) in this I really can't say what the impact would be, again, lending itself toward the creation of a tool which exists in /bin (thus should be OK in all mounting suituations) that can pull the specific process id in question. (There was some talk of this on IRC a while ago...) - Chris To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message