memcpy() - unable to handle kernel NULL pointer dereference

51 Views Asked by At

I'm writing a kernel module and I need to return to the user a lot of data.

I have a linked list with log_list_head as head (and it is empty) and the function print_log() that transfers the log_list data to a string and stores it in buffer.

ssize_t my_read(struct file *filp, char *buff, size_t length, loff_t *offp)
{
    struct log_list *temp;
    char *buffer;
    buffer = (char *)kmalloc(1024 * sizeof(char), GFP_KERNEL);
    temp = log_list_head->next;

    while (temp != NULL) {
        print_log(temp->data, buffer);
        copy_to_user(buff, buffer, strlen(buffer));  // This is not correct

        temp = temp->next;
    }
    copy_to_user(buff, message, strlen(buffer));
    kfree(buffer);
    return 0;
}

I have 2 problems:

  1. The user doesn't get anything, after running print_log(buffer), it's empty
  2. I know that copy_to_user() doesnt work to print multiple lines. Is there a way to return string by string (I need to print it line by line) and I have been told that it can be very long?

I want to send the buffer to the user one at a time.

2

There are 2 best solutions below

2
stark On

Currently you are overwriting the user buff every time.

If you make buffer large enough to hold the maximum size of data + message, you can do it in one shot:

int i=0;
while (temp != NULL){
    print_log(temp->data, buffer+i);  //offset by amount already done
    i = strlen(buffer);
    temp=temp->next;
}
strcat(buffer, message);
copy_to_user(buff, buffer, strlen(buffer)+1);  // include terminator

It could be made more efficient if print_log kept track of the end of the buffer, but that's likely premature optimization.

0
Its me On

For future people who come here. The reason it didn't work is because i returned 0 and not buf length