/* * I had this weird bug where my /dev/null kept going to perm mode 0600. * Using this program I was able to figure out the guilty program that did this horrible thing. * satebackire * * gcc -shared -fPIC -Wall -ldl -lm chmod_hook.c -o /usr/local/lib/chmod_hook.so * chown root:root /usr/local/lib/chmod_hook.so * chmod 755 /usr/local/lib/chmod_hook.so * echo /usr/local/lib/chmod_hook.so > /etc/ld.so.preload */ #define _GNU_SOURCE /* required to get RTLD_NEXT defined */ #define _XOPEN_SOURCE /* required to get strptime() defined */ #include #include #include #include #include #include #include /* prototype */ int chmod(const char *path, mode_t mode); /* * Intercepted lib calls: * chmod() */ int chmod(const char *path, mode_t mode){ static int (*real_chmod)(const char *, mode_t); FILE *log, *proc; char buf[1024*8]; /* 8K static buffer */ char rwx[16]; time_t mytime = time(NULL); strcpy(rwx, "--- --- ---"); //printf("p[%s]\n", path); real_chmod = NULL; real_chmod = dlsym(RTLD_NEXT, "chmod"); /* check whether dlsym() worked */ if (dlerror() != NULL) { errx(-1, "Dead in dlsym\n"); } if( strstr(path, "/dev/null") != NULL ){ log = fopen( "/tmp/chmod_log.txt", "a"); if( log == NULL){ errx(-1, "can't open log"); } fprintf( log, "chmod of /dev/null:"); /* who was the proc did this horrible thing? */ proc = fopen("/proc/self/cmdline", "r"); if( proc == NULL){ errx(-1, "can't open proc entry"); } fread( buf, sizeof(buf)-1, 1, proc); fclose( proc ); fprintf( log, " cmdline[%s]", buf); /* what are they trying to change to? */ if( S_IRUSR & mode){ rwx[0] = 'r'; } if( S_IWUSR & mode){ rwx[1] = 'w'; } if( S_IXUSR & mode){ rwx[2] = 'x'; } if( S_IRGRP & mode){ rwx[4] = 'r'; } if( S_IWGRP & mode){ rwx[5] = 'w'; } if( S_IXGRP & mode){ rwx[6] = 'x'; } if( S_IROTH & mode){ rwx[8] = 'r'; } if( S_IWOTH & mode){ rwx[9] = 'w'; } if( S_IXOTH & mode){ rwx[10] = 'x'; } /* when did they do it? */ fprintf( log, " perms[%s] time:%s", rwx, ctime(&mytime)); } return (*real_chmod)(path, mode); }