[PATCH 5/7] Trap SIGBUS to handle truncated shared memory segments
Mark Kettenis
mark.kettenis at xs4all.nl
Fri Nov 8 12:41:38 PST 2013
> From: Keith Packard <keithp at keithp.com>
> Date: Thu, 7 Nov 2013 12:15:58 -0800
>
> If a client passes a section of memory via file descriptor and then
> subsequently truncates that file, the underlying pages will be freed
> and the addresses invalidated. Subsequent accesses to the page will
> fail with a SIGBUS error.
>
> Trap that SIGBUS, figure out which segment was causing the error and
> then allocate new pages to fill in for that region. Mark the offending
> shared segment as invalid and free the resource ID so that the client
> will be able to tell when subsequently attempting to use the segment.
>
> Signed-off-by: Keith Packard <keithp at keithp.com>
>
> v2: Use MAP_FIXED to simplify the recovery logic (Mark Kettenis)
> v3: Also catch errors in ShmCreateSegment
>
> +static void
> +busfault_sigaction(int sig, siginfo_t *info, void *param)
> +{
> + void *fault = info->si_addr;
> + struct busfault *busfault = NULL;
> + void *new_addr;
> +
> + /* Locate the faulting address in our list of shared segments
> + */
> + xorg_list_for_each_entry(busfault, &busfaults, list) {
> + if ((char *) busfault->addr <= (char *) fault && (char *) fault < (char *) busfault->addr + busfault->size) {
> + break;
> + }
> + }
> + if (!busfault)
> + goto panic;
> +
> + if (!busfault->valid)
> + goto panic;
> +
> + busfault->valid = FALSE;
> + busfaulted = TRUE;
> +
> + /* The client truncated the file; unmap the shared file, map
> + * /dev/zero over that area and keep going
> + */
> +
> + new_addr = mmap(busfault->addr, busfault->size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE|MAP_FIXED, -1, 0);
Proper spelling of MAP_ANONYMOUS is MAP_ANON. The former doesn't
exist on BSD and the latter is available everywhere AFAIK (checked
Solaris and Linux).
You also might want to wrap that line ;).
Cheers,
Mark
More information about the xorg-devel
mailing list