From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Darryl Dixon - Winterhouse Consulting" Subject: Re: Decoding arguments passed to system calls Date: Tue, 3 Jul 2007 10:48:23 +1200 (NZST) Message-ID: <42015.65.99.233.211.1183416503.squirrel@pythonhacker.is-a-geek.net> References: <52930.65.99.233.211.1183412786.squirrel@pythonhacker.is-a-geek.net> <1183415256.4534.50.camel@localhost.localdomain> Reply-To: darryl.dixon@winterhouseconsulting.com Mime-Version: 1.0 Content-Type: text/plain;charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable Return-path: In-Reply-To: <1183415256.4534.50.camel@localhost.localdomain> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-audit-bounces@redhat.com Errors-To: linux-audit-bounces@redhat.com To: Matthew Booth Cc: linux-audit@redhat.com List-Id: linux-audit@redhat.com Hi Matt, On Tue, July 3, 2007 10:27 am, Matthew Booth wrote: > On Tue, 2007-07-03 at 09:46 +1200, Darryl Dixon - Winterhouse Consultin= g > wrote: >> Scenario: >> A very large filesystem with potentially millions of files in an ad-ho= c, >> unordered directory structure. The requirement is to be able to audit >> any >> action on any file in this filesystem (moves, adds, changes, deletes, >> etc). In auditfs terms, there is a requirement to have a 'watch' on >> every >> single file (millions of files), and on any new file that is added. >> >> Hypothetical solution: >> Clearly, scanning the filesystem with `find` and adding calling auditc= tl >> with the appropriate arguments to generate a watch on every singly fil= e >> is >> totally infeasible (find takes almost an hour to run, and in the >> meantime >> stuff is potentially changing...). Instead, I envision it would make >> better sense to simply audit every call to write(), open(), rename(), >> etc, >> and then filter backwards from there with ausearch and a filter based = on >> the path. On Solaris with BSM, this is possible. My problem is that th= is >> doesn't seem possible with the Linux Audit subsystem, as the arguments >> to >> the system calls are not decoded (eg, the audit records for write() >> include only an opaque filehandle and pointer to the written data, etc= ). > > This is entirely feasible, with the exception that you probably don't > want to audit write() calls generally. That would be a truly insane > amount of traffic. A highly effective heuristic is to look at the > arguments to the open() system call. If the file was opened for write > (a1 | 1 =3D=3D 1 || a1 | 2 =3D=3D 2), then assume that the file was alt= ered. > > Take the following example: > > type=3DSYSCALL msg=3Daudit(1183414428.656:2779): arch=3D40000003 syscal= l=3D5 > success=3Dyes exit=3D3 a0=3D91d4088 a1=3D8000 a2=3D0 a3=3D8000 items > =3D1 ppid=3D16166 pid=3D16270 auid=3D500 uid=3D0 gid=3D0 euid=3D0 suid=3D= 0 fsuid=3D0 > egid=3D0 sgid=3D0 fsgid=3D0 tty=3Dpts2 comm=3D"vi" exe=3D"/bin/vi" sub > j=3Duser_u:system_r:unconfined_t:s0 key=3D(null) > > type=3DCWD msg=3Daudit(1183414428.656:2779): cwd=3D"/root" > > type=3DPATH msg=3Daudit(1183414428.656:2779): item=3D0 name=3D"install.= log" > inode=3D720898 dev=3Dfd:00 mode=3D0100644 ouid=3D0 ogid=3D0 rdev=3D00 > :00 obj=3Droot:object_r:user_home_t:s0 > > You can tell the filesystem from the dev field of the PATH record: > [mbooth@mbooth ~]$ ls -l /dev/mapper/vg_local-root > brw-rw---- 1 root disk 253, 0 Jul 2 19:53 /dev/mapper/vg_local-root > > 253, 0 =3D=3D fd:00 > > You can tell it was opened for read, because the last 2 bits of a1 in > the SYSCALL record are 00. I guess doing this automatically is the crux > of your question. For ease of path handling, you're also going to want = a > solution to the absolute path question. > > As an aside, adding the rules you mention above with a standard audit > configuration is likely to kill your system as soon as you put load on > it. The principal reason for this is the frequent flushing of the log > file. If integrity of the audit trail isn't that important, tone down > the flushing on the audit log and you'll find that it can sustain prett= y > intense throughput. If you need both integrity and performance, the bes= t > solution I've come up with is to send audit records to a remote host vi= a > syslog in real time over a network which we trust not to drop packets, > and not write anything to disk. > > Matt Hi Matt, Thank you for your very thorough response. What you say about not being able to audit 'write()' is worrying to me. The problem with auditing writ= e by inference from open(), is that one doesn't know *when* the file was written, or even if it really ever was at all (eg, was data written continuously from open() to close(), or only sporadically over the course of hours or days?). Auditing for actual alterations is definitely something that we need to be able to track. Assuming for a moment that we have beefy enough hardware ( heh ), can the path be extracted from write(= ) as with your example for open() above? My assumption would have been that CWD reflected only where the exe was launched from, and not necessarily where the write()-en file was located... regards, Darryl Dixon Winterhouse Consulting Ltd http://www.winterhouseconsulting.com