# HG changeset patch # User Paul Boddie # Date 1652962108 -7200 # Node ID 12b7393c13dcb1147e85eb6dac4b6936c3dbc550 # Parent 3bc0f7f438bd7bfe88eab62d14070224f6d2a5ec Introduced a region flags parameter to mmap operations to potentially control the attributes of allocated memory, this being necessary when memory must be marked as executable. diff -r 3bc0f7f438bd -r 12b7393c13dc libfsclient/include/fsclient/client.h --- a/libfsclient/include/fsclient/client.h Sat May 14 23:52:24 2022 +0200 +++ b/libfsclient/include/fsclient/client.h Thu May 19 14:08:28 2022 +0200 @@ -64,7 +64,8 @@ /* File and region operations. */ long client_flush(file_t *file); -void *client_mmap(file_t *file, offset_t position, offset_t length); +void *client_mmap(file_t *file, offset_t position, offset_t length, l4re_rm_flags_t region_flags); +l4re_rm_flags_t client_region_flags(prot_t prot, flags_t flags); /* Pipe region operations. */ diff -r 3bc0f7f438bd -r 12b7393c13dc libfsclient/include/fsclient/file.h --- a/libfsclient/include/fsclient/file.h Sat May 14 23:52:24 2022 +0200 +++ b/libfsclient/include/fsclient/file.h Thu May 19 14:08:28 2022 +0200 @@ -23,6 +23,7 @@ #include +#include #include #include @@ -74,6 +75,10 @@ notify_flags_t notifications; + /* Flags indicated when opening the file. */ + + flags_t flags; + } file_t; @@ -104,7 +109,8 @@ /* File and region operations. */ long file_flush(file_t *file); -long file_mmap(file_t *file, offset_t position, offset_t length); +long file_mmap(file_t *file, offset_t position, offset_t length, l4re_rm_flags_t region_flags); +l4re_rm_flags_t file_region_flags(flags_t flags); long file_resize(file_t *file, offset_t size); /* File and region properties. */ diff -r 3bc0f7f438bd -r 12b7393c13dc libfsclient/lib/src/client.cc --- a/libfsclient/lib/src/client.cc Sat May 14 23:52:24 2022 +0200 +++ b/libfsclient/lib/src/client.cc Thu May 19 14:08:28 2022 +0200 @@ -41,6 +41,32 @@ +/* Merging of region flags from protection and access flags. */ + +static l4re_rm_flags_t _combine_region_flags(l4re_rm_flags_t region_flags, + flags_t flags) +{ + return region_flags & (file_region_flags(flags) | L4RE_RM_F_X); +} + +/* Conversion of protection and access flags to region flags. */ + +l4re_rm_flags_t client_region_flags(prot_t prot, flags_t flags) +{ + l4re_rm_flags_t rm_flags = 0; + + if (prot & PROT_READ) + rm_flags |= L4RE_RM_F_R; + if (prot & PROT_WRITE) + rm_flags |= L4RE_RM_F_W; + if (prot & PROT_EXEC) + rm_flags |= L4RE_RM_F_X; + + return _combine_region_flags(rm_flags, flags); +} + + + /* Access the given position and synchronise state with the file object. Pipe objects may return busy conditions indicating that the desired access cannot yet be fulfilled. */ @@ -55,7 +81,8 @@ if ((position < file->start_pos) || (position >= file->end_pos)) { - if (file_mmap(file, position, file_span(file))) + if (file_mmap(file, position, file_span(file), + file_region_flags(file->flags))) return -L4_EIO; } @@ -164,7 +191,8 @@ if (file->memory == NULL) { if (file->object_flags & OBJECT_SUPPORTS_MMAP) - return client_mmap(file, client_tell(file), count); + return client_mmap(file, client_tell(file), count, + file_region_flags(file->flags)); else if (pipe_current(file)) return NULL; } @@ -459,9 +487,10 @@ /* Map a memory region to a file. */ -void *client_mmap(file_t *file, offset_t position, offset_t length) +void *client_mmap(file_t *file, offset_t position, offset_t length, + l4re_rm_flags_t region_flags) { - if ((file == NULL) || (file_mmap(file, position, length))) + if ((file == NULL) || file_mmap(file, position, length, region_flags)) return NULL; return file->memory; diff -r 3bc0f7f438bd -r 12b7393c13dc libfsclient/lib/src/file.cc --- a/libfsclient/lib/src/file.cc Sat May 14 23:52:24 2022 +0200 +++ b/libfsclient/lib/src/file.cc Thu May 19 14:08:28 2022 +0200 @@ -21,8 +21,10 @@ #include #include +#include #include +#include #include #include "dataspace_client.h" @@ -88,6 +90,7 @@ file->object_flags = 0; file->can_block = 0; file->notifications = 0; + file->flags = 0; } @@ -255,6 +258,7 @@ long err; file_init(file); + file->flags = O_RDWR; err = opener.context(&file->ref); if (err) @@ -286,6 +290,7 @@ { client_OpenerContext openercontext(context->ref); file_init(file); + file->flags = flags; return openercontext.open(flags, &file->size, &file->ref, &file->object_flags); } @@ -346,7 +351,8 @@ /* Map a region of the given file to a memory region, obtaining an updated file size and populated data details. Unmap any previously mapped region. */ -long file_mmap(file_t *file, offset_t position, offset_t length) +long file_mmap(file_t *file, offset_t position, offset_t length, + l4re_rm_flags_t region_flags) { char *memory = file->memory; client_MappedFile mapped_file(file->ref); @@ -358,7 +364,10 @@ _update_extent(file); - err = ipc_attach_dataspace(file->ref, file_span(file), (void **) &file->memory); + err = ipc_attach_dataspace_align(file->ref, file_span(file), + L4RE_RM_F_SEARCH_ADDR | region_flags, + L4_PAGESHIFT, + (void **) &file->memory); if (err) return err; @@ -368,6 +377,30 @@ return L4_EOK; } +/* Return mmap flags corresponding to the file access flags. */ + +l4re_rm_flags_t file_region_flags(flags_t flags) +{ + l4re_rm_flags_t rm_flags; + + switch (flags & 3) + { + case O_WRONLY: + rm_flags = L4RE_RM_F_W; + break; + + case O_RDWR: + rm_flags = L4RE_RM_F_RW; + break; + + default: + rm_flags = L4RE_RM_F_R; + break; + } + + return rm_flags; +} + /* Resize a file, obtaining updated file size and populated data details. */ long file_resize(file_t *file, offset_t size) @@ -624,6 +657,8 @@ file_init(reader); file_init(writer); + reader->flags = O_RDONLY; + writer->flags = O_WRONLY; return opener.pipe(size, &reader->ref, &writer->ref); } @@ -697,6 +732,7 @@ { client_Directory directory(file->ref); file_init(reader); + reader->flags = O_RDONLY; return directory.opendir(&reader->size, &reader->ref, &reader->object_flags); } diff -r 3bc0f7f438bd -r 12b7393c13dc libfsserver/include/fsserver/directory_provider.h --- a/libfsserver/include/fsserver/directory_provider.h Sat May 14 23:52:24 2022 +0200 +++ b/libfsserver/include/fsserver/directory_provider.h Thu May 19 14:08:28 2022 +0200 @@ -1,7 +1,7 @@ /* * An object providing a directory abstraction with notification facilities. * - * Copyright (C) 2021 Paul Boddie + * Copyright (C) 2021, 2022 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -41,7 +41,8 @@ virtual DirectoryAccessor *accessor(); - virtual long make_resource(offset_t *size, object_flags_t *object_flags, + virtual long make_resource(flags_t flags, offset_t *size, + object_flags_t *object_flags, Resource **resource); }; diff -r 3bc0f7f438bd -r 12b7393c13dc libfsserver/include/fsserver/file_provider.h --- a/libfsserver/include/fsserver/file_provider.h Sat May 14 23:52:24 2022 +0200 +++ b/libfsserver/include/fsserver/file_provider.h Thu May 19 14:08:28 2022 +0200 @@ -1,7 +1,7 @@ /* * An object encapsulating file resources. * - * Copyright (C) 2021 Paul Boddie + * Copyright (C) 2021, 2022 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -35,14 +35,15 @@ PageMapper *_mapper; public: - explicit FileProvider(fileid_t fileid, map_flags_t flags, - ProviderRegistry *registry, PageMapper *mapper); + explicit FileProvider(fileid_t fileid, ProviderRegistry *registry, + PageMapper *mapper); virtual ~FileProvider(); virtual PageMapper *mapper(); - virtual long make_resource(offset_t *size, object_flags_t *object_flags, + virtual long make_resource(map_flags_t flags, offset_t *size, + object_flags_t *object_flags, Resource **resource); virtual void remove(); diff -r 3bc0f7f438bd -r 12b7393c13dc libfsserver/include/fsserver/provider.h --- a/libfsserver/include/fsserver/provider.h Sat May 14 23:52:24 2022 +0200 +++ b/libfsserver/include/fsserver/provider.h Thu May 19 14:08:28 2022 +0200 @@ -1,7 +1,7 @@ /* * Filesystem object provider support. * - * Copyright (C) 2021 Paul Boddie + * Copyright (C) 2021, 2022 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -44,7 +44,8 @@ virtual ProviderRegistry *registry(); - virtual long make_resource(offset_t *size, object_flags_t *object_flags, + virtual long make_resource(flags_t flags, offset_t *size, + object_flags_t *object_flags, Resource **resource) = 0; /* Lifecycle methods. */ diff -r 3bc0f7f438bd -r 12b7393c13dc libfsserver/lib/directories/directory_provider.cc --- a/libfsserver/lib/directories/directory_provider.cc Sat May 14 23:52:24 2022 +0200 +++ b/libfsserver/lib/directories/directory_provider.cc Thu May 19 14:08:28 2022 +0200 @@ -1,7 +1,7 @@ /* * An object providing access to directory functionality. * - * Copyright (C) 2021 Paul Boddie + * Copyright (C) 2021, 2022 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -48,10 +48,12 @@ /* Return a directory resource initialised with this provider. */ -long DirectoryProvider::make_resource(offset_t *size, +long DirectoryProvider::make_resource(flags_t flags, offset_t *size, object_flags_t *object_flags, Resource **resource) { + (void) flags; + /* Provide non-file values for certain outputs. */ *size = 0; diff -r 3bc0f7f438bd -r 12b7393c13dc libfsserver/lib/files/file_provider.cc --- a/libfsserver/lib/files/file_provider.cc Sat May 14 23:52:24 2022 +0200 +++ b/libfsserver/lib/files/file_provider.cc Thu May 19 14:08:28 2022 +0200 @@ -1,7 +1,7 @@ /* * An object providing access to file functionality. * - * Copyright (C) 2021 Paul Boddie + * Copyright (C) 2021, 2022 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -26,9 +26,9 @@ /* Initialise the provider with a page 'mapper' for the file's contents. */ -FileProvider::FileProvider(fileid_t fileid, map_flags_t flags, - ProviderRegistry *registry, PageMapper *mapper) -: Provider(fileid, registry), _flags(flags), _mapper(mapper) +FileProvider::FileProvider(fileid_t fileid, ProviderRegistry *registry, + PageMapper *mapper) +: Provider(fileid, registry), _mapper(mapper) { } @@ -54,13 +54,14 @@ /* Return a file pager initialised with a provider, page mapper and accessor. */ -long FileProvider::make_resource(offset_t *size, object_flags_t *object_flags, +long FileProvider::make_resource(map_flags_t flags, offset_t *size, + object_flags_t *object_flags, Resource **resource) { /* Initialise the pager with the provider and a reference to this object for detaching from the provider. */ - FilePager *pager = new FilePager(_fileid, this, _flags); + FilePager *pager = new FilePager(_fileid, this, flags); /* Obtain the size details from the pager, also providing appropriate flags. */ diff -r 3bc0f7f438bd -r 12b7393c13dc libfsserver/lib/generic/resource_registry.cc --- a/libfsserver/lib/generic/resource_registry.cc Sat May 14 23:52:24 2022 +0200 +++ b/libfsserver/lib/generic/resource_registry.cc Thu May 19 14:08:28 2022 +0200 @@ -23,6 +23,7 @@ #include "file_pager.h" #include "resource_registry.h" +#include /* file_region_flags */ #include @@ -41,7 +42,7 @@ map_flags_t ResourceRegistry::get_flags(flags_t flags) { - return flags & (O_WRONLY | O_RDWR) ? L4RE_DS_MAP_FLAG_RW : L4RE_DS_MAP_FLAG_RO; + return file_region_flags(flags); } @@ -81,7 +82,7 @@ return err; PageMapper *mapper = new PageMapper(accessor, _pages); - *provider = new FileProvider(fileid, get_flags(flags), this, mapper); + *provider = new FileProvider(fileid, this, mapper); return L4_EOK; } @@ -167,7 +168,7 @@ /* Make a resource for the provider. */ - return provider->make_resource(size, object_flags, resource); + return provider->make_resource(get_flags(flags), size, object_flags, resource); } /* Request the removal of a filesystem object through any active provider or diff -r 3bc0f7f438bd -r 12b7393c13dc libfsserver/lib/mapping/ipc.cc --- a/libfsserver/lib/mapping/ipc.cc Sat May 14 23:52:24 2022 +0200 +++ b/libfsserver/lib/mapping/ipc.cc Thu May 19 14:08:28 2022 +0200 @@ -1,7 +1,7 @@ /* * Interprocess communication utilities. * - * Copyright (C) 2021 Paul Boddie + * Copyright (C) 2021, 2022 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -28,12 +28,17 @@ #include "ipc.h" + /* Make an L4 representation of the given flexpage. */ static l4_fpage_t ipc_get_fpage(SendFlexpage *send_flexpage) { - return l4_fpage(send_flexpage->base_addr, send_flexpage->order, - (send_flexpage->flags & L4RE_DS_MAP_FLAG_RW) ? L4_FPAGE_RW : L4_FPAGE_RO); + unsigned char flags = send_flexpage->flags; + + if (!flags) + flags = L4RE_DS_MAP_FLAG_RO; + + return l4_fpage(send_flexpage->base_addr, send_flexpage->order, flags); } /* Make a representation of a flexpage for the IPC system. */ diff -r 3bc0f7f438bd -r 12b7393c13dc libsystypes/include/systypes/base.h --- a/libsystypes/include/systypes/base.h Sat May 14 23:52:24 2022 +0200 +++ b/libsystypes/include/systypes/base.h Thu May 19 14:08:28 2022 +0200 @@ -1,7 +1,7 @@ /* * Base types used by various other types. * - * Copyright (C) 2019, 2021 Paul Boddie + * Copyright (C) 2019, 2021, 2022 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -63,6 +63,19 @@ OBJECT_HAS_SIZE = 2 }; +/* Memory mapping protection flags compatible with sys/mman.h (and incompatible + with comparable L4Re flags). */ + +typedef unsigned long prot_t; + +enum prot_flags +{ + PROT_NONE = 0, + PROT_READ = 1, + PROT_WRITE = 2, + PROT_EXEC = 4 +}; + /* Equivalent types are defined in sys/types.h typically. In newlib, they are defined in sys/_types.h if not defined elsewhere (such as in machine/_types.h). diff -r 3bc0f7f438bd -r 12b7393c13dc tests/dstest_block_client.cc --- a/tests/dstest_block_client.cc Sat May 14 23:52:24 2022 +0200 +++ b/tests/dstest_block_client.cc Thu May 19 14:08:28 2022 +0200 @@ -1,7 +1,7 @@ /* * Test dataspace operations. * - * Copyright (C) 2020, 2021 Paul Boddie + * Copyright (C) 2020, 2021, 2022 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -82,7 +82,7 @@ /* A region of the file is mapped. */ - err = file_mmap(&file, 0, page(10)); + err = file_mmap(&file, 0, page(10), file_region_flags(file.flags)); if (err) { diff -r 3bc0f7f438bd -r 12b7393c13dc tests/dstest_host_client.cc --- a/tests/dstest_host_client.cc Sat May 14 23:52:24 2022 +0200 +++ b/tests/dstest_host_client.cc Thu May 19 14:08:28 2022 +0200 @@ -1,7 +1,7 @@ /* * Test dataspace operations. * - * Copyright (C) 2020, 2021 Paul Boddie + * Copyright (C) 2020, 2021, 2022 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -68,7 +68,7 @@ /* A region of the file is mapped. */ - err = file_mmap(&file, 0, page(10)); + err = file_mmap(&file, 0, page(10), file_region_flags(file.flags)); if (err) { diff -r 3bc0f7f438bd -r 12b7393c13dc tests/dstest_test_client.cc --- a/tests/dstest_test_client.cc Sat May 14 23:52:24 2022 +0200 +++ b/tests/dstest_test_client.cc Thu May 19 14:08:28 2022 +0200 @@ -1,7 +1,7 @@ /* * Test dataspace operations. * - * Copyright (C) 2020, 2021 Paul Boddie + * Copyright (C) 2020, 2021, 2022 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -77,7 +77,7 @@ /* A region of the file is mapped. */ - err = file_mmap(&file, page(start_page), page(MAP_PAGES)); + err = file_mmap(&file, page(start_page), page(MAP_PAGES), file_region_flags(file.flags)); if (err) {