Reputation: 51
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?
Upvotes: 0
Views: 670
Reputation: 1146
If you are dealing with strings try using strncpy() instead of memcpy. 'coz that will put a NULL char at the end automatically and you are safe from buffer over runs. But in this case, i'm not very sure what exactly is the problem, unless you give more details about the issue.
And for any kernel programming errors, the key is to add debugs/printks and collect as much as data about what is happening. If thats not helping you debug yourself, that will help others to help you better.
Upvotes: 0
Reputation: 409206
The problem: sizeof(text)
returns the size of the pointer, and not the length of the string text
points to. Also remember that all string have an extra character that terminates the string. This all means that you write to, and read from, beyond the memory you allocated, and that is undefined behavior which means anything could happen.
Also, literal strings are actually constant (const char *
).
And lastly, you might want to read about ROT13, as what you're doing is not ROT13 encryption.
Upvotes: 2
Reputation: 212979
You haven't terminated str
with a '\0'
so you're most likely just running off the end of the buffer and stomping over memory.
Change:
str = kmalloc(len, GFP_KERNEL);
to:
str = kmalloc(len + 1, GFP_KERNEL); // allocate additional char for terminator
and change:
memcpy(str, log->buf + read->off, len);
to:
memcpy(str, log->buf + read->off, len);
str[len] = '\0'; // put terminator at end of string
Upvotes: 1