wayland/keyboard: Use write() instead of mmapped address to write file

When starting an application on Wayland we store its keymap file in /tmp
using mmap() to map the file into virtual memory and strcpy() to write
to the file. Now in case /tmp is filled up and the write fails (/tmp is
usually mounted as a ramdisk, so that can easily happen), the shell
crashes with SIGBUS when trying to call strcpy(). That's because mmap()
does not check whether the space is actually available on the filesystem
and gives us a chunk of virtual memory anyway even though writing to it
is going to fail.

This allows for an easy denial-of-service attack, because /tmp is
world-writeable, and as soon as it's filled up and the user tries to
open a new application, the shell is going to crash.

To fix this, use write() instead of mmap() and strcpy() to write the
string to the file: write() handles out-of-space errors gracefully and
just returns an error instead of crashing.

Fixes GNOME/gnome-shell#1734

GNOME/mutter!1008
5 jobs for !1008 with fix-crash-on-tmp-filled in 10 minutes and 47 seconds (queued for 1 second)
latest detached
Status Job ID Name Coverage
  Review
passed #554625
check-commit-log

00:00:35

 
  Build
passed #554626
build-mutter

00:06:56

passed #554627
build-without-native-backend-and-wayland

00:03:12

 
  Test
failed #554629
can-build-gnome-shell

00:01:28

passed #554628
test-mutter

00:03:15

 
Name Stage Failure
failed
can-build-gnome-shell Test
Run-time dependency gtk+-3.0 found: YES 3.24.13
Run-time dependency libxml-2.0 found: YES 2.9.10
Dependency mutter-clutter-6 found: NO found '3.35.2' but need: '>= 3.35.3'
Run-time dependency mutter-clutter-6 found: NO

meson.build:90:0: ERROR: Invalid version of dependency, need 'mutter-clutter-6' ['>= 3.35.3'] found '3.35.2'.

A full log can be found at /builds/verdre/mutter/gnome-shell/build/meson-logs/meson-log.txt
ERROR: Job failed: exit code 1