[lug] resolve.conf contents -- origin?

Jim Buzbee james.buzbee at echostar.com
Mon Oct 23 11:09:19 MDT 2000


"Atkinson, Chip" wrote:
> 
> Greetings,
> 
> Every time I reboot my machine resolve.conf gets over written with the
> old/original values.  I thought I used linuxconf to change the name servers
> that are referenced but they still show up as being the non-current values.
> I'm using RH 6.1.  Any idea where I can look to force the issue?  I could
> always do something lame like put "cat .... > /etc/resolv.conf" in rc.local,
> but that seems rather lame.
> 
> Thanks in advance,
> 
> Chip
>

OK, if you _really_ want to know who is doing it, try the attached
dangerous kernel module.  The origin of the module is from Ori
Pomerantz, but I hacked it up crudely it for my needs.  It allows you to
watch a file, in this case resolv.conf and then report which process
opened it.  Since your problem happens at boot time, you would need to
have the module loaded early.  It will also only tell you the pid and
uid which may not be enough. You will get a lot of false alarms as
process read it for name resolution. Modify as needed to report only
writers, and get the process name.

Jim
-------------- next part --------------

/* syscall.c 
 * 
 * System call "stealing" sample
 */


/* Copyright (C) 1998-99 by Ori Pomerantz */


/* The necessary header files */

/* Standard in kernel modules */
#include <linux/kernel.h>	/* We're doing kernel work */
#include <linux/module.h>	/* Specifically, a module */

/* Deal with CONFIG_MODVERSIONS */
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include <linux/modversions.h>
#endif

#include <sys/syscall.h>	/* The list of system calls */

/* For the current (process) structure, we need
 * this to know who the current user is. */
#include <linux/sched.h>




/* In 2.2.3 /usr/include/linux/version.h includes a 
 * macro for this, but 2.0.35 doesn't - so I add it 
 * here if necessary. */
#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))
#endif



#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
#include <asm/uaccess.h>
#endif



/* The system call table (a table of functions). We 
 * just define this as external, and the kernel will 
 * fill it up for us when we are insmod'ed 
 */
extern void *sys_call_table[];


/* UID we want to spy on - will be filled from the 
 * command line */
int uid = -1;

/* UID we want to spy on - will be filled from the 
 * command line */
int pid = -1;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
MODULE_PARM (uid, "i");
MODULE_PARM (pid, "i");
#endif

/* A pointer to the original system call. The reason 
 * we keep this, rather than call the original function 
 * (sys_open), is because somebody else might have 
 * replaced the system call before us. Note that this 
 * is not 100% safe, because if another module 
 * replaced sys_open before us, then when we're inserted 
 * we'll call the function in that module - and it 
 * might be removed before we are.
 *
 * Another reason for this is that we can't get sys_open.
 * It's a static variable, so it is not exported. */
asmlinkage int (*original_call) (const char *, int, int);



/* For some reason, in 2.2.3 current->uid gave me 
 * zero, not the real user ID. I tried to find what went 
 * wrong, but I couldn't do it in a short time, and 
 * I'm lazy - so I'll just use the system call to get the 
 * uid, the way a process would. 
 *
 * For some reason, after I recompiled the kernel this 
 * problem went away. 
 */
asmlinkage int (*getuid_call) ();



/* The function we'll replace sys_open (the function 
 * called when you call the open system call) with. To 
 * find the exact prototype, with the number and type 
 * of arguments, we find the original function first 
 * (it's at fs/open.c). 
 *
 * In theory, this means that we're tied to the 
 * current version of the kernel. In practice, the 
 * system calls almost never change (it would wreck havoc 
 * and require programs to be recompiled, since the system
 * calls are the interface between the kernel and the 
 * processes).
 */
asmlinkage int
our_sys_open (const char *filename, int flags, int mode)
{
   int i = 0;
   char ch;
   int status;

   /* Check if this is the user we're spying on */
/*
   if (uid == getuid_call ())
printk("pid = %d\n", current->pid );
   if ( (uid == current->uid ) || ( pid ==  current->pid ) )
   if ( ( pid ==  current->pid ) )
*/
   uid = getuid_call ();
   pid =  current->pid;

   if ( strstr( filename, "resolv.conf" ) )
   {
      /* getuid_call is the getuid system call, 
       * which gives the uid of the user who
       * ran the process which called the system
       * call we got */

      /* Report the file, if relevant */
      printk(  " resolv.conf Opened file by %d, %d: ", uid, pid);

      do
      {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
	 get_user (ch, filename + i);
#else
	 ch = get_user (filename + i);
#endif
	 i++;
	 printk (  "%c", ch);
      }
      while (ch != 0);

      status = original_call (filename, flags, mode);
      printk (  " : Status = %d\n", status);
      return (status);
   }
   else
   {
      /* Call the original sys_open - otherwise, we lose 
       * the ability to open files */
      return ( original_call (filename, flags, mode) );
   }
}



/* Initialize the module - replace the system call */
int
init_module ()
{
   /* Warning - too late for it now, but maybe for 
    * next time... */
   printk (  "I'm dangerous. I hope you did a ");
   printk (  "sync before you insmod'ed me.\n");
   printk (  "My counterpart, cleanup_module(), is even");
   printk (  "more dangerous. If\n");
   printk (  "you value your file system, it will ");
   printk (  "be \"sync; rmmod\" \n");
   printk (  "when you remove this module.\n");

   /* Keep a pointer to the original function in 
    * original_call, and then replace the system call 
    * in the system call table with our_sys_open */
   original_call = sys_call_table[__NR_open];
   sys_call_table[__NR_open] = our_sys_open;

   /* To get the address of the function for system 
    * call foo, go to sys_call_table[__NR_foo]. */

   if ( uid >= 0 )
   {
      printk (  "Spying on UID:%d\n", uid);
   }

   if ( pid >= 0 )
   {
      printk (  "Spying on pid:%d\n", pid);
   }

   /* Get the system call for getuid */
   getuid_call = sys_call_table[__NR_getuid];

   return 0;
}


/* Cleanup - unregister the appropriate file from /proc */
void
cleanup_module ()
{
   /* Return the system call back to normal */
   if (sys_call_table[__NR_open] != our_sys_open)
   {
      printk (  "Somebody else also played with the ");
      printk (  "open system call\n");
      printk (  "The system may be left in ");
      printk (  "an unstable state.\n");
   }

   sys_call_table[__NR_open] = original_call;
}
-------------- next part --------------
INCLUDEDIR = /usr/include

CFLAGS = -D__KERNEL__ -DMODULE -O -Wall -I$(INCLUDEDIR)

VER = $(shell awk -F\" '/REL/ {print $$2}' $(INCLUDEDIR)/linux/version.h)

OBJS = syscall.o

all: syscall.o


unload  : 
	sync
	/sbin/rmmod syscall

load  : syscall.o
	sync
	/sbin/insmod syscall.o

install : 
	sync
	/sbin/rmmod syscall
	/sbin/insmod syscall.o
	dmesg


More information about the LUG mailing list