summaryrefslogtreecommitdiff
path: root/net-misc/dhcpcd/files/10.0.5/0003-control-abort-control-recv-path-hangup.patch
blob: de4ee353ccf30775f7e29f3da45b8d4866d59af1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
https://github.com/NetworkConfiguration/dhcpcd/issues/262
https://github.com/NetworkConfiguration/dhcpcd/commit/3b4c71859c45b9405f96a5ee8fce04bd3014b2d0

From 3b4c71859c45b9405f96a5ee8fce04bd3014b2d0 Mon Sep 17 00:00:00 2001
From: Roy Marples <roy@marples.name>
Date: Mon, 13 Nov 2023 10:24:15 +0000
Subject: [PATCH] control: Abort control recv path on hangup

This fixes a crash when we try and re-use it in another function.
--- a/src/control.c
+++ b/src/control.c
@@ -106,7 +106,7 @@ control_hangup(struct fd_list *fd)
 	control_free(fd);
 }
 
-static void
+static int
 control_handle_read(struct fd_list *fd)
 {
 	char buffer[1024];
@@ -117,7 +117,7 @@ control_handle_read(struct fd_list *fd)
 		logerr(__func__);
 	if (bytes == -1 || bytes == 0) {
 		control_hangup(fd);
-		return;
+		return -1;
 	}
 
 #ifdef PRIVSEP
@@ -129,21 +129,23 @@ control_handle_read(struct fd_list *fd)
 		fd->flags &= ~FD_SENDLEN;
 		if (err == -1) {
 			logerr(__func__);
-			return;
+			return 0;
 		}
 		if (err == 1 &&
 		    ps_ctl_sendargs(fd, buffer, (size_t)bytes) == -1) {
 			logerr(__func__);
 			control_free(fd);
+			return -1;
 		}
-		return;
+		return 0;
 	}
 #endif
 
 	control_recvdata(fd, buffer, (size_t)bytes);
+	return 0;
 }
 
-static void
+static int
 control_handle_write(struct fd_list *fd)
 {
 	struct iovec iov[2];
@@ -170,7 +172,7 @@ control_handle_write(struct fd_list *fd)
 			logerr("%s: write", __func__);
 		}
 		control_hangup(fd);
-		return;
+		return -1;
 	}
 
 	TAILQ_REMOVE(&fd->queue, data, next);
@@ -183,7 +185,7 @@ control_handle_write(struct fd_list *fd)
 #endif
 
 	if (TAILQ_FIRST(&fd->queue) != NULL)
-		return;
+		return 0;
 
 #ifdef PRIVSEP
 	if (IN_PRIVSEP_SE(fd->ctx) && !(fd->flags & FD_LISTEN)) {
@@ -196,9 +198,9 @@ control_handle_write(struct fd_list *fd)
 	if (eloop_event_add(fd->ctx->eloop, fd->fd, ELE_READ,
 	    control_handle_data, fd) == -1)
 		logerr("%s: eloop_event_add", __func__);
+	return 0;
 }
 
-
 static void
 control_handle_data(void *arg, unsigned short events)
 {
@@ -207,10 +209,14 @@ control_handle_data(void *arg, unsigned short events)
 	if (!(events & (ELE_READ | ELE_WRITE | ELE_HANGUP)))
 		logerrx("%s: unexpected event 0x%04x", __func__, events);
 
-	if (events & ELE_WRITE && !(events & ELE_HANGUP))
-		control_handle_write(fd);
-	if (events & ELE_READ)
-		control_handle_read(fd);
+	if (events & ELE_WRITE && !(events & ELE_HANGUP)) {
+		if (control_handle_write(fd) == -1)
+			return;
+	}
+	if (events & ELE_READ) {
+		if (control_handle_read(fd) == -1)
+			return;
+	}
 	if (events & ELE_HANGUP)
 		control_hangup(fd);
 }