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