Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ned14/llfio.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiall Douglas <s_github@nedprod.com>2022-09-13 20:12:48 +0300
committerNiall Douglas <s_github@nedprod.com>2022-09-13 20:12:48 +0300
commit05141b444da3ce26740fa0a22baac7f13704609e (patch)
tree8b26e5eb842dd17b54ad3a2ffea589a03af9839f
parentae7f9c5a92879285ad5100c89efc47ce1cb0031b (diff)
Fix issue #102 Using a status code converted from a file_io_error segfaults.
-rw-r--r--cmake/tests.cmake1
-rw-r--r--include/llfio/revision.hpp6
-rw-r--r--include/llfio/v2.0/status_code.hpp40
-rw-r--r--test/tests/issue0102.cpp45
-rw-r--r--test/tests/tls_socket_handle.cpp9
5 files changed, 89 insertions, 12 deletions
diff --git a/cmake/tests.cmake b/cmake/tests.cmake
index 3a09d38c..630aeba3 100644
--- a/cmake/tests.cmake
+++ b/cmake/tests.cmake
@@ -19,6 +19,7 @@ set(llfio_TESTS
"test/tests/issue0027.cpp"
"test/tests/issue0028.cpp"
"test/tests/issue0073.cpp"
+ "test/tests/issue0102.cpp"
"test/tests/large_pages.cpp"
"test/tests/map_handle_cache.cpp"
"test/tests/map_handle_create_close/kernel_map_handle.cpp.hpp"
diff --git a/include/llfio/revision.hpp b/include/llfio/revision.hpp
index c72ba4fd..f2b2549a 100644
--- a/include/llfio/revision.hpp
+++ b/include/llfio/revision.hpp
@@ -1,4 +1,4 @@
// Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time
-#define LLFIO_PREVIOUS_COMMIT_REF 1714505e3cb9e9547bd45faaefcea1b9ad0506ae
-#define LLFIO_PREVIOUS_COMMIT_DATE "2022-09-06 18:54:18 +00:00"
-#define LLFIO_PREVIOUS_COMMIT_UNIQUE 1714505e
+#define LLFIO_PREVIOUS_COMMIT_REF ae7f9c5a92879285ad5100c89efc47ce1cb0031b
+#define LLFIO_PREVIOUS_COMMIT_DATE "2022-09-07 15:07:48 +00:00"
+#define LLFIO_PREVIOUS_COMMIT_UNIQUE ae7f9c5a
diff --git a/include/llfio/v2.0/status_code.hpp b/include/llfio/v2.0/status_code.hpp
index eb1b2959..9813f4a1 100644
--- a/include/llfio/v2.0/status_code.hpp
+++ b/include/llfio/v2.0/status_code.hpp
@@ -194,8 +194,15 @@ public:
static inline constexpr const file_io_error_domain &get();
#endif
+ virtual typename _base::payload_info_t payload_info() const noexcept override
+ {
+ return {sizeof(value_type), sizeof(SYSTEM_ERROR2_NAMESPACE::status_code_domain *) + sizeof(value_type),
+ (alignof(value_type) > alignof(SYSTEM_ERROR2_NAMESPACE::status_code_domain *)) ? alignof(value_type) :
+ alignof(SYSTEM_ERROR2_NAMESPACE::status_code_domain *)};
+ }
+
protected:
- virtual inline string_ref _do_message(const SYSTEM_ERROR2_NAMESPACE::status_code<void> &code) const noexcept override final
+ virtual inline string_ref _do_message(const SYSTEM_ERROR2_NAMESPACE::status_code<void> &code) const noexcept override
{
assert(code.domain() == *this);
const auto &v = static_cast<const SYSTEM_ERROR2_NAMESPACE::status_code<file_io_error_domain> &>(code); // NOLINT
@@ -246,6 +253,27 @@ protected:
memcpy(p, ret.c_str(), ret.size() + 1);
return atomic_refcounted_string_ref(p, ret.size());
}
+ virtual bool _do_erased_copy(SYSTEM_ERROR2_NAMESPACE::status_code<void> &dst, const SYSTEM_ERROR2_NAMESPACE::status_code<void> &src,
+ typename _base::payload_info_t dstinfo) const override
+ {
+ // Note that dst may not have its domain set
+ const auto srcinfo = payload_info();
+ if(dstinfo.total_size >= srcinfo.total_size)
+ {
+ // Identity
+ memcpy(&dst, &src, srcinfo.total_size);
+ return true;
+ }
+ if(dstinfo.total_size >= sizeof(SYSTEM_ERROR2_NAMESPACE::status_code_domain *) + sizeof(value_type::sc))
+ {
+ // Allow dropping LLFIO additional state
+ const auto *basedomain = &_base::get();
+ memcpy(&dst, &src, sizeof(SYSTEM_ERROR2_NAMESPACE::status_code_domain *) + sizeof(value_type::sc));
+ memcpy(&dst, &basedomain, sizeof(SYSTEM_ERROR2_NAMESPACE::status_code_domain *));
+ return true;
+ }
+ return false;
+ }
};
#if __cplusplus >= 201402L || defined(_MSC_VER)
template <class BaseStatusCodeDomain> constexpr file_io_error_domain<BaseStatusCodeDomain> file_io_error_domain_inst = {};
@@ -327,7 +355,10 @@ inline file_io_error ntkernel_error(SYSTEM_ERROR2_NAMESPACE::win32::NTSTATUS c);
namespace detail
{
- inline std::ostream &operator<<(std::ostream &s, const file_io_error &v) { return s << "llfio::file_io_error(" << v.message().c_str() << ")"; }
+ inline std::ostream &operator<<(std::ostream &s, const file_io_error &v)
+ {
+ return s << "llfio::file_io_error(" << v.message().c_str() << ")";
+ }
} // namespace detail
inline file_io_error error_from_exception(std::exception_ptr &&ep = std::current_exception(),
SYSTEM_ERROR2_NAMESPACE::system_code not_matched = errc::resource_unavailable_try_again) noexcept
@@ -408,7 +439,10 @@ public:
}
//! Retrieve the value of the error code
- int value() const noexcept { return ec.value(); }
+ int value() const noexcept
+ {
+ return ec.value();
+ }
//! Retrieve any first path associated with this failure. Note this only works if called from the same thread as where the failure occurred.
inline filesystem::path path1() const
{
diff --git a/test/tests/issue0102.cpp b/test/tests/issue0102.cpp
new file mode 100644
index 00000000..6ba76e62
--- /dev/null
+++ b/test/tests/issue0102.cpp
@@ -0,0 +1,45 @@
+/* Integration test kernel for issue #73 Windows directory junctions cannot be opened with symlink_handle
+(C) 2022 Niall Douglas <http://www.nedproductions.biz/> (2 commits)
+File Created: Sept 2022
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License in the accompanying file
+Licence.txt or at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
+Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file Licence.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#include "../test_kernel_decl.hpp"
+
+static inline void TestIssue0102()
+{
+ namespace llfio = LLFIO_V2_NAMESPACE;
+ namespace outcome_e = OUTCOME_V2_NAMESPACE::experimental;
+
+ auto page = llfio::utils::page_allocator<std::byte>().allocate(llfio::utils::page_size());
+
+ llfio::file_io_error ioError = llfio::generic_error(llfio::errc::state_not_recoverable);
+
+ // (I know this is very likely to be misaligned on 64Bit systems, but
+ // otherwise the problem/segfault is only triggered on 32Bit systems)
+ auto erasedError =
+ new(page + llfio::utils::page_size() - sizeof(outcome_e::status_code_domain *) - sizeof(int)) outcome_e::errored_status_code<outcome_e::erased<int>>(ioError);
+
+ // the following line must not segfault
+ std::cout << erasedError->message() << std::endl;
+}
+
+KERNELTEST_TEST_KERNEL(regression, llfio, issues, 0102, "Tests issue #0102 Using a status code converted from a file_io_error segfaults", TestIssue0102())
diff --git a/test/tests/tls_socket_handle.cpp b/test/tests/tls_socket_handle.cpp
index 5df7dd3d..631c3023 100644
--- a/test/tests/tls_socket_handle.cpp
+++ b/test/tests/tls_socket_handle.cpp
@@ -285,10 +285,7 @@ static inline void TestAuthenticatingTLSSocketHandles()
//! [https_get]
namespace llfio = LLFIO_V2_NAMESPACE;
static constexpr llfio::string_view test_host("github.com");
- static constexpr llfio::string_view get_request(R"(GET / HTTP/1.0
-Host: github.com
-
-)");
+ static constexpr llfio::string_view get_request("GET / HTTP/1.0\r\nHost: github.com\r\n\r\n");
if(llfio::tls_socket_source_registry::empty())
{
std::cout << "\nNOTE: This platform has no TLS socket sources in its registry, skipping this test." << std::endl;
@@ -320,9 +317,9 @@ Host: github.com
// Fetch the front page. The connection will close once all data is sent.
std::vector<llfio::byte> buffer(4096);
size_t offset = 0;
- for(size_t readed = 0; (readed = sock->read({{buffer.data() + offset, buffer.size() - offset}}, std::chrono::seconds(3)).value()) > 0;)
+ for(size_t nread = 0; (nread = sock->read({{buffer.data() + offset, buffer.size() - offset}}, std::chrono::seconds(3)).value()) > 0;)
{
- offset += readed;
+ offset += nread;
if(buffer.size() - offset < 1024)
{
buffer.resize(buffer.size() + 4096);