💾 Archived View for tilde.pink › ~racoon › unix › wine_sandbox.gmi captured on 2022-06-03 at 23:52:28. Gemini links have been rewritten to link to archived content

View Raw

More Information

➡️ Next capture (2023-01-29)

-=-=-=-=-=-=-

Running Wine in a 32-bit sandbox on 64-bit NetBSD

So, you want to play old Windows games on NetBSD...

My machine runs amd64, and Wine needs to be built with 32-bit

libraries to run a lot of older Windows applications.

"Mainline pkgsrc" can't do strange multi-arch Wine builds yet,

so a 32-bit sandbox seems like a reasonable way to use 32-bit Wine

on amd64 without resorting to running real Windows in NVMM.

We're using sandboxctl, which is a neat tool for quickly shelling into

a different NetBSD userspace. Maybe you also don't trust the Windows

applications you're running too much - sandboxctl creates a chroot based

on a fresh system image, and chroot on NetBSD is bombproof.

Prerequisites

First, install the sandboxctl package:

	# pkgin install sandboxctl

You'll need to enable some sysctl variables.

This one will allow multiple system users to play audio,

and will save you some debugging if you're wondering why

things are mysteriously silent:

	# sysctl -w hw.audio0.multiuser=1

This one will allow Wine to map the NULL page (which it needs to do for cursed reasons):

	# sysctl -w vm.user_va0_disable=0

Add them to /etc/sysctl.conf to make them permanent.

Configuring sandboxctl

Download some i386 NetBSD sets into a directory:

	$ mkdir -p ~/netbsd-i386/binary/sets && cd ~/netbsd-i386/binary/sets
	$ ftp https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/i386/binary/sets/base.tgz
	$ ftp https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/i386/binary/sets/etc.tgz
	$ ftp https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/i386/binary/sets/xbase.tgz
	$ ftp https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/i386/binary/sets/xetc.tgz
	$ ftp https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/i386/binary/sets/xfont.tgz

Create a new config file for sandboxctl in /usr/pkg/etc/sandboxctl/wine.conf:

	SANDBOX_TYPE=netbsd-release
	SANDBOX_ROOT="/var/chroot/wine-i386"

	NETBSD_RELEASE_RELEASEDIR="/home/washbear/netbsd-i386"
	NETBSD_RELEASE_SETS="base etc xbase xetc xfont"

Let's create the sandbox and Wine user:

	# sandboxctl -c wine create
	# sandboxctl -c wine run useradd -m -d /home/wine wine

Kernel config abuse

Wine needs to abuse the system, because it needs to run Windows applications.

Running NetBSD 10 or -current? Then you don't need to do this.

Running NetBSD 9.x? Make sure your kernel has the necessary security

features disabled to run Wine. You'll need fresh netbsd-9 sources.

	$ vi sys/arch/amd64/conf/GENERIC

These options matter:

	# USER_LDT. You need to disable SVS to use it.
	options 	USER_LDT	# user-settable LDT; used by WINE
	no options	SVS

Build a new kernel. Shouldn't take too long :D

	$ ./build.sh -U -j4 tools
	$ ./build.sh -U -j4 kernel=GENERIC

Back up the old kernel, copy the new one into place and reboot:

	# mv /netbsd /onetbsd
	# cp sys/arch/amd64/compile/obj/GENERIC/netbsd /netbsd
	# shutdown -r now

Making X11 play nicely with the sandbox

We need some way to allow X11 applications inside the sandbox to

communicate with the X server.

Attempt 1 (X11-over-TCP)

This is required if /tmp is not on the same filesystem as the sandbox -

it took me far too long to realize this. It's quite slow, though.

Start the X server on the host machine with TCP connections and indirect GLX enabled:

	$ startx -- -listen tcp +iglx

Once you're in X11, disable access control, and hopefully you're either behind a firewall or on a trusted network...

	$ xhost +

Attempt 2 (/tmp on the same filesystem as the sandbox)

I gave up with TCP and removed my tmpfs mount in /etc/fstab so

that /tmp could reside on the same filesystem as the sandbox.

I actually don't like this at all.

This allows us to use hard links to the X11 Unix socket once

X is started:

	# mkdir -m 777 -p /var/chroot/wine-i386/tmp/.X11-unix
	# ln -f /tmp/.X11-unix/X0 /var/chroot/wine-i386/tmp/.X11-unix/X0
	# chmod 777 /var/chroot/wine-i386/tmp/.X11-unix/X0

Then use xauth to grant access to your user's X server to the sandbox:

	$ xauth extract /var/chroot/wine-i386/home/wine/.Xauthority :0

OpenGL

I quickly discovered Direct Rendering from a 32-bit sandbox isn't all that viable.

In the sense that `glxgears` immediately segfaults,

regardless of whether the connection to X11 is over TCP or Unix socket.

I think this is due to lack of DRM ioctls in NetBSD's 32-bit compat layer.

So:

	$ export LIBGL_ALWAYS_SOFTWARE=1

This makes OpenGL use llvmpipe instead of the GPU, which might be slow depending on

the age of the software and your hardware. You do not need +iglx for this.

llvmpipe is surprisingly good even on my 5 year old CPU.

Alternatively, you can do:

	$ export LIBGL_ALWAYS_INDIRECT=1

Which seems to work briefly, but then my X server crashes - ymmv.

The Xserver(1) man page has some interesting things to say about +iglx and LIBGL_ALWAYS_INDIRECT=1...

Indirect GLX is of limited use, since it lacks support for many modern
OpenGL features and extensions; it's slower than direct contexts; and it
opens a large attack surface for protocol parsing errors.

Ouch.

Using your sandbox

Shell into your sandbox:

	# sandboxctl -c wine shell

Install the Wine package, and any others you desire in your 32-bit sandbox:

	# export PKG_PATH=http://cdn.netbsd.org/pub/pkgsrc/packages/NetBSD/i386/9.0/All
	# pkg_add pkgin
	# pkgin update
	# pkgin install wine

(I prefer to always use pkgin even for simple cases like this, it's just better.)

su into your user account:

	# useradd -m -d /home/wine wine
	# su -l wine

From outside the sandbox, copy some files, maybe.

In this case, I'm copying the DRM-free version of Red Faction from GOG:

	# cp ~/Downloads/setup_red_faction_2.0.0.7.exe /var/chroot/wine-i386/home/wine/

Inside the sandbox, I can now run my 32-bit executable:

	$ export DISPLAY=:0
	$ winecfg
	$ wine setup_red_faction_2.0.0.7.exe

When you're done, exit the sandbox with ^D.

Suggestions

Making sure the sandbox user has the same `uid` as your normal user

account probably helps with permissions nonsense.

In my case, it was the first ordinary user created on both systems,

so that was automatic.

The entire concept of running Windows applications on Unix is somewhat

cursed and requires some security compromises to make easy. If you care

about keeping your Unix system hardened, maybe keep Windows on another

machine - and don't let it near an Ethernet cable.

This kind of sandbox is really nice for development, testing, and isolating

applications, but comes with strong asterisks when it comes to graphics.

I actually much prefer running DRM-free games using compat_linux when

I can.

More Unix and NetBSD