ループバックデバイスのCRYPT2


crypt type=12として、write時++1/read時--1とするloop transferのlkmサンプルです。hogeloop_funcsのinitは、loop_register_transfer()、releaseはloop_unregister_transfer()でコールされ、initは暗号等必要な初期化処理また掛かる動的なメモリの取得等の処理を行う場合に、releaseは動的メモリの解放等の処理で使用することが想定されます。サンプルはreturn 0としています。不必要ならNULLとし定義する必要はありません。
#include <linux/module.h>
#include <linux/loop.h>

#define         LO_HOGECRYPT    12

static int hogeloop_transfer(struct loop_device *lo, int cmd,
                       struct page *raw_page, unsigned raw_off,
                       struct page *loop_page, unsigned loop_off,
                       int size, sector_t real_block)
{
       char *raw_buf = kmap_atomic(raw_page, KM_USER0) + raw_off;
       char *loop_buf = kmap_atomic(loop_page, KM_USER1) + loop_off;
       char *in, *out;

       int i;

       if (cmd == READ) {
               in = raw_buf;
               out = loop_buf;
       } else {
               in = loop_buf;
               out = raw_buf;
       }

       for (i = 0; i < size; i++) {
               if (cmd == READ) {
                       *out++ = *in++ - 1;
               }
               else {
                       *out++ = *in++ + 1;
               }
       }
       kunmap_atomic(loop_buf, KM_USER1);
       kunmap_atomic(raw_buf, KM_USER0);
       return 0;
}

static int
hogeloop_init(struct loop_device *lo, const struct loop_info64 *info)
{
      return 0;
}

static int
hogeloop_release(struct loop_device *lo)
{
       return 0;
}

static struct loop_func_table hogeloop_funcs = {
       .number = LO_HOGECRYPT,
       .init = hogeloop_init,
       .transfer = hogeloop_transfer,
       .release = hogeloop_release,
       .owner = THIS_MODULE
};

static int __init
init_hogeloop(void)
{
       int rc = loop_register_transfer(&hogeloop_funcs);

       if (rc)
               printk("hogeloop register failed\n");
       return rc;
}

static void __exit
exit_hogeloop(void)
{
       if (loop_unregister_transfer(LO_HOGECRYPT))
               printk("hogeloop unregister failed\n");
}

module_init(init_hogeloop);
module_exit(exit_hogeloop);
サンプルをinsmodし、/dev/loop0にdiskをバインド、cryptをLO_HOGECRYPTとします。
[root@localhost lkm]# insmod hogeloop.ko
[root@localhost lkm]# dd if=/dev/zero of=disk bs=1M count=1
[root@localhost lkm]# losetup /dev/loop0 disk
[root@localhost lkm]# ./loopcrypt set /dev/loop0
[root@localhost lkm]# ./loopcrypt show /dev/loop0
lo_encrypt_type:12
lo_encrypt_key:hoge
diskに書き込まれたデータは元データ++となりますが、/dev/loop0は元データとして参照しています。
[root@localhost lkm]# echo 12345 > /dev/loop0
[root@localhost lkm]# cat /dev/loop0
12345
ddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
  :

[root@localhost lkm]# cat disk
23456
    eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
  :

補足

crypt typeはlosetupの-Eオプションで設定できるらしいのですが、crypt名称もチェックしているのかlosetupコマンドで設定できませんでした。loopinfo.lo_encrypt_typeにtypeナンバーを設定すればいいだけの事ですので、オリジナルのloopcryptコマンドとして無理やり設定しています。なお、encrypt_keyをhogeとしていますが、サンプルでは使用していません。
#include "stdio.h"
#include <fcntl.h>
#include <string.h>

typedef unsigned short  __kernel_old_dev_t;
#define LO_NAME_SIZE    64
#define LO_KEY_SIZE     32

struct loop_info {
       int                lo_number;           /* ioctl r/o */
       __kernel_old_dev_t lo_device;           /* ioctl r/o */
       unsigned long      lo_inode;            /* ioctl r/o */
       __kernel_old_dev_t lo_rdevice;          /* ioctl r/o */
       int                lo_offset;
       int                lo_encrypt_type;
       int                lo_encrypt_key_size;         /* ioctl w/o */
       int                lo_flags;                    /* ioctl r/o */
       char               lo_name[LO_NAME_SIZE];
       unsigned char      lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
       unsigned long      lo_init[2];
       char               reserved[4];
};

#define LOOP_SET_STATUS         0x4C02
#define LOOP_GET_STATUS         0x4C03

void show_crypt();
void set_crypt();
int     get_cmd(char *cmd);

void    main(int argc, char *argv[])
{
       if (argc == 3 ) {
               switch (get_cmd(argv[1])) {
                       case 0:
                               show_crypt(argv[2]);
                               break;
                       case 1:
                               set_crypt(argv[2]);
                               break;
                       default:
                               printf("cmd err\n");
                               break;
               }
       }
       else {
               printf("param err\n");
       }
}

int     get_cmd(char *cmd)
{
       int     ans = -1;
       if (!strcmp(cmd, "show")) {
               ans = 0;
       }
       if (!strcmp(cmd, "set")) {
               ans = 1;
       }
       return ans;
}

void set_crypt()
{
       struct loop_info loopinfo;
       int fd;

       if ((fd = open ("/dev/loop0", O_RDONLY)) < 0) {
               fprintf(stderr, "can't open device\n");
               return;
       }

       if (ioctl (fd, LOOP_GET_STATUS, &loopinfo) < 0) {
               fprintf(stderr, "can't get info\n");
               close (fd);
               return;
       }

       loopinfo.lo_encrypt_type = 12;
       loopinfo.lo_encrypt_key_size = 4;
       strncpy(loopinfo.lo_encrypt_key, "hoge", 4);
       if (ioctl (fd, LOOP_SET_STATUS, &loopinfo) < 0) {
               fprintf(stderr, "can't set info\n");
       }
       close (fd);
}

void show_crypt()
{
       struct loop_info loopinfo;
       int fd, i;

       if ((fd = open ("/dev/loop0", O_RDONLY)) < 0) {
               fprintf(stderr, "can't open device\n");
               close (fd);
               return;
       }

       if (ioctl (fd, LOOP_GET_STATUS, &loopinfo) < 0) {
               fprintf(stderr, "can't get info\n");
               close (fd);
               return;
       }
       printf("lo_encrypt_type:%d\n", loopinfo.lo_encrypt_type);
       printf("lo_encrypt_key:");
       for (i = 0; i < loopinfo.lo_encrypt_key_size; i++) {
               putchar(loopinfo.lo_encrypt_key[i]);
       }
       putchar('\n');
       close (fd);
}


最終更新 2014/12/18 20:38:33 - north
(2014/12/18 20:36:57 作成)


検索

アクセス数
3676068
最近のコメント
コアダンプファイル - sakaia
list_head構造体 - yocto_no_yomikata
勧告ロックと強制ロック - wataash
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
Adsense
広告情報が設定されていません。