Kernel-Mode Databases
by Andrei Gorine and Alexander Krivolapov


Example 1: Database schema.

struct ACL
{
  uint4   uid;       // user id
  uint4   access;    // access allowed for some user id
};
class File
{
  char<100> name;   // file name
  uint4  inode;     // file inode
  uint4  device;    // device    
  uint4  owner;     // owner of the File
  uint4  defaccess;  
  vector< ACL > acls; // access control lists

  hash < name >          hname[4096];
  hash < inode ,device > hfile[4096];
};

Example 2: Allocating virtual memory for the database pool.

/* allocate the database memory pool */
mem_ua_ptr = (char*)vmalloc( arg+PAGE_SIZE*2 );
if ( mem_ua_ptr == 0 ) {
     return -ENOMEM; /* error allocating memory */
}


Example 3: Locking virtual memory pages.

/* calculate page aligned address */
mem_ptr = (char*) ( ((unsigned long)mem_ua_ptr+PAGE_SIZE-1) & PAGE_MASK );
    /* lock pages */
    for ( va=(unsigned long)mem_ptr;
           va<(unsigned long)(&(mem_ptr[mem_size/sizeof(int)]));
           va+=PAGE_SIZE) {
     SetPageReserved(vmalloc_to_page((void *)(((unsigned long)va))));
    }

Example 4: Interface definition header file.

#ifndef __EX_DB_API_H
#define __EX_DB_API_H

typedef struct tagFile {
        unsigned char result;
        char     name[100];
        unsigned int  inode;
        unsigned int  device;
        unsigned int  owner;
        unsigned int  defaccess;
}File_t, *File_h;

typedef char* zstring    /*sero-terminated string*/;
typedef unsigned int* pint;
int exdb_init_database ( unsigned long mem_size );
int exdb_shutdown_database( );
int exdb_add_file
        (zstring file_name, unsigned int inode,
         unsigned int device, unsigned int owner,
         unsigned int defaccess );

int exdb_remove_file( zstring file_name );
int exdb_find_file( zstring file_name,
                   /*out*/ pint pinode,
                   /*out*/ pint pdevice,
                   /*out*/ pint powner,
                   /*out*/ pint pdefaccess );
int exdb_authorize_file( zstring file_name, unsigned int uid, unsigned int access );
#endif /* __EX_DB_API_H */


Example 5: (a) User mode; (b) Kernel mode

(a)

if ( 0 != (i = exdb_find_file( name, &inode, &device, &owner, &access ))) {
         printf("exdb_find_file(\"%s\")==%d\n", name, i );
         return (0);
 };


(b)

if ( 0 != (i = exdb_find_file( name,&inode,&device,&owner,&access ))) {
         pr_info(DEV_NAME" exdb_find_file(\"%s\")==%d\n", name, i );
         return (0);
 };


Example 6:

static int __init eACmod_init( void )
{
  if (!sys_call_table)
  {
    return -1;
  }
  if ( (major = register_chrdev( 0, DEV_NAME, &eACmod_fops )) < 0 )
  {
    return -EIO;
  };
  eACm_api_Init();
  intercept_syscalls();
  return 0;
};


Example 7: intercept_syscalls

extern void *sys_call_table[];
typedef int (*syscall_t)();

extern int my_open();
extern int my_creat();
extern int my_chmod();
extern int my_chown();
extern int my_unlink();
extern int my_execve();

struct replace_syscall replace_syscall[]={
     {INDEX_NR_open,     __NR_open,     (int(*)())0,   my_open},
     {INDEX_NR_creat,    __NR_creat,    (int(*)())0,   my_creat},
     {INDEX_NR_chmod,    __NR_chmod,    (int(*)())0,   my_chmod},
     {INDEX_NR_chown,    __NR_chown,    (int(*)())0,   my_chown},
     {INDEX_NR_unlink,   __NR_unlink,   (int(*)())0,   my_unlink},
     {INDEX_NR_execve,   __NR_execve,   (int(*)())0,   my_execve},
     {-1,           -1,       (int(*)())0,   (int(*)())0}
};
int nreplace_syscall = sizeof(replace_syscall)/sizeof(*replace_syscall)-1; 
void intercept_syscalls()
{
  int i, f;
  for(i = 0; i < nreplace_syscall; i++)
  {
    f = replace_syscall[i].index;
    replace_syscall[i].original = sys_call_table[f];
    sys_call_table[f] = replace_syscall[i].seos_syscall;
  }
}

Example 8: my_open() example

asmlinkage int my_open(const char* fname, int fmode, int mode)
{
  int access, rv;
  /* some processing */
  rv = replace_syscall[INDEX_NR_open].original(fname, fmode, mode);
  return rv;
}


3


