hashing file in security hook

From: rjf (itripn@private)
Date: Thu Jun 02 2005 - 19:39:39 PDT


This may border on off topic, and I would be pleased to be pointed
elsewhere if so...

I am attempting to write an lsm that hashes as part of the
bprm_check_security hook. The trouble I am having is trying to read
and hash the file. I have successfully used the kernel crytpo code to
hash a static buffer, to make sure I understood its usage, and have
now moved on to actually trying to open and read the file being passed
to the hook. My module causes a kernel exception with this message in
the syslog:

Jun  2 09:36:36 foo Unable to handle kernel paging request at virtual
address c6000000

I'll be the first to admit I don't know what the hell I am doing, as
this is my first foray into kernel code. Below is the code for the
helper function in question, which is being called like so from the
hook:

 hashFile(bprm->filename, "sha1", bprm->file );

And the helper function:

static void hashFile(char *filename, char *algo, struct file *file) {

  struct scatterlist sg[1];
  char result[64];
  struct crypto_tfm *tfm;

  // alloc a buffer
  void *m = kmalloc(1024, GFP_KERNEL);
  if ( !m ) {
    printk("failed to alloc buffer...\n");
    return;
  }

  // init crypto
  tfm = crypto_alloc_tfm(algo, 0);
  if (tfm == NULL) {
    printk("failed to load transform for %s\n", algo);
    return;
  }
  crypto_digest_init (tfm);

  // init scatterlist -- the first two fields shouldn't change
  // since we read into the same buffer each time.
  sg[0].page = virt_to_page (m);
  sg[0].offset = offset_in_page (m);
  sg[0].length = 0;

  // loop reading the file a buffer at a time, updating the hash.
  int bytesRead = 0;
  int ret = file->f_op->open( file->f_mapping->host, file );
  if ( ret == 0 ) {
    do {

      bytesRead = file->f_op->read(file, m, 1024, &file->f_pos);
      sg[0].length = bytesRead;
      crypto_digest_update (tfm, sg, 1);

    } while (bytesRead == 1024);

    // cleanup
    file->f_op->release(file->f_mapping->host, file);
    crypto_digest_final(tfm, result);

    // log the hash to the syslog
    hexdump(filename, result, crypto_tfm_alg_digestsize (tfm));
  }
  else
    printk("failed to open file: %s (%d)\n", filename, ret);

  kfree(m);
}


Thanks,
-- 
rjf&



This archive was generated by hypermail 2.1.3 : Thu Jun 02 2005 - 20:27:49 PDT