mac80211模块上的rmmod崩溃了

时间:2014-10-08 18:46:13

标签: c linux-kernel cryptography wireless cryptographic-hash-function

mac80211模块上的rmmod(我在ieee80211_init()中的更改)是 崩溃。我在ieee80211_exit()中没有任何变化。但是,在ieee80211_exit()上发现了一个崩溃,用于释放网格表tbl。为什么我的init函数更改会导致退出函数出现问题?没有 我的更改,卸载模块没有问题。

如果我注释掉语句来调用hmac_sha512(),那么 rmmod成功了。如果我将此代码集成到自定义模块中 您好,那么rmmod没有问题。如果是同步 问题,那么Hello模块怎么没有问题? 我已经粘贴了函数的代码,hmac_sha512()和其他相关函数。 我也尝试过同步API。即便如此,同样的问题也是可以重现的。

深入了解mac80211的功能,发现问题是由网格表de-引起的 分配。在解除分配之前,必须通过ieee80211s_start()分配Mesh表以获得de- 分配ieee80211s_stop()。已将日志放入代码中以检查谁从mac80211分配网格表;根据日志,mac80211中没有人(包括HMAC代码)分配网格表。

如果我从ieee80211_exit()注释掉下面的行,rmmod工作正常:

/*

If(mesh_allocated)
    ieee80211_stop;

*/

请提供解决此问题的一些指示。

#define HMAC_SHA512_SIZE 64

struct hmac_sha512_result {
    struct completion completion;
    int err;
};

static void hmac_sha512_complete(struct crypto_async_request *req, int err) {
    struct hmac_sha512_result *r=req->data;
    if(err==-EINPROGRESS)
        return;
    r->err=err;
    complete(&r->completion);
}

int hmac_sha512(const unsigned char *key, // key 
                         const unsigned char *data_in, // data in
                        unsigned char *hash_out, size_t outlen) {  // hash buffer and length

    int rc=0;
    struct crypto_ahash *tfm;
    struct scatterlist sg;
    struct ahash_request *req;
    struct hmac_sha512_result tresult;
    void *hash_buf;
        size_t klen = strlen(key);
        size_t dlen = strlen(data_in); 

        int len = HMAC_SHA512_SIZE;
        char hash_tmp[HMAC_SHA512_SIZE];
    char *hash_res = hash_tmp;

        printk(KERN_INFO "hmac_sha512: HMAC key is %s ", key);

    /* Set hash output to 0 initially */
    memset(hash_out, 0, outlen);

    init_completion(&tresult.completion);
    tfm=crypto_alloc_ahash("hmac(sha512)",0,0);
    if(IS_ERR(tfm)) {
        printk(KERN_ERR "hmac_sha512: crypto_alloc_ahash failed.\n");
        rc=PTR_ERR(tfm);
        goto err_tfm;
    }
    if(!(req=ahash_request_alloc(tfm,GFP_KERNEL))) {
        printk(KERN_ERR "hmac_sha512: failed to allocate request for hmac(sha512)\n");
        rc=-ENOMEM;
        goto err_req;
    }
    if(crypto_ahash_digestsize(tfm)>len) {
        printk(KERN_ERR "hmac_sha512: tfm size > result buffer.\n");
        rc=-EINVAL;
        goto err_req;
    }
    ahash_request_set_callback(req,CRYPTO_TFM_REQ_MAY_BACKLOG,
                    hmac_sha512_complete,&tresult);

    if(!(hash_buf=kzalloc(dlen,GFP_KERNEL))) {
        printk(KERN_ERR "hmac_sha512: failed to kzalloc hash_buf");
        rc=-ENOMEM;
        goto err_hash_buf;
    }
    memcpy(hash_buf,data_in,dlen);
    sg_init_one(&sg,hash_buf,dlen);

    crypto_ahash_clear_flags(tfm,-0);
    if((rc=crypto_ahash_setkey(tfm,key,klen))){
        printk(KERN_ERR "hmac_sha512: crypto_ahash_setkey failed\n");
        goto err_setkey;
    }
    ahash_request_set_crypt(req,&sg,hash_res,dlen);
    rc=crypto_ahash_digest(req);
    switch(rc) {
        case 0:
            while (len--) {
                snprintf(hash_out, outlen, "%02x", (*hash_res++ & 0x0FF));
                hash_out += 2;
            }

                break;
        case -EINPROGRESS:
        case -EBUSY:
            rc=wait_for_completion_interruptible(&tresult.completion);
            if(!rc && !(rc=tresult.err)) {
                INIT_COMPLETION(tresult.completion);
                break;
            } else {
                printk(KERN_ERR "hmac_sha512: wait_for_completion_interruptible failed\n");
                goto out;
            }
        default:
            goto out;
    }

    out:
    err_setkey:
        kfree(hash_buf);
    err_hash_buf:
        ahash_request_free(req);
    err_req:
        crypto_free_ahash(tfm);
    err_tfm:
        return rc;
}

0 个答案:

没有答案