[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

logging setuid changes

I started playing around with having the kernel log setuid changes a
while ago, mostly out of frustration with the noise my box makes at
1:30am every night as it runs a find on all the filesystems.

I wrote a little patch to the chmod system call that writes a message to
syslog every time someone adds the setuid bit to a file. I spent a while
messing around with the name cache to see if I could get it to print out
the pathname but gave up and have it printing the inode number and
filesystem. This way you can at least just `find -inum xxx /fs` and find
the file. It wouldn't be hard to rewrite /etc/security to handle that,
but I'd rather spend the time and get it right. I just wanted to get
some feedback on whether this was a good idea at all before I waste too
much more time.

Some things to do that I have in mind:
-add to fchmod (easy)
-wrap in a sysctl so you can turn it off and on
-print out different warnings (no warning?) if the fs is mounted
-try and get the pathname out of the kernel name cache if possible, a la

The advantages that I see, aside from quieter disks, are that it is
realtime, instead of a daily check. Also, you don't have to keep
/var/backups/setuid.backup around anymore. Not a big deal, but it's one
less file in that dir. I'm sure our friends running on CF will
appreciate it.

Let me know if this is something with potential or not and I'll work on
it accordingly.


*** /usr/src/sys/kern/vfs_syscalls.c.orig	Mon May 10 13:49:50 2004
--- /usr/src/sys/kern/vfs_syscalls.c	Mon May 10 14:00:00 2004
*** 57,62 ****
--- 57,66 ----
  #include <uvm/uvm_extern.h>
  #include <sys/sysctl.h>
+ #include <sys/syslog.h>
+ #include <ufs/ufs/quota.h>
+ #include <ufs/ufs/inode.h>
  extern int suid_clear;
  int	usermount = 0;		/* sysctl: by default, users may not mount */
*** 1889,1895 ****
--- 1893,1902 ----
  	struct vattr vattr;
  	int error;
  	struct nameidata nd;
+ 	struct inode *ip;
+ 	struct statfs *mntbuf;
  	if (SCARG(uap, mode) & ~(S_IFMT | ALLPERMS))
  		return (EINVAL);
*** 1907,1912 ****
--- 1914,1933 ----
  		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
+ 	/* log if setuid is changed */
+ 	if ((SCARG(uap, mode) & S_ISUID) && !error) {
+ 		/* get the inode */
+ 		ip = VTOI(vp);
+ 		/* get the filesystem */
+ 		*mntbuf = vp->v_mount->mnt_stat;
+ 		/* send notice to syslog */
+ 		log(LOG_NOTICE, "Setuid bit set on inode %u in filesystem mounted on %s by uid %u\n", 
+ 			ip->i_number, mntbuf->f_mntonname, p->p_cred->p_ruid);
+ 	} /* setuid */
  	return (error);