修改Linux内核中的指针值

时间:2013-10-04 11:38:29

标签: c pointers memory-management linux-kernel encryption

首先,我在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

因为如果将其删除,程序将作为原始案例运行。我在这里错过了什么吗?

3 个答案:

答案 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,并且你可以安全地缓冲运行。但在这种情况下,我不太确定究竟是什么问题,除非你提供有关该问题的更多细节。

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