Skip to content
Bitcoin Roots

v31.1-roots.1 · Commit 6: [PATCH 06/17] feat(wallet): preserve Roots signing and spend controls on v31

src/test/system_tests.cpp

Before: src/test/system_tests.cpp · After: src/test/system_tests.cpp

File metadata
index bd57661b051cb7e05d4aea86a872e08760739fec..cc8c079caad8522103904d3dd3442257f0752e37 100644

Download original patch · Release notes

Diff rows 1–76 of 76. Line numbers refer to the original before/after files.

+ Added− RemovedUnmarked lines are context.

Scroll the code area horizontally to read long lines. Before is on the left; after is on the right. Unified view fits narrow screens more easily.

src/test/system_tests.cpp CHANGED
@@ -20,6 +20,13 @@
20
 
21
  #include <string>
22
 
 
 
 
 
 
 
 
23
  BOOST_FIXTURE_TEST_SUITE(system_tests, BasicTestingSetup)
24
 
25
  #ifdef ENABLE_EXTERNAL_SIGNER
@@ -84,6 +91,63 @@ BOOST_AUTO_TEST_CASE(run_command)
84
  BOOST_CHECK_EQUAL(success.get_bool(), true);
85
  }
86
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  #endif // ENABLE_EXTERNAL_SIGNER
88
 
89
  BOOST_AUTO_TEST_SUITE_END()
 
20
 
21
  #include <string>
22
 
23
+ #ifndef WIN32
24
+ #include <fcntl.h>
25
+ #include <sys/resource.h>
26
+ #include <sys/wait.h>
27
+ #include <unistd.h>
28
+ #endif
29
+
30
  BOOST_FIXTURE_TEST_SUITE(system_tests, BasicTestingSetup)
31
 
32
  #ifdef ENABLE_EXTERNAL_SIGNER
 
91
  BOOST_CHECK_EQUAL(success.get_bool(), true);
92
  }
93
  }
94
+ #ifndef WIN32
95
+ BOOST_AUTO_TEST_CASE(signer_fallback_closes_descriptors_above_lowered_limit)
96
+ {
97
+ const int fd = open("/dev/null", O_RDONLY);
98
+ BOOST_REQUIRE(fd >= 0);
99
+ const int inherited = fcntl(fd, F_DUPFD, 123);
100
+ close(fd);
101
+ BOOST_REQUIRE(inherited >= 123);
102
+ int pipe_fds[2];
103
+ BOOST_REQUIRE_EQUAL(pipe(pipe_fds), 0);
104
+ const pid_t child = fork();
105
+ BOOST_REQUIRE(child >= 0);
106
+ if (child == 0) {
107
+ close(pipe_fds[0]);
108
+ struct rlimit limit;
109
+ if (getrlimit(RLIMIT_NOFILE, &limit) != 0) _exit(1);
110
+ limit.rlim_cur = 32;
111
+ if (setrlimit(RLIMIT_NOFILE, &limit) != 0) _exit(2);
112
+ int error_fd{pipe_fds[1]};
113
+ const bool closed = subprocess::detail::subprocess_close_all_fds(error_fd, /*force_fallback=*/true);
114
+ const unsigned char facts = (closed ? 1 : 0) |
115
+ (fcntl(inherited, F_GETFD) == -1 && errno == EBADF ? 2 : 0) |
116
+ (error_fd == 3 && fcntl(error_fd, F_GETFD) >= 0 ? 4 : 0) |
117
+ (fcntl(0, F_GETFD) >= 0 && fcntl(1, F_GETFD) >= 0 && fcntl(2, F_GETFD) >= 0 ? 8 : 0) |
118
+ ((fcntl(error_fd, F_GETFD) & FD_CLOEXEC) != 0 ? 16 : 0);
119
+ const bool sent = write(error_fd, &facts, sizeof(facts)) == sizeof(facts);
120
+ _exit(sent ? 0 : 3);
121
+ }
122
+ close(inherited);
123
+ close(pipe_fds[1]);
124
+ unsigned char facts{0};
125
+ BOOST_CHECK_EQUAL(read(pipe_fds[0], &facts, sizeof(facts)), sizeof(facts));
126
+ close(pipe_fds[0]);
127
+ int status{0};
128
+ BOOST_REQUIRE_EQUAL(waitpid(child, &status, 0), child);
129
+ BOOST_CHECK(WIFEXITED(status));
130
+ BOOST_CHECK_EQUAL(WEXITSTATUS(status), 0);
131
+ #if defined(__linux__) || HAVE_CLOSEFROM
132
+ BOOST_CHECK_EQUAL(facts, 31);
133
+ #else
134
+ BOOST_CHECK_EQUAL(facts & 1, 0); // Unsupported platforms fail closed.
135
+ #endif
136
+ }
137
+
138
+ BOOST_AUTO_TEST_CASE(signer_closes_inherited_descriptors)
139
+ {
140
+ const int fd = open("/dev/null", O_RDONLY);
141
+ BOOST_REQUIRE(fd >= 0);
142
+ // A high descriptor avoids collision with the child's startup files.
143
+ const int inherited = fcntl(fd, F_DUPFD, 123);
144
+ close(fd);
145
+ BOOST_REQUIRE(inherited >= 123);
146
+ const auto result = RunCommandParseJSON(mock_executable("check_inherited_fd"), std::to_string(inherited));
147
+ close(inherited);
148
+ BOOST_CHECK(!result.find_value("inherited").get_bool());
149
+ }
150
+ #endif
151
  #endif // ENABLE_EXTERNAL_SIGNER
152
 
153
  BOOST_AUTO_TEST_SUITE_END()