Skip to content

Commit

Permalink
server: Reuse shared mapping's mmaped pointer and handle mmap failures.
Browse files Browse the repository at this point in the history
Desktop and its shared mapping can be still alive and may be reused
after desktop is unlinked via close_desktop_timeout() but before all
references and handles are cleared.

On the re-use path the mmap(PROT_WRITE) is called on a write-sealed fd
which will fail returning MAP_FAILED. It would then be propagated up and
dereferenced causing the server to crash.

This fixes the crash + makes sure that we can recreate the desktop
successfully if needed.

Fixes: 653dab0 ("server: Seal shared memory mappings against future writes.")
Fixes: 61521e3 ("HACK: server: Close desktop immediately when last user is removed.")
CW-Bug-Id: #20266
  • Loading branch information
ivyl committed Mar 9, 2022
1 parent f70b0f2 commit 60b85b1
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 2 deletions.
11 changes: 10 additions & 1 deletion server/mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ struct mapping
pe_image_info_t image; /* image info (for PE image mapping) */
struct ranges *committed; /* list of committed ranges in this mapping */
struct shared_map *shared; /* temp file for shared PE mapping */
void *shared_ptr; /* mmaped pointer for shared mappings */
};

static void mapping_dump( struct object *obj, int verbose );
Expand Down Expand Up @@ -905,6 +906,7 @@ static struct mapping *create_mapping( struct object *root, const struct unicode
mapping->fd = NULL;
mapping->shared = NULL;
mapping->committed = NULL;
mapping->shared_ptr = NULL;

if (!(mapping->flags = get_mapping_flags( handle, flags ))) goto error;

Expand Down Expand Up @@ -1148,16 +1150,23 @@ struct object *create_shared_mapping( struct object *root, const struct unicode_

if (!(mapping = create_mapping( root, name, OBJ_OPENIF, size, SEC_COMMIT, 0,
FILE_READ_DATA | FILE_WRITE_DATA, sd ))) return NULL;
*ptr = mmap( NULL, mapping->size, PROT_WRITE, MAP_SHARED, get_unix_fd( mapping->fd ), 0 );

if (mapping->shared_ptr)
*ptr = mapping->shared_ptr;
else
*ptr = mmap( NULL, mapping->size, PROT_WRITE, MAP_SHARED, get_unix_fd( mapping->fd ), 0 );

fcntl( get_unix_fd( mapping->fd ), F_ADD_SEALS, seals );

if (*ptr == MAP_FAILED)
{
*ptr = NULL;
release_object( &mapping->obj );
return NULL;
}

mapping->shared_ptr = *ptr;

return &mapping->obj;
}

Expand Down
2 changes: 1 addition & 1 deletion server/winstation.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ static void desktop_destroy( struct object *obj )
if (desktop->msg_window) destroy_window( desktop->msg_window );
if (desktop->global_hooks) release_object( desktop->global_hooks );
list_remove( &desktop->entry );
release_object( desktop->shared_mapping );
if (desktop->shared_mapping) release_object( desktop->shared_mapping );
release_object( desktop->winstation );
}

Expand Down

0 comments on commit 60b85b1

Please sign in to comment.