Hi All,
I want to encrypt the data before it is written to the disk and decrypt is after it is being read from the disk. so copied the ext2 source code in my directory.
Then modified the ext2 file_operations structure to invoke my read and write functions instead of do_sync_read/write
const struct file_operations ext2_file_operations = {
.llseek = generic_file_llseek,
.read = my_read, /* do_sync_read */ <<<<<<<<<<<<<<<<<<<<<<<<
.write = my_write, /* do_sync_write */ <<<<<<<<<<<<<<<<<<<<<<<<
.aio_read = generic_file_aio_read,
.aio_write = generic_file_aio_write,
.unlocked_ioctl = ext2_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = ext2_compat_ioctl,
#endif
.mmap = generic_file_mmap,
.open = generic_file_open,
.release = ext2_release_file,
.fsync = ext2_sync_file,
.splice_read = generic_file_splice_read,
.splice_write = generic_file_splice_write,
};
For time being i used simplest encryption XOR 5
int encrypt_data(char *data, size_t len)
{
int i;
for(i=0; i < len; i++)
data[i] ^= 5;
return 0;
}
int decrypt_data(char *data, size_t len)
{
int i;
for(i=0; i < len; i++)
data[i] ^= 5;
return 0;
}
ssize_t my_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
{
size_t ret;
char *data = "" GFP_KERNEL);
ret = do_sync_read(filp, data, len, ppos);
decrypt_data(data, len);
copy_to_user(buf, data, len);
kfree(data);
return ret;
}
In write I am supposed to encrypt the data before it is written to the disk, ie encrypt the data before it is passed to the do_sync_write.
But, the data is in the buf which is passed from the user process and has the type const char *buf so I can't modify the buf
I thought of copying data from the (userland) buf to some variable in the kernelspace and then encrypt it and pass to do_sync_write()
This is what I did
ssize_t my_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
{
size_t ret;
char *data = "" GFP_KERNEL);
copy_from_user(data, buf, len);
encrypt_data(data, len);
ret = do_sync_write(filp, data, len, ppos);
kfree(data);
return ret;
}
After running the code and writing data to the file using echo "test" > /mnt_pt/file I am getting bad address error
Is it because do_sync_write() also expects buf pointer from the userspace?
ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
But, the only thing do_sync_write should be concerned with whether it can access the data pointer or not. So, if the data pointer is valid and kernel is able to access the location why so worry about userspace pointer?
Thanks and Regards,
Prasad
I want to encrypt the data before it is written to the disk and decrypt is after it is being read from the disk. so copied the ext2 source code in my directory.
Then modified the ext2 file_operations structure to invoke my read and write functions instead of do_sync_read/write
const struct file_operations ext2_file_operations = {
.llseek = generic_file_llseek,
.read = my_read, /* do_sync_read */ <<<<<<<<<<<<<<<<<<<<<<<<
.write = my_write, /* do_sync_write */ <<<<<<<<<<<<<<<<<<<<<<<<
.aio_read = generic_file_aio_read,
.aio_write = generic_file_aio_write,
.unlocked_ioctl = ext2_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = ext2_compat_ioctl,
#endif
.mmap = generic_file_mmap,
.open = generic_file_open,
.release = ext2_release_file,
.fsync = ext2_sync_file,
.splice_read = generic_file_splice_read,
.splice_write = generic_file_splice_write,
};
For time being i used simplest encryption XOR 5
int encrypt_data(char *data, size_t len)
{
int i;
for(i=0; i < len; i++)
data[i] ^= 5;
return 0;
}
int decrypt_data(char *data, size_t len)
{
int i;
for(i=0; i < len; i++)
data[i] ^= 5;
return 0;
}
ssize_t my_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
{
size_t ret;
char *data = "" GFP_KERNEL);
ret = do_sync_read(filp, data, len, ppos);
decrypt_data(data, len);
copy_to_user(buf, data, len);
kfree(data);
return ret;
}
In write I am supposed to encrypt the data before it is written to the disk, ie encrypt the data before it is passed to the do_sync_write.
But, the data is in the buf which is passed from the user process and has the type const char *buf so I can't modify the buf
I thought of copying data from the (userland) buf to some variable in the kernelspace and then encrypt it and pass to do_sync_write()
This is what I did
ssize_t my_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
{
size_t ret;
char *data = "" GFP_KERNEL);
copy_from_user(data, buf, len);
encrypt_data(data, len);
ret = do_sync_write(filp, data, len, ppos);
kfree(data);
return ret;
}
After running the code and writing data to the file using echo "test" > /mnt_pt/file I am getting bad address error
Is it because do_sync_write() also expects buf pointer from the userspace?
ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
But, the only thing do_sync_write should be concerned with whether it can access the data pointer or not. So, if the data pointer is valid and kernel is able to access the location why so worry about userspace pointer?
Thanks and Regards,
Prasad