Skip to content

Commit 16a0bfb

Browse files
committed
Move the vars for reading onto the stack and off the context
1 parent cd75b08 commit 16a0bfb

File tree

3 files changed

+46
-97
lines changed

3 files changed

+46
-97
lines changed

src/privsep-root.c

Lines changed: 46 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,18 @@ struct psr_ctx {
7171
struct psr_error psr_error;
7272
size_t psr_datalen;
7373
void *psr_data;
74-
size_t psr_mdatalen;
75-
void *psr_mdata;
76-
bool psr_usemdata;
74+
bool psr_mallocdata;
7775
};
7876

7977
static ssize_t
80-
ps_root_readerrorcb(struct psr_ctx *psr_ctx)
78+
ps_root_readerrorcb(struct psr_ctx *pc)
8179
{
82-
struct dhcpcd_ctx *ctx = psr_ctx->psr_ctx;
80+
struct dhcpcd_ctx *ctx = pc->psr_ctx;
8381
int fd = PS_ROOT_FD(ctx);
84-
struct psr_error *psr_error = &psr_ctx->psr_error;
82+
struct psr_error *psr_error = &pc->psr_error;
8583
struct iovec iov[] = {
8684
{ .iov_base = psr_error, .iov_len = sizeof(*psr_error) },
87-
{ .iov_base = NULL, .iov_len = 0 },
85+
{ .iov_base = pc->psr_data, .iov_len = pc->psr_datalen },
8886
};
8987
struct msghdr msg = { .msg_iov = iov, .msg_iovlen = __arraycount(iov) };
9088
ssize_t len;
@@ -99,8 +97,12 @@ ps_root_readerrorcb(struct psr_ctx *psr_ctx)
9997
if (eloop_waitfd(fd) == -1)
10098
PSR_ERROR(errno);
10199

100+
if (!pc->psr_mallocdata)
101+
goto recv;
102+
102103
/* We peek at the psr_error structure to tell us how much of a buffer
103104
* we need to read the whole packet. */
105+
msg.msg_iovlen--;
104106
len = recvmsg(fd, &msg, MSG_PEEK | MSG_WAITALL);
105107
if (len == -1)
106108
PSR_ERROR(errno);
@@ -114,35 +116,18 @@ ps_root_readerrorcb(struct psr_ctx *psr_ctx)
114116
PSR_ERROR(EINVAL);
115117
}
116118

117-
if (psr_ctx->psr_usemdata &&
118-
psr_error->psr_datalen > psr_ctx->psr_mdatalen)
119-
{
120-
void *d = realloc(psr_ctx->psr_mdata, psr_error->psr_datalen);
121-
122-
/* If we failed to realloc then psr_mdatalen will be smaller
123-
* than psr_datalen.
124-
* The following recvmsg will get MSG_TRUNC so the malloc error
125-
* will be reported there but more importantly the
126-
* message will be correctly discarded from the queue. */
127-
if (d != NULL) {
128-
psr_ctx->psr_mdata = d;
129-
psr_ctx->psr_mdatalen = psr_error->psr_datalen;
130-
}
131-
}
132-
if (psr_error->psr_datalen != 0) {
133-
/* Set our buffers */
134-
if (psr_ctx->psr_usemdata) {
135-
iov[1].iov_base = psr_ctx->psr_mdata;
136-
iov[1].iov_len = psr_ctx->psr_mdatalen;
137-
} else {
138-
iov[1].iov_base = psr_ctx->psr_data;
139-
iov[1].iov_len = psr_ctx->psr_datalen;
140-
}
141-
/* We might require less than the buffer size */
142-
if (iov[1].iov_len > psr_error->psr_datalen)
143-
iov[1].iov_len = psr_error->psr_datalen;
119+
/* No data to read? Unlikely but ... */
120+
if (psr_error->psr_datalen == 0)
121+
goto recv;
122+
123+
pc->psr_data = malloc(psr_error->psr_datalen);
124+
if (pc->psr_data != NULL) {
125+
iov[1].iov_base = pc->psr_data;
126+
iov[1].iov_len = psr_error->psr_datalen;
127+
msg.msg_iovlen++;
144128
}
145129

130+
recv:
146131
len = recvmsg(fd, &msg, MSG_WAITALL);
147132
if (len == -1)
148133
PSR_ERROR(errno);
@@ -161,42 +146,35 @@ ps_root_readerrorcb(struct psr_ctx *psr_ctx)
161146
ssize_t
162147
ps_root_readerror(struct dhcpcd_ctx *ctx, void *data, size_t len)
163148
{
164-
struct psr_ctx *pc = ctx->ps_root->psp_data;
149+
struct psr_ctx pc = {
150+
.psr_ctx = ctx,
151+
.psr_data = data,
152+
.psr_datalen = len,
153+
.psr_mallocdata = false
154+
};
165155

166-
pc->psr_data = data;
167-
pc->psr_datalen = len;
168-
pc->psr_usemdata = false;
169-
ps_root_readerrorcb(pc);
156+
ps_root_readerrorcb(&pc);
170157

171-
errno = pc->psr_error.psr_errno;
172-
return pc->psr_error.psr_result;
158+
errno = pc.psr_error.psr_errno;
159+
return pc.psr_error.psr_result;
173160
}
174161

175162
ssize_t
176163
ps_root_mreaderror(struct dhcpcd_ctx *ctx, void **data, size_t *len)
177164
{
178-
struct psr_ctx *pc = ctx->ps_root->psp_data;
179-
void *d;
165+
struct psr_ctx pc = {
166+
.psr_ctx = ctx,
167+
.psr_data = NULL,
168+
.psr_datalen = 0,
169+
.psr_mallocdata = true
170+
};
180171

181-
pc->psr_usemdata = true;
182-
ps_root_readerrorcb(pc);
172+
ps_root_readerrorcb(&pc);
183173

184-
if (pc->psr_error.psr_datalen != 0) {
185-
if (pc->psr_error.psr_datalen > pc->psr_mdatalen) {
186-
errno = EINVAL;
187-
return -1;
188-
}
189-
d = malloc(pc->psr_error.psr_datalen);
190-
if (d == NULL)
191-
return -1;
192-
memcpy(d, pc->psr_mdata, pc->psr_error.psr_datalen);
193-
} else
194-
d = NULL;
195-
196-
errno = pc->psr_error.psr_errno;
197-
*data = d;
198-
*len = pc->psr_error.psr_datalen;
199-
return pc->psr_error.psr_result;
174+
errno = pc.psr_error.psr_errno;
175+
*data = pc.psr_data;
176+
*len = pc.psr_error.psr_datalen;
177+
return pc.psr_error.psr_result;
200178
}
201179

202180
static ssize_t
@@ -220,6 +198,8 @@ ps_root_writeerror(struct dhcpcd_ctx *ctx, ssize_t result,
220198
logdebugx("%s: result %zd errno %d", __func__, result, errno);
221199
#endif
222200

201+
if (len == 0)
202+
msg.msg_iovlen = 1;
223203
err = sendmsg(fd, &msg, MSG_EOR);
224204

225205
/* Error sending the message? Try sending the error of sending. */
@@ -228,8 +208,8 @@ ps_root_writeerror(struct dhcpcd_ctx *ctx, ssize_t result,
228208
__func__, result, data, len);
229209
psr.psr_result = err;
230210
psr.psr_errno = errno;
231-
iov[1].iov_base = NULL;
232-
iov[1].iov_len = 0;
211+
psr.psr_datalen = 0;
212+
msg.msg_iovlen = 1;
233213
err = sendmsg(fd, &msg, MSG_EOR);
234214
}
235215

@@ -626,7 +606,7 @@ ps_root_recvmsgcb(void *arg, struct ps_msghdr *psm, struct msghdr *msg)
626606
break;
627607
}
628608

629-
err = ps_root_writeerror(ctx, err, rlen != 0 ? rdata : 0, rlen);
609+
err = ps_root_writeerror(ctx, err, rdata, rlen);
630610
if (free_rdata)
631611
free(rdata);
632612
return err;
@@ -867,17 +847,6 @@ ps_root_log(void *arg, unsigned short events)
867847
logerr(__func__);
868848
}
869849

870-
static void
871-
ps_root_freepsdata(void *arg)
872-
{
873-
struct psr_ctx *pc = arg;
874-
875-
if (pc == NULL)
876-
return;
877-
free(pc->psr_mdata);
878-
free(pc);
879-
}
880-
881850
pid_t
882851
ps_root_start(struct dhcpcd_ctx *ctx)
883852
{
@@ -888,7 +857,6 @@ ps_root_start(struct dhcpcd_ctx *ctx)
888857
struct ps_process *psp;
889858
int logfd[2] = { -1, -1}, datafd[2] = { -1, -1};
890859
pid_t pid;
891-
struct psr_ctx *pc;
892860

893861
if (xsocketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CXNB, 0, logfd) == -1)
894862
return -1;
@@ -907,27 +875,15 @@ ps_root_start(struct dhcpcd_ctx *ctx)
907875
return -1;
908876
#endif
909877

910-
pc = calloc(1, sizeof(*pc));
911-
if (pc == NULL)
912-
return -1;
913-
pc->psr_ctx = ctx;
914-
915878
psp = ctx->ps_root = ps_newprocess(ctx, &id);
916879
if (psp == NULL)
917-
{
918-
free(pc);
919880
return -1;
920-
}
921-
psp->psp_freedata = ps_root_freepsdata;
881+
922882
strlcpy(psp->psp_name, "privileged proxy", sizeof(psp->psp_name));
923883
pid = ps_startprocess(psp, ps_root_recvmsg, NULL,
924884
ps_root_startcb, PSF_ELOOP);
925-
if (pid == -1) {
926-
free(pc);
885+
if (pid == -1)
927886
return -1;
928-
}
929-
930-
psp->psp_data = pc;
931887

932888
if (pid == 0) {
933889
ctx->ps_log_fd = logfd[0]; /* Keep open to pass to processes */

src/privsep.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -761,11 +761,6 @@ ps_freeprocess(struct ps_process *psp)
761761

762762
TAILQ_REMOVE(&ctx->ps_processes, psp, next);
763763

764-
if (psp->psp_freedata != NULL)
765-
psp->psp_freedata(psp->psp_data);
766-
else
767-
free(psp->psp_data);
768-
769764
if (psp->psp_fd != -1) {
770765
eloop_event_delete(ctx->eloop, psp->psp_fd);
771766
close(psp->psp_fd);

src/privsep.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,6 @@ struct ps_process {
184184
char psp_name[PSP_NAMESIZE];
185185
uint16_t psp_proto;
186186
const char *psp_protostr;
187-
void *psp_data;
188-
void (*psp_freedata)(void *);
189187
bool psp_started;
190188

191189
#ifdef INET

0 commit comments

Comments
 (0)