5

I want to implement a syscall in the PM server in Minix that has access to some data in the user space, and can modify it.

I am passing data to the syscall using Minix's message passing mechanism. 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 the 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 the data, I get an error that the kernel has panicked, and needs a reboot.

I realise that this is probably because in user space, virtual addresses specific to the user are being used, which is not recognizable in the syscall.

On searching further, I found that Linux has functions copy_from_user() and copy_to_user() to achieve this.

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


With the help of @osgx's suggestion in the comments, I have tried using sys_datacopy(). While this allows me to read and write the data in the system call, the changes I make are not reflected back into the user program that called the system call.

My latest attempt is as follows:

In the 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 the 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 value of var inside the syscall using ptr, and modify it inside the syscall as well. However, after returning from the syscall, I observe that the underlying value of `var' has not changed.

As per my understanding, what should have happened is that the sys_datacopy() should have copied an equivalent virtual of m_in.m1_p1 that lies in the address space of the syscall to ptr, that points to the same physical address. So, *ptrshould exactly reach var, thus modifying it.

Or is it that the data corresponding to the address is copied, when I use sys_datacopy()? If this is the case, one solution I can think of is defining a message structure that allows double pointers, and passing an char** to the syscall. Then, dereferencing once will ensure that the address is copied to ptr. But then again, dereferencing ptr will attempt to dereference a virtual address that belongs to the user process's address space, which will not work.

Why is this method not working? What is the correct way to achieve this?

I am using Minix 3.2.1.

Thank you.

Community
  • 1
  • 1
GoodDeeds
  • 7,956
  • 5
  • 34
  • 61
  • 1
    Can functions of `minix/include/minix/syslib.h` named `sys_datacopy` or `sys_copy` help you? datacopy [is used in VFS](http://code.metager.de/source/s?refs=sys_datacopy_wrapper&project=minix), possibly to implement `read` & `write` syscalls, here is the wrapper http://code.metager.de/source/xref/minix/minix/servers/vfs/utility.c#139. Also, are you sure to implement syscall in kernel, not in server? There are also sys_safecopyfrom / ..to / sys_vsafecopy listed at http://wiki.minix3.org/doku.php?id=developersguide:kernelapi & http://condor.depaul.edu/glancast/443class/docs/lecOct05.html#slide21 – osgx Mar 14 '17 at 00:09
  • 1
    @osgx Thank you. I came across these functions after I had posted this. They appeared highly relevant, but I could not find any example regarding their usage. I actually came across `SYS_SAFECOPYFROM` and `SYS_SAFECOPYTO`, which needed a grant id. I read about memory grants, but again, couldn't figure out how to implement them and couldn't find any examples either. I am implementing the syscall in a server. I am new to this, so sorry if I have used incorrect terms. What I assumed was that a syscall runs in kernel mode, especially when the kernel panicked when there was any error in there... – GoodDeeds Mar 14 '17 at 06:36
  • 1
    @osgx ... `sys_datacopy` seems very useful. But I am not able to understand its usage. Could you please direct me to, or provide an, example that would make this clearer? Thank you. – GoodDeeds Mar 14 '17 at 06:37
  • 1
    I'm don't understand anything of Minix & its demons services, but +50 rep is +50 rep. Did you try to start from some manual like "implementing syscall for minix"? Some manuals may have useful ideas of transmitting data and may mention sys_datacopy, sys_copy, sys_vsafecopy, sys_safecopyfrom. Another source of knowlendge is source of minix services in x-ref systems like metager.de – osgx Mar 14 '17 at 06:48
  • 1
    @osgx Thank you for your suggestions, I have tried them, and updated my question. – GoodDeeds Mar 14 '17 at 09:21
  • I cannot give you a closed solution but at last some thoughts: In kernel you do/might have access to the physical memory of your machine. Every process should have it's own mapping from virtual to physical memory address (kernel might have a mapping as well, but that would usually be 1:1). So you should at last be able to map an address by yourself by accessing the process memory map. Whatever functions you are looking for should do exactly that for you. – RuDevel Mar 18 '17 at 20:31
  • You should read [the documentation about grants (safecopies)](http://wiki.minix3.org/doku.php?id=developersguide:memorygrants) to see if it fits your use case. – AntoineL Apr 24 '17 at 16:33

0 Answers0