]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3506] Fixed lock code
authorFrancis Dupont <fdupont@isc.org>
Mon, 2 Sep 2024 08:04:16 +0000 (10:04 +0200)
committerFrancis Dupont <fdupont@isc.org>
Fri, 20 Sep 2024 12:55:54 +0000 (14:55 +0200)
src/lib/config/unix_command_mgr.cc

index 77fa87e7800f971be592bcd7d7caf134c6a7ed94..43fc24c789aac682b3e51535629b1c0c45719109 100644 (file)
@@ -573,11 +573,8 @@ UnixCommandMgrImpl::openCommandSocket(const isc::data::ConstElementPtr& socket_i
 
     // First let's open lock file.
     std::string lock_name = getLockName();
-    if (lock_fd_ != -1) {
-        close(lock_fd_);
-    }
-    lock_fd_ = open(lock_name.c_str(), O_RDONLY | O_CREAT, 0600);
-    if (lock_fd_ == -1) {
+    int new_lock_fd = open(lock_name.c_str(), O_RDONLY | O_CREAT, 0600);
+    if (new_lock_fd == -1) {
         std::string errmsg = strerror(errno);
         isc_throw(SocketError, "cannot create socket lockfile, "
                   << lock_name  << ", : " << errmsg);
@@ -585,13 +582,12 @@ UnixCommandMgrImpl::openCommandSocket(const isc::data::ConstElementPtr& socket_i
 
     // Try to acquire lock. If we can't somebody else is actively
     // using it.
-    int ret = flock(lock_fd_, LOCK_EX | LOCK_NB);
+    int ret = flock(new_lock_fd, LOCK_EX | LOCK_NB);
     if (ret != 0) {
         std::string errmsg = strerror(errno);
+        close(new_lock_fd);
         isc_throw(SocketError, "cannot lock socket lockfile, "
                   << lock_name  << ", : " << errmsg);
-        close(lock_fd_);
-        lock_fd_ = -1;
     }
 
     // We have the lock, so let's remove the pre-existing socket
@@ -601,6 +597,12 @@ UnixCommandMgrImpl::openCommandSocket(const isc::data::ConstElementPtr& socket_i
     LOG_INFO(command_logger, COMMAND_ACCEPTOR_START)
         .arg(socket_name_);
 
+    // Close previous lock to avoid file descriptor leak.
+    if (lock_fd_ != -1) {
+        close(lock_fd_);
+    }
+    lock_fd_ = new_lock_fd;
+
     try {
         // Start asynchronous acceptor service.
         acceptor_.reset(new UnixDomainSocketAcceptor(io_service_));