cms icon indicating copy to clipboard operation
cms copied to clipboard

Add support for C# compiled by .NET SDK

Open gollux opened this issue 2 years ago • 3 comments

I tried adding support for C# compiled by .NET SDK 7.0. I have a very preliminary version running in the Czech national olympiad, but before I submit a pull request, I would like to discuss some problems I stumbled upon and agree on how they should be solved properly.

(1) Permission problems. The dotnet compiler creates a whole forest of intermediate directories, often with restrictive permissions. This hits the issue #1242. I worked around this by creating a temporary directory within /box and symlinking it as obj in the current directory.

(2) User lookup problem. The compiler expects that the current UID has an entry in /etc/passwd. With a typical installation of Isolate (as installed by CMS installation scripts), the sandbox users don't have their entries. As CMS bind-mounts /etc in compilation sandboxes, this can be worked around by adding all sandbox users to /etc/passwd of the host system. I wonder if this has a nicer solution...

(3) To use dotnet build, one must create a *.cproj project file first. I figured out how to do it, but not how to integrate it nicely with the CMS language modules: they allow generating compilation commands, but I would rather need to call a Python function which would generate the file and put it in the sandbox directory. I worked around it by calling a helper script, but then we have to install the helper script to a location which is available inside the sandbox (e.g., /usr/local/bin), which is different from where we install the CMS itself (in my case, it's a virtual environment).

(4) I need to modify some parameters of the sandbox: increase the maximum number of open files, pass some extra environment variables, possibly bind-mount more directories. I did it by adding these options to all languages, but it would be really nice to have them per-language. I handled environment variables in the helper script for the time being.

I would appreciate any ideas on how to solve these problems in an upstreamable way.

gollux avatar Oct 08 '23 16:10 gollux

(2) User lookup problem. The compiler expects that the current UID has an entry in /etc/passwd. [...] I wonder if this has a nicer solution

Does the compiler really read /etc/passwd directly, or does it use getpwuid()?

In the latter case it should be possible to write a glibc NSS plugin for isolate that would resolve isolate uids dynamically. systemd's DynamicUser= feature is resolved this way via nss-systemd(8).

Alternatively, it may be possible to define the user records in /etc/userdb or /run/userdb. Then they would get resolved through systemd-userdbd(8). But the sandboxed program needs to have the ability to call host D-Bus for this, which likely has security implications.

EDIT: Another possibility is to bind-mount a temporary /etc/passwd and /etc/group in the sandbox.

andreyv avatar Oct 29 '23 10:10 andreyv

Does the compiler really read /etc/passwd directly, or does it use getpwuid()?

I don't know yet. I suspect it does the latter, but I didn't want to dig deeper before I find any solution where using getpwuid() would actually help :)

Adding a NSS plugin would work, but I don't think it's easier than just adding all the sandbox UIDs to /etc/passwd :-)

Running D-Bus inside the sandbox is even more complicated. (Also, I'm not sure that Isolate should depend on systemd being available.)

Bind-mounting temporary /etc/passwd could solve the problem, but so far, Isolate didn't assume anything about /etc being always mounted.

Generally, adding the entries to host /etc/passwd looks as the easiest solution.

I am more worried with the other problems.

gollux avatar Oct 29 '23 11:10 gollux