Re: hashing file in security hook

From: rjf (itripn@private)
Date: Thu Jun 02 2005 - 22:15:38 PDT


On 6/2/05, rjf <itripn@private> wrote:
> Dang, I sent this a little too early... I meant to point out that the
> read() call is returning -14, which I believe is EFAULT. I think the

And just to go ahead and wrap the thread up... grin... After about 90
minutes of googling, I came up with the right set of terms to find
this page:

http://www.daimi.au.dk/~kasperd/comp.os.linux.development.faq.html#filp_open

Which led to the following, operational, version of my kernel module
file hashing 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
  unsigned long page = __get_free_page(GFP_KERNEL);
  if ( !page ) {
    printk("failed to alloc buffer...\n");
    return;
  }
  char *m = (char*)page;

  // 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;

  mm_segment_t orgfs = get_fs();
  set_fs( KERNEL_DS );

  // 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, PAGE_SIZE, &file->f_pos);
      if ( bytesRead > 0 ) {
        sg[0].length = bytesRead;
        crypto_digest_update (tfm, sg, 1);
      }
      else
        printk("failed to read: %d\n", bytesRead);

    } while (bytesRead == PAGE_SIZE);

    // 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);

  free_page(page);
  set_fs(orgfs);

}


-- 
rjf&



This archive was generated by hypermail 2.1.3 : Thu Jun 02 2005 - 23:35:34 PDT