> From: Keith Packard <kei...@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 <kei...@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 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel