How to convert size_t to char* in kernel C?

5.1k Views Asked by At

I use a size_t variable in my kernel module. when I want to write it to a file it must be cast to char* according to vfs_write signature:

extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *);

I use this function that uses vfs_write (I found it on internet):

int file_write(struct file *file, unsigned long long offset, unsigned 
char *data, unsigned int size) 
{
    mm_segment_t oldfs;
    int ret;

    oldfs = get_fs();
    set_fs(get_ds());

    ret = vfs_write(file, data, size, &offset);

    set_fs(oldfs);
    return ret;
}

the nbytes variable is size_t I try (char *) cast for convert nbytes to char* but the kernel immediately crashes. here is my code.

index_filename = "/home/rocket/Desktop/index_pool";
index_file = file_open(index_filename,O_WRONLY | O_CREAT, 0644);
if(index_file == NULL)
    printk(KERN_ALERT "index_file open error !!.\n");
else{
    // file_write(index_file, 0, nbytes, nbytes); => this crashs also
    file_write(index_file, 0, (char*) nbytes, 100);
    file_close(index_file);
}

Is there a way to safely convert size_t type to char * one in Kernel ?

2

There are 2 best solutions below

4
Chris Turner On BEST ANSWER

Of course it would crash - you're trying to write 100 bytes of whatever memory location nbytes is pointing at. Which because it isn't a pointer is extremely unlikely to be a valid area of memory. And even if it was, it might not be 100 bytes in size.

What you want to be passing instead to vfs_write is a pointer to nbytes. And the size of that would be sizeof(nbytes). So you'd call your wrapper function like this

file_write(index_file, 0, (char*) &nbytes, sizeof(nbytes));

That will write out the how ever many bytes that a size_t is at the memory location of nbytes

If you want to write out the value of nbytes, which is different to what you appear to be asking in the question, you need to store it in a string and pass that to your function like this:

char temp_string[20];
sprintf(temp_string,"%zu",nbytes);
file_write(index_file, 0, temp_string, strlen(temp_string));
0
Hadi shamqoli On

Is there a way to safely convert size_t type to char * one in Kernel ?

yes there is. you should use sprintf function in linux/kernel.h library

so you should do something like this:

sprintf(destination_char_star, "%zu", your_s_size_var);

be carefull you should allocate memory to char star if needed.