+2265. [sec]* fdupont
+ Change the umask to no group write and no other access
+ at the entry of Kea server/agent binaries.
+ CVE:2025-32803
+ (Gitlab #3842, #3832)
+
2264. [sec]* tmark
kea-dhcp4, kea-dhcp6, kea-dhcp-ddns, and kea-ctrl-agent will
now only load hook libraries from the default installation
removed as of libc++ 19.
(Gitlab #3823, #3532)
-
Kea 2.6.2 (stable) released on March 26, 2025
2261. [build] mgodzina
# used.
set -eu
+# Set no group write and no other access umask
+orig_umask=$(umask)
+umask $((orig_umask | 0027))
+
# Shell ${variables} derived from autoconf @variables@. Some depend on others, so mind the order.
prefix="@prefix@"
export prefix
#include <config.h>
#include <agent/ca_controller.h>
#include <exceptions/exceptions.h>
+#include <util/filesystem.h>
#include <cstdlib>
#include <iostream>
using namespace isc::process;
int main(int argc, char* argv[]) {
+ isc::util::file::setUmask();
+
int ret = EXIT_SUCCESS;
// Launch the controller passing in command line arguments.
#include <exceptions/exceptions.h>
#include <log/logger_manager.h>
#include <log/logger_support.h>
+#include <util/filesystem.h>
#include <iostream>
/// The exit value of the program will be EXIT_SUCCESS if there were no
/// errors, EXIT_FAILURE otherwise.
int main(int argc, char* argv[]) {
+ isc::util::file::setUmask();
+
int ret = EXIT_SUCCESS;
// Launch the controller passing in command line arguments.
#include <log/output_option.h>
#include <process/cfgrpt/config_report.h>
#include <process/daemon.h>
+#include <util/filesystem.h>
#include <boost/lexical_cast.hpp>
int
main(int argc, char* argv[]) {
+ isc::util::file::setUmask();
+
int ch;
// The default. Any other values are useful for testing only.
int server_port_number = DHCP4_SERVER_PORT;
#include <log/output_option.h>
#include <process/cfgrpt/config_report.h>
#include <process/daemon.h>
+#include <util/filesystem.h>
#include <boost/lexical_cast.hpp>
int
main(int argc, char* argv[]) {
+ isc::util::file::setUmask();
+
int ch;
// The default. Any other values are useful for testing only.
int server_port_number = DHCP6_SERVER_PORT;
# used.
set -eu
+# Set no group write and no other access umask
+orig_umask=$(umask)
+umask $((orig_umask | 0027))
+
PACKAGE_VERSION="@PACKAGE_VERSION@"
EXTENDED_VERSION="@EXTENDED_VERSION@"
#include <exceptions/exceptions.h>
#include <log/logger_support.h>
#include <log/logger_manager.h>
+#include <util/filesystem.h>
#include <boost/exception/diagnostic_information.hpp>
#include <boost/exception_ptr.hpp>
#include <iostream>
/// The exit value of the program will be EXIT_SUCCESS if there were no
/// errors, EXIT_FAILURE otherwise.
int main(int argc, char* argv[]) {
+ isc::util::file::setUmask();
+
int ret = EXIT_SUCCESS;
try {
// Ask scheduling to not give too much resources to LFC.
#include <config.h>
#include <exceptions/exceptions.h>
+#include <util/filesystem.h>
#include <netconf/netconf_controller.h>
#include <cstdlib>
using namespace std;
int main(int argc, char* argv[]) {
+ isc::util::file::setUmask();
+
int ret = EXIT_SUCCESS;
// Launch the controller passing in command line arguments.
#include <config.h>
+#include <util/filesystem.h>
#include <perfdhcp/avalanche_scen.h>
#include <perfdhcp/basic_scen.h>
#include <perfdhcp/command_options.h>
int
main(int argc, char* argv[]) {
+ isc::util::file::setUmask();
+
int ret_code = 0;
std::string diags;
bool parser_error = true;
return ((statbuf.st_mode & S_IFMT) == S_IFREG);
}
-Umask::Umask(mode_t mask) : orig_umask_(umask(S_IWGRP | S_IWOTH)) {
- umask(orig_umask_ | mask);
-}
-
-Umask::~Umask() {
- umask(orig_umask_);
-}
-
-bool
-isSocket(string const& path) {
- struct stat statbuf;
- if (::stat(path.c_str(), &statbuf) < 0) {
- return (false);
+void
+setUmask() {
+ // No group write and no other access.
+ mode_t mask(S_IWGRP | S_IRWXO);
+ mode_t orig = umask(mask);
+ // Handle the case where the original umask was already more restrictive.
+ if ((orig | mask) != mask) {
+ static_cast<void>(umask(orig | mask));
}
- return ((statbuf.st_mode & S_IFMT) == S_IFSOCK);
}
Path::Path(string const& full_name) {
bool
isFile(const std::string& path);
-/// @brief RAII device to limit access of created files.
-struct Umask {
- /// @brief Constructor
- ///
- /// Set wanted bits in umask.
- Umask(mode_t mask);
-
- /// @brief Destructor.
- ///
- /// Restore umask.
- ~Umask();
-
-private:
- /// @brief Original umask.
- mode_t orig_umask_;
-};
-
-bool
-isSocket(const std::string& path);
+/// @brief Set umask (at least 0027 i.e. no group write and no other access).
+void
+setUmask();
-/// @brief Paths on a filesystem
+/// \brief Paths on a filesystem
struct Path {
/// @brief Constructor
///
EXPECT_FALSE(isFile(TEST_DATA_BUILDDIR));
}
-/// @brief Check Umask.
-TEST_F(FileUtilTest, umask) {
- // Protect the test itself assuming that Umask does what we expect...
- Umask m0(0);
- mode_t orig = umask(0);
- {
- Umask m(S_IROTH);
- EXPECT_EQ(S_IROTH, umask(S_IRWXO));
+/// @brief Test fixture class for testing operations on umask.
+struct UMaskUtilTest : ::testing::Test {
+ /// @brief Constructor.
+ ///
+ /// Cache the original umask value.
+ UMaskUtilTest() : orig_umask_(umask(S_IWGRP | S_IWOTH)) { }
+
+ /// @brief Destructor.
+ ///
+ /// Restore the original umask value.
+ virtual ~UMaskUtilTest() {
+ static_cast<void>(umask(orig_umask_));
}
- EXPECT_EQ(0, umask(orig));
+
+private:
+ /// @brief Original umask.
+ mode_t orig_umask_;
+};
+
+/// @brief Check setUmask from 0000.
+TEST_F(UMaskUtilTest, umask0) {
+ static_cast<void>(umask(0));
+ ASSERT_NO_THROW(setUmask());
+ EXPECT_EQ(S_IWGRP | S_IRWXO, umask(0));
+}
+
+/// @brief Check setUmask from no group access.
+TEST_F(UMaskUtilTest, umask077) {
+ static_cast<void>(umask(S_IRWXG | S_IRWXO));
+ ASSERT_NO_THROW(setUmask());
+ EXPECT_EQ(S_IRWXG | S_IRWXO, umask(0));
}
/// @brief Check that the components are split correctly.