Is there a way to access and change user data from a system call in Minix 3? Can I use sys_datacopy () here? Why is my attempt not working?

I want to implement syscall on a PM server on Minix, which has access to some data in user space and can change it.

I pass data to syscall using the Minix messaging engine. In the message structure that is being passed, I assign one of the pointers to the address of the variable from the user space that I want to pass.

For example, in a user program

 message m; m.m1_p1 = &var; //data to be passed //pass it to the syscall 

In the kernel, in the syscall function, I do

 char *ptr = m_in.m1_p1; 

However, when I try to either read or write data, I get an error message that the kernel has panicked and requires a reboot.

I understand that this is probably because user space uses user-specific virtual addresses that are not recognized in syscall.

Looking for further, I found that Linux has the functions copy_from_user() and copy_to_user() to achieve this.

Is there an equivalent to this minix? If not, is there any other way to achieve this?


Using the @osgx suggestion in the comments, I tried using sys_datacopy() . Although this allows me to read and write data in a system call, the changes I make are not reflected back to the user program that calls the system call.

My last attempt is as follows:

In user program

 message m; m.m1_p1 = &var; //data to be passed printf("%c\n",*(m.m1_p1)); //gives the value in var //pass it to the syscall printf("%c\n",var); //gives the old value of var 

Inside syscall,

 char *ptr = (char*)malloc(sizeof(char)); sys_datacopy(who_e,(vir_bytes)(m_in.m1_p1),SELF,(vir_bytes)(ptr),sizeof(char*)); //or some other version of sys_vircopy()? printf("Read value of ptr : %c\n",*ptr); //gives correct value *ptr = //new value printf("New value of ptr : %c\n",*ptr); //gives modified value 

Here now I can access the var value inside syscall with ptr and change it inside syscall. However, after returning from syscall, I noticed that the base value of `var 'has not changed.

According to my understanding, what was supposed to happen was that sys_datacopy() was supposed to copy the equivalent virtual object m_in.m1_p1 , which is in the syscall address space on ptr , which points to the same physical address. Thus, *ptr must exactly reach var , thereby changing it.

Or is it that the data corresponding to the address is copied when I use sys_datacopy() ? If so, one solution that I can think of is to define a message structure that allows double pointers and passes char** to syscall. Then dereferencing will ensure that the address is copied to ptr . But again, dereferencing ptr will try to dereference a virtual address belonging to the address space of a user process that will not work.

Why does this method not work? What is the right way to achieve this?

I am using Minix 3.2.1.

Thanks.

+5
source share

Source: https://habr.com/ru/post/1265286/


All Articles