Skip to content

Adding SafePOSIX Implementation of Syscalls

Çağlar Doğan edited this page Nov 29, 2020 · 22 revisions

Development Cycle:

There are two main paths that can be taken in implementing a new system call, defined in the Native Client section. In both these paths, a system call is defined in Lind_GlibC.

GlibC (Lind_GlibC)

First, a file in Lind_GlibC/sysdeps/nacl/ named X.c should be created for a system call X. In this file, a function to implement the system call should be defined with the name __X. This definition should be followed by weak_alias (__X, X) to denote the reference. (Aditional references can also be added here)

This file's full path (sysdeps/nacl/X.c) should then be added to the override_list in make_sysd_rules.py to make sure that this function is used.

This __X function should reference a function that can call the NACL_SYSCALL function. Such functions can be implemented in either sysdeps/nacl/lind_syscalls.c or sysdeps/nacl/irt_syscalls.c (after being defined in the respective header files).

In lind_syscalls.c, the convention is to implement this function as lind_X after defining the function in the header file. Here, two parameters of type LindArg named in_args and out_args should be defined properly, and a NACL_SYSCALL directly targeting the lind_api should be carried out (for path 1).

For this path (path 1), a number should be assigned to a macro denoting the new system call. This macro should later be used as the first argument for NACL_SYSCALL(lind_api).

In irt_syscalls.c, the convention is to implement this function as nacl_irt_X after defining the function as *__nacl_irt_X in both the header and the .c file. This is followed by a devotion: __nacl_irt_X = nacl_irt_X at the bottom of irt_syscalls.c. These function are normally used to call NACL_SYSCALL with a custom system call name (for path 2) but can also be used as a relay to call the functions in lind_syscalls.c.

If a NACL_SYSCALL with a custom system call name is going to be used, the function should be defined nacl_syscalls.h after the propper assignment of the syscall number. (for path 2)

The functions defined in lind_syscalls.c and/or irt_syscalls.c (__nacl_irt_X and/or lind_X) should then be added to the GLIBC_PRIVATE part in Lind_GlibC/elf/Versions alongside other system calls to ensure their interception.

Native Client (native_client)

The changes needed to be done in the Native Client is completely dependent on the preferred development path:

1) Using native_client as a relay:

In this path, the NACL_SYSCALL(lind_api) reaches the NaClSysLindSyscall function in native_client/src/trusted/service_runtime/lind_syscalls.c file directly. In this function; the parameters are parsed and are combined with the cage_id. Then, the CallPythonFunc function in native_client/src/shared/platform/lind_platform.c is called with the proper parameters. This function carries out the RPC, directly relaying the system call number coming from GlibC to the RePy alongside the proper arguments format.

No changes are necessary for any of the files in Native Client for this path.

2) Implementing parts of the system call in native_client:

This path will be explained in the upcoming version of this wiki page.

Repy + SafePOSIX:

This file is where RPC is accepted and syscalls are delivered to the dispatcher. Have the new syscall included here:

  • nacl_repy/seattlelib/lind_server.mix

To match the syscall with its Lind implementation, add a new pairing here:

  • nacl_repy/seattlelib/dispatcher.repy

It is important that the number assigned to the system call here matches the one assigned in GlibC.

Add the syscall's Lind implementation here:

  • nacl_repy/seattlelib/lind_fs_calls.py OR
  • nacl_repy/seattlelib/lind_net_calls.py

In this directory, you will also need to create a new .repy file that will act as the syscall's handler. There you do any mandatory checking and, after the syscall is implemented, pack the result back to NaCl.

Important files (for a system call X):

GlibC

  • Lind-GlibC/sysdeps/nacl/X.c

  • Lind-GlibC/make_sysd_rules.py

  • Lind-GlibC/elf/Versions

For development path 1:

  • Lind-GlibC/sysdeps/nacl/lind_syscalls.h
  • Lind-GlibC/sysdeps/nacl/lind_syscalls.c

For development path 2:

  • Lind-GlibC/sysdeps/nacl/irt_syscalls.h
  • Lind-GlibC/sysdeps/nacl/irt_syscalls.c
  • Lind-GlibC/sysdeps/nacl/nacl_syscalls.h

Native Client

  • native_client/src/trusted/service_runtime/nacl_syscall_common.h

  • native_client/src/trusted/service_runtime/nacl_syscall_common.c

  • native_client/src/shared/platform/lind_platform.h

  • native_client/src/shared/platform/lind_platform.c

For reference:

  • native_client/src/trusted/service_runtime/lind_syscalls.h
  • native_client/src/trusted/service_runtime/lind_syscalls.c

Repy + SafePOSIX

  • nacl_repy/seattlelib/X.repy

  • nacl_repy/seattlelib/lind_server.mix

  • nacl_repy/seattlelib/dispatcher.repy

  • nacl_repy/seattlelib/lind_fs_calls.py

  • nacl_repy/seattlelib/lind_net_calls.py

Clone this wiki locally