Re: hashing file in security hook

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


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
reason for the kernel exception is that I pass that blindly to the
hash update call.

The root of the problem appears to be the read call, but I don't
understand what I am doing wrong there.

rjf&


On 6/2/05, rjf <itripn@private> wrote:
> 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&
> 


-- 
rjf&



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