首先,我在C
中创建了一个简单的程序unsigned char * text ="Test program";
int _size = strlen(text);
unsigned char * str = malloc(sizeof(text));
memcpy(str, text, _size);
printf("Before(%d): %s\n", _size, str);
for(i=0;i < _size; i++) {
str[i] -= 13; //rot13
}
printf("After: (%d): %s\n", strlen(str), str);
运行正常。但是,当我将此代码移动到Linux内核时,似乎无法正常工作
unsigned char * str;
len = min(count, log->size - read->off);
/* Allocate the memory for storing plain text */
str = kmalloc(len, GFP_KERNEL);
if(str == NULL) {
printk(KERN_ERR "logger: failed to allocate buffer\n");
return -ENOMEM;
}
memcpy(str, log->buf + read->off, len);
/* Start: Add a simple rot13 encryption here */
for(i=0;i < strlen(str); i++)
str[i] -= 13; //rot13
/* End: Add a simple rot13 encryption here */
if (copy_to_user(buf, str, len))
return -EFAULT;
if(str != NULL) {
kfree(str);
}
问题来自以下代码
for(i=0;i < strlen(str); i++)
str[i] -= 13; //rot13
因为如果将其删除,程序将作为原始案例运行。我在这里错过了什么吗?
答案 0 :(得分:2)
问题:sizeof(text)
返回指针的大小,而不是字符串text
指向的长度。还要记住,所有字符串都有一个额外的字符来终止字符串。这意味着你在你分配的内存之外写入和读取,这是未定义的行为,这意味着任何事情都可能发生。
此外,文字字符串实际上是常量(const char *
)。
最后,您可能想了解ROT13,因为您正在做的是而不是 ROT13加密。
答案 1 :(得分:1)
您没有使用str
终止'\0'
,因此您很可能只是在缓冲区的末尾运行并踩踏内存。
变化:
str = kmalloc(len, GFP_KERNEL);
为:
str = kmalloc(len + 1, GFP_KERNEL); // allocate additional char for terminator
并改变:
memcpy(str, log->buf + read->off, len);
为:
memcpy(str, log->buf + read->off, len);
str[len] = '\0'; // put terminator at end of string
答案 2 :(得分:0)
如果您正在处理字符串,请尝试使用strncpy()而不是memcpy。 'coz会自动在结尾处放置一个NULL char,并且你可以安全地缓冲运行。但在这种情况下,我不太确定究竟是什么问题,除非你提供有关该问题的更多细节。
对于任何内核编程错误,关键是添加调试/打印并收集与正在发生的事情有关的数据。如果这不能帮助您调试自己,那将有助于其他人更好地帮助您。