0

Firstly, I've create a simple program in 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);

It runs properly. However, when I move this code to Linux kernel, it seems to fail to work

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

The problem comes from following code

for(i=0;i < strlen(str); i++)
    str[i] -= 13; //rot13

Because if it's removed, program runs as original case. Did I miss something here?

4

3 回答 3

2

问题:sizeof(text)返回指针的大小,而不是指向的字符串的长度text。还要记住,所有字符串都有一个终止字符串的额外字符。这一切都意味着您在分配的内存之外进行写入和读取,这是未定义的行为,这意味着任何事情都可能发生。

此外,文字字​​符串实际上是常量 ( const char *)。

最后,您可能想了解ROT13,因为您所做的不是ROT13 加密。

于 2013-10-04T11:44:33.417 回答
1

您还没有str以 a终止,'\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
于 2013-10-04T11:41:01.537 回答
0

如果您正在处理字符串,请尝试使用 strncpy() 而不是 memcpy。'因为它将自动在末尾放置一个 NULL 字符,并且您可以安全地避免缓冲区溢出。但在这种情况下,我不太确定问题到底是什么,除非您提供有关该问题的更多详细信息。

对于任何内核编程错误,关键是添加调试/打印并尽可能多地收集有关正在发生的事情的数据。如果那不能帮助您调试自己,那将帮助其他人更好地帮助您。

于 2013-10-04T12:02:45.233 回答