'BUG: scheduling while atomic' 和 crypto_alloc_hash
'BUG: scheduling while atomic' with crypto_alloc_hash
我正在尝试使用 Linux 内核的加密库来计算给定密钥和消息的 HMAC 值。这个想法是计算 HMAC 并在 iperf 会话期间将其插入 TCP 选项(这部分不相关)。
这是我为使用加密库而编写的函数,它需要两个 8 字节的密钥(要组合)和组成消息的可变字节数:
void crypto_hmac_sha1(u8 *key_1, u8 *key_2, u32 *hash_out, int arg_num, ...)
{
struct crypto_ashash *shash;
struct shash_desc *desc = NULL;
const char hmac_alg[] = "hmac(sha1)";
u8 key[16];
int i;
int ret;
int length;
u8 *msg;
va_list list;
/* Initialize result placeholder */
memset(hash_out, 0, sizeof(hash_out));
for (i = 0; i < 8; i++)
key[i] ^= key_1[i];
for (i = 0; i < 8; i++)
key[i + 8] ^= key_2[i];
printk("A1\n");
shash = crypto_alloc_ahash(hmac_alg, 0, 0);
printk("A2\n");
desc = kzalloc(sizeof(*desc) + crypto_shash_descsize(shash), GFP_KERNEL);
if (!desc)
goto out;
desc->tfm = shash;
desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
ret = crypto_shash_setkey(shash, key, 16);
if (ret < 0)
goto out;
crypto_shash_init(desc);
for (i = 0; i < arg_num; i++) {
length = va_arg(list, int);
msg = va_arg(list, u8 *);
ret = crypto_shash_update(desc, msg, length);
if (ret < 0)
goto out;
}
ret = crypto_shash_final(desc, hash_out);
out:
kfree(desc);
}
错误如下(由于 crypto_alloc_ahash 试图获取信号量,但在当前上下文中是不允许的):
BUG: scheduling while atomic: iperf/769/0x00000100
CPU: 0 PID: 769 Comm: iperf Not tainted 4.1.0-gdee0521-dirty #143
Received SIGSEGV in SIGSEGV handler, aborting stack trace!
修复建议?
在不熟悉加密库的情况下:如果您对 crypto_hmac_sha1
的并发执行数有一个上限,则可以使用预先分配的哈希算法结构池。鉴于 scheduling/sleeping 似乎是不允许的,这样的界限应该不难找到:硬件线程的数量会做到这一点。
此外,如果不允许安排,CRYPTO_TFM_REQ_MAY_SLEEP
似乎很可疑。
我正在尝试使用 Linux 内核的加密库来计算给定密钥和消息的 HMAC 值。这个想法是计算 HMAC 并在 iperf 会话期间将其插入 TCP 选项(这部分不相关)。 这是我为使用加密库而编写的函数,它需要两个 8 字节的密钥(要组合)和组成消息的可变字节数:
void crypto_hmac_sha1(u8 *key_1, u8 *key_2, u32 *hash_out, int arg_num, ...)
{
struct crypto_ashash *shash;
struct shash_desc *desc = NULL;
const char hmac_alg[] = "hmac(sha1)";
u8 key[16];
int i;
int ret;
int length;
u8 *msg;
va_list list;
/* Initialize result placeholder */
memset(hash_out, 0, sizeof(hash_out));
for (i = 0; i < 8; i++)
key[i] ^= key_1[i];
for (i = 0; i < 8; i++)
key[i + 8] ^= key_2[i];
printk("A1\n");
shash = crypto_alloc_ahash(hmac_alg, 0, 0);
printk("A2\n");
desc = kzalloc(sizeof(*desc) + crypto_shash_descsize(shash), GFP_KERNEL);
if (!desc)
goto out;
desc->tfm = shash;
desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
ret = crypto_shash_setkey(shash, key, 16);
if (ret < 0)
goto out;
crypto_shash_init(desc);
for (i = 0; i < arg_num; i++) {
length = va_arg(list, int);
msg = va_arg(list, u8 *);
ret = crypto_shash_update(desc, msg, length);
if (ret < 0)
goto out;
}
ret = crypto_shash_final(desc, hash_out);
out:
kfree(desc);
}
错误如下(由于 crypto_alloc_ahash 试图获取信号量,但在当前上下文中是不允许的):
BUG: scheduling while atomic: iperf/769/0x00000100
CPU: 0 PID: 769 Comm: iperf Not tainted 4.1.0-gdee0521-dirty #143
Received SIGSEGV in SIGSEGV handler, aborting stack trace!
修复建议?
在不熟悉加密库的情况下:如果您对 crypto_hmac_sha1
的并发执行数有一个上限,则可以使用预先分配的哈希算法结构池。鉴于 scheduling/sleeping 似乎是不允许的,这样的界限应该不难找到:硬件线程的数量会做到这一点。
此外,如果不允许安排,CRYPTO_TFM_REQ_MAY_SLEEP
似乎很可疑。