1

I'm trying to code an encryption driver in Linux, but when I encrypt the string and copy it into the buffer by using copy_from_user() it doesn't work and the k value is the number of chars in the string

If I change the temp in copy_from_user to buf it work fine

ssize_t encdec_write_caesar(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
    char *temp ;
    temp = kmalloc(memory_size * sizeof(char),GFP_USER);
    memset(temp, 0, memory_size);

    int i , k ;

    k = ((encdec_private_date *)(filp->private_data))->key;
    for(i = 0; i < count; i++)
    {
        temp[i] = (buf[i] + k) % 128;
    }

    k = copy_from_user ( caesar_Buf , temp , count);
    printk("write-> %d\n"  ,k);

    kfree(temp);
    return 0;
 }

this is part of the code

#include <linux/ctype.h>
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/fcntl.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <linux/string.h>

#include "encdec.h"

#define MODULE_NAME "encdec"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("YOUR NAME");

int     encdec_open(struct inode *inode, struct file *filp);
int     encdec_release(struct inode *inode, struct file *filp);
int     encdec_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);

ssize_t encdec_read_caesar( struct file *filp, char *buf, size_t count, loff_t *f_pos );
ssize_t encdec_write_caesar(struct file *filp, const char *buf, size_t count, loff_t *f_pos);



int memory_size = 0;

MODULE_PARM(memory_size, "i");

int major = 0;
char *caesar_Buf = NULL;


struct file_operations fops_caesar = {
    .open    =  encdec_open,
    .release =  encdec_release,
    .read    =  encdec_read_caesar,
    .write   =  encdec_write_caesar,
    .llseek  =  NULL,
    .ioctl   =  encdec_ioctl,
    .owner   =  THIS_MODULE
};


// Implemetation suggestion:
// -------------------------
// Use this structure as your file-object's private data structure
typedef struct {
    unsigned char key;
    int read_state;
} encdec_private_date;

int init_module(void)
{
    major = register_chrdev(major, MODULE_NAME, &fops_caesar);
    if(major < 0)
    {
        return major;
    }



    caesar_Buf = (char *)kmalloc(memory_size * sizeof(char),GFP_KERNEL);



    return 0;
}

  • 2
    `it doesn't work` - how do you know that? How do you check that? – KamilCuk May 15 '19 at 13:34
  • 1
    can you provide the desired output and what's you actually get? – Yoni Newman May 15 '19 at 13:35
  • copy_from_user returns the number of chars that couldn't copy so when i run it the k value always equal to the char number in temp. but when i change temp with buf ,k equals 0. – Victor Hanna May 15 '19 at 13:39
  • 2
    Where and how is `caesar_Buf` defined? Where and how is `memory_size` defined. `sizeof(char)` is always `== 1` therefore `temp = kmalloc(memory_size ,GFP_USER);` is sufficient, _as long as_ `GPF_USER` _is defined somewhere._ ( Show them or indicate this information some how in the code, or in your post. It is not possible to answer the question without this type of information.) – ryyker May 15 '19 at 13:50
  • ``char *caesar_Buf = NULL;`` in the head and ``caesar_Buf = (char *)kmalloc(memory_size * sizeof(char),GFP_KERNEL);`` in the init_module func – Victor Hanna May 15 '19 at 13:58
  • `GFP_USER` is defined for for the `kmalloc()` – Victor Hanna May 15 '19 at 14:00
  • It would be more helpful to include the parts of your code where they are defined. Use [this guide](https://stackoverflow.com/help/reprex) to help you make the necessary edits to your question. – Das_Geek May 15 '19 at 14:10
  • i have add part of the code – Victor Hanna May 15 '19 at 14:29
  • Fix your code to do what? `copy_from_user` is doing exactly what it's supposed to do here; it's refusing to copy from kernel-space. `temp` is in kernel-space memory, so `copy_from_user` doesn't copy. `buf` is in user-space memory, so it does. – cha0site May 15 '19 at 14:39
  • i need to copy buf into temp and then do the encription on temp and save it into caesar_buf by using copy_from_user. – Victor Hanna May 15 '19 at 17:13

1 Answers1

1

You should be using copy_from_user instead of accessing buf directly (inside the loop, not when accessing temp (which is in kernel-space memory.)

copy_from_user is intended to ensure that to accesses in a user context only access user-space data -- i.e., that someone doesn't pass a pointer to kernel memory in a syscall and leaks data from the kernel somehow.

cha0site
  • 10,517
  • 3
  • 33
  • 51