Fix heartbeat device treatment.
authorTatsuo Ishii <ishii@postgresql.org>
Sat, 14 Jun 2025 11:12:57 +0000 (20:12 +0900)
committerTatsuo Ishii <ishii@postgresql.org>
Sat, 14 Jun 2025 11:29:17 +0000 (20:29 +0900)
wd_create_hb_recv_socket() and wd_create_hb_send_socket() called
setsockopt(2) with wrong argument.

struct ifreq i;
strlcpy(i.ifr_name, hb_if->if_name, sizeof(i.ifr_name));
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &i, sizeof(i)) == -1)
:

This is not quite correct since the 4th argument should be
just a null terminated string (device name), not struct ifreq.

Discussion: [pgpool-hackers: 4602] heartbeat and SO_BINDTODEVICE
https://www.pgpool.net/pipermail/pgpool-hackers/2025-May/004603.html
Backpatch-through: v4.6

src/watchdog/wd_heartbeat.c

index 28a01d290d9e5d15e169660b1f6fd3a53aa084d6..09b1ef559426b0b610b246d93b9814c5eb856f10 100644 (file)
@@ -203,11 +203,8 @@ wd_create_hb_send_socket(WdHbIf * hb_if)
                {
                        if (geteuid() == 0) /* check root privileges */
                        {
-                               struct ifreq i;
-
-                               strlcpy(i.ifr_name, hb_if->if_name, sizeof(i.ifr_name));
-
-                               if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &i, sizeof(i)) == -1)
+                               if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE,
+                                                          hb_if->if_name, strlen(hb_if->if_name)) == -1)
                                {
                                        close(sock);
                                        ereport(ERROR,
@@ -217,7 +214,7 @@ wd_create_hb_send_socket(WdHbIf * hb_if)
                                }
                                ereport(LOG,
                                                (errmsg("creating socket for sending heartbeat"),
-                                                errdetail("bind send socket to device: %s", i.ifr_name)));
+                                                errdetail("bind send socket to device: %s", hb_if->if_name)));
                        }
                        else
                                ereport(LOG,
@@ -336,11 +333,8 @@ wd_create_hb_recv_socket(WdHbIf * hb_if)
                        {
                                if (geteuid() == 0) /* check root privileges */
                                {
-                                       struct ifreq i;
-
-                                       strlcpy(i.ifr_name, hb_if->if_name, sizeof(i.ifr_name));
-
-                                       if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &i, sizeof(i)) == -1)
+                                       if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE,
+                                                                  hb_if->if_name, strlen(hb_if->if_name)) == -1)
                                        {
                                                ereport(LOG,
                                                                (errmsg("failed to create watchdog heartbeat receive socket"),
@@ -350,7 +344,7 @@ wd_create_hb_recv_socket(WdHbIf * hb_if)
                                        }
                                        ereport(LOG,
                                                        (errmsg("creating watchdog heartbeat receive socket."),
-                                                        errdetail("bind receive socket to device: \"%s\"", i.ifr_name)));
+                                                        errdetail("bind receive socket to device: \"%s\"", hb_if->if_name)));
                                }
                                else
                                {