stela
stela

Reputation: 51

Modify pointer value in Linux kernel

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

Answers (3)

joe
joe

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

Some programmer dude
Some programmer dude

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

Paul R
Paul R

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

Related Questions