commit 291ecc472387b3e2c14aeb08563387771faa5192 from: Omar Polo date: Sun Jul 02 10:11:48 2023 UTC sync imsg. commit - 095689b382398c67bdbe8ebf208639626def2882 commit + 291ecc472387b3e2c14aeb08563387771faa5192 blob - 7abea4e0debb0a22243abaa74c5cb9c58e4d06df blob + 750d7c077026ebf7d392ba7308df8a9fe0c25af4 --- compat/imsg/imsg-buffer.c +++ compat/imsg/imsg-buffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: imsg-buffer.c,v 1.14 2022/04/23 08:57:52 tobias Exp $ */ +/* $OpenBSD: imsg-buffer.c,v 1.16 2023/06/19 17:19:50 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -32,15 +33,20 @@ static int ibuf_realloc(struct ibuf *, size_t); static void ibuf_enqueue(struct msgbuf *, struct ibuf *); static void ibuf_dequeue(struct msgbuf *, struct ibuf *); +static void msgbuf_drain(struct msgbuf *, size_t); struct ibuf * ibuf_open(size_t len) { struct ibuf *buf; + if (len == 0) { + errno = EINVAL; + return (NULL); + } if ((buf = calloc(1, sizeof(struct ibuf))) == NULL) return (NULL); - if ((buf->buf = malloc(len)) == NULL) { + if ((buf->buf = calloc(len, 1)) == NULL) { free(buf); return (NULL); } @@ -55,15 +61,23 @@ ibuf_dynamic(size_t len, size_t max) { struct ibuf *buf; - if (max < len) + if (max < len) { + errno = EINVAL; return (NULL); + } - if ((buf = ibuf_open(len)) == NULL) + if ((buf = calloc(1, sizeof(struct ibuf))) == NULL) return (NULL); + if (len > 0) { + if ((buf->buf = calloc(len, 1)) == NULL) { + free(buf); + return (NULL); + } + } + buf->size = len; + buf->max = max; + buf->fd = -1; - if (max > 0) - buf->max = max; - return (buf); } @@ -87,23 +101,6 @@ ibuf_realloc(struct ibuf *buf, size_t len) return (0); } -int -ibuf_add(struct ibuf *buf, const void *data, size_t len) -{ - if (len > SIZE_MAX - buf->wpos) { - errno = ERANGE; - return (-1); - } - - if (buf->wpos + len > buf->size) - if (ibuf_realloc(buf, len) == -1) - return (-1); - - memcpy(buf->buf + buf->wpos, data, len); - buf->wpos += len; - return (0); -} - void * ibuf_reserve(struct ibuf *buf, size_t len) { @@ -120,19 +117,160 @@ ibuf_reserve(struct ibuf *buf, size_t len) b = buf->buf + buf->wpos; buf->wpos += len; + memset(b, 0, len); return (b); } +int +ibuf_add(struct ibuf *buf, const void *data, size_t len) +{ + void *b; + + if ((b = ibuf_reserve(buf, len)) == NULL) + return (-1); + + memcpy(b, data, len); + return (0); +} + +int +ibuf_add_buf(struct ibuf *buf, const struct ibuf *from) +{ + return ibuf_add(buf, from->buf, from->wpos); +} + +int +ibuf_add_n8(struct ibuf *buf, uint64_t value) +{ + uint8_t v; + + if (value > UINT8_MAX) { + errno = EINVAL; + return (-1); + } + v = value; + return ibuf_add(buf, &v, sizeof(v)); +} + +int +ibuf_add_n16(struct ibuf *buf, uint64_t value) +{ + uint16_t v; + + if (value > UINT16_MAX) { + errno = EINVAL; + return (-1); + } + v = htobe16(value); + return ibuf_add(buf, &v, sizeof(v)); +} + +int +ibuf_add_n32(struct ibuf *buf, uint64_t value) +{ + uint32_t v; + + if (value > UINT32_MAX) { + errno = EINVAL; + return (-1); + } + v = htobe32(value); + return ibuf_add(buf, &v, sizeof(v)); +} + +int +ibuf_add_n64(struct ibuf *buf, uint64_t value) +{ + value = htobe64(value); + return ibuf_add(buf, &value, sizeof(value)); +} + +int +ibuf_add_zero(struct ibuf *buf, size_t len) +{ + void *b; + + if ((b = ibuf_reserve(buf, len)) == NULL) + return (-1); + return (0); +} + void * ibuf_seek(struct ibuf *buf, size_t pos, size_t len) { /* only allowed to seek in already written parts */ - if (len > SIZE_MAX - pos || pos + len > buf->wpos) + if (len > SIZE_MAX - pos || pos + len > buf->wpos) { + errno = ERANGE; return (NULL); + } return (buf->buf + pos); } +int +ibuf_set(struct ibuf *buf, size_t pos, const void *data, size_t len) +{ + void *b; + + if ((b = ibuf_seek(buf, pos, len)) == NULL) + return (-1); + + memcpy(b, data, len); + return (0); +} + +int +ibuf_set_n8(struct ibuf *buf, size_t pos, uint64_t value) +{ + uint8_t v; + + if (value > UINT8_MAX) { + errno = EINVAL; + return (-1); + } + v = value; + return (ibuf_set(buf, pos, &v, sizeof(v))); +} + +int +ibuf_set_n16(struct ibuf *buf, size_t pos, uint64_t value) +{ + uint16_t v; + + if (value > UINT16_MAX) { + errno = EINVAL; + return (-1); + } + v = htobe16(value); + return (ibuf_set(buf, pos, &v, sizeof(v))); +} + +int +ibuf_set_n32(struct ibuf *buf, size_t pos, uint64_t value) +{ + uint32_t v; + + if (value > UINT32_MAX) { + errno = EINVAL; + return (-1); + } + v = htobe32(value); + return (ibuf_set(buf, pos, &v, sizeof(v))); +} + +int +ibuf_set_n64(struct ibuf *buf, size_t pos, uint64_t value) +{ + value = htobe64(value); + return (ibuf_set(buf, pos, &value, sizeof(value))); +} + +void * +ibuf_data(struct ibuf *buf) +{ + return (buf->buf); +} + size_t ibuf_size(struct ibuf *buf) { @@ -151,7 +289,46 @@ ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf) ibuf_enqueue(msgbuf, buf); } +void +ibuf_free(struct ibuf *buf) +{ + if (buf == NULL) + return; +#ifdef NOTYET + if (buf->fd != -1) + close(buf->fd); +#endif + freezero(buf->buf, buf->size); + free(buf); +} + int +ibuf_fd_avail(struct ibuf *buf) +{ + return (buf->fd != -1); +} + +int +ibuf_fd_get(struct ibuf *buf) +{ + int fd; + + fd = buf->fd; +#ifdef NOTYET + buf->fd = -1; +#endif + return (fd); +} + +void +ibuf_fd_set(struct ibuf *buf, int fd) +{ + if (buf->fd != -1) + close(buf->fd); + buf->fd = fd; +} + +int ibuf_write(struct msgbuf *msgbuf) { struct iovec iov[IOV_MAX]; @@ -188,15 +365,6 @@ again: } void -ibuf_free(struct ibuf *buf) -{ - if (buf == NULL) - return; - freezero(buf->buf, buf->size); - free(buf); -} - -void msgbuf_init(struct msgbuf *msgbuf) { msgbuf->queued = 0; @@ -204,7 +372,7 @@ msgbuf_init(struct msgbuf *msgbuf) TAILQ_INIT(&msgbuf->bufs); } -void +static void msgbuf_drain(struct msgbuf *msgbuf, size_t n) { struct ibuf *buf, *next; @@ -313,8 +481,10 @@ ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf) { TAILQ_REMOVE(&msgbuf->bufs, buf, entry); - if (buf->fd != -1) + if (buf->fd != -1) { close(buf->fd); + buf->fd = -1; + } msgbuf->queued--; ibuf_free(buf); blob - b381b1edd4711442af6ada9266a4ba09e4c2e000 blob + 73a0cc27e51feaca76ea0aa5b4c23cd681a4cb52 --- compat/imsg/imsg.c +++ compat/imsg/imsg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: imsg.c,v 1.17 2022/01/28 10:41:44 claudio Exp $ */ +/* $OpenBSD: imsg.c,v 1.19 2023/06/19 17:19:50 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -175,8 +175,7 @@ imsg_compose(struct imsgbuf *ibuf, uint32_t type, uint if (imsg_add(wbuf, data, datalen) == -1) return (-1); - wbuf->fd = fd; - + ibuf_fd_set(wbuf, fd); imsg_close(ibuf, wbuf); return (1); @@ -199,14 +198,49 @@ imsg_composev(struct imsgbuf *ibuf, uint32_t type, uin if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1) return (-1); - wbuf->fd = fd; - + ibuf_fd_set(wbuf, fd); imsg_close(ibuf, wbuf); return (1); } -/* ARGSUSED */ +int +imsg_compose_ibuf(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, + pid_t pid, struct ibuf *buf) +{ + struct ibuf *wbuf = NULL; + struct imsg_hdr hdr; + int save_errno; + + if (ibuf_size(buf) + IMSG_HEADER_SIZE > MAX_IMSGSIZE) { + errno = ERANGE; + goto fail; + } + + hdr.type = type; + hdr.len = ibuf_size(buf) + IMSG_HEADER_SIZE; + hdr.flags = 0; + hdr.peerid = peerid; + if ((hdr.pid = pid) == 0) + hdr.pid = ibuf->pid; + + if ((wbuf = ibuf_open(IMSG_HEADER_SIZE)) == NULL) + goto fail; + if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1) + goto fail; + + ibuf_close(&ibuf->w, wbuf); + ibuf_close(&ibuf->w, buf); + return (1); + + fail: + save_errno = errno; + ibuf_free(buf); + ibuf_free(wbuf); + errno = save_errno; + return (-1); +} + struct ibuf * imsg_create(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid, uint16_t datalen) @@ -253,11 +287,10 @@ imsg_close(struct imsgbuf *ibuf, struct ibuf *msg) hdr = (struct imsg_hdr *)msg->buf; hdr->flags &= ~IMSGF_HASFD; - if (msg->fd != -1) + if (ibuf_fd_avail(msg)) hdr->flags |= IMSGF_HASFD; + hdr->len = ibuf_size(msg); - hdr->len = (uint16_t)msg->wpos; - ibuf_close(&ibuf->w, msg); } blob - 9e19bedb893decd22b167421d22c86500cc3d217 blob + fb516e30287318ec10ccdddc451e5d8658db0a12 --- compat/imsg/imsg.h +++ compat/imsg/imsg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: imsg.h,v 1.6 2021/01/13 09:56:28 claudio Exp $ */ +/* $OpenBSD: imsg.h,v 1.7 2023/06/19 17:19:50 claudio Exp $ */ /* * Copyright (c) 2006, 2007 Pierre-Yves Ritschard @@ -80,21 +80,35 @@ struct imsg { struct iovec; -/* buffer.c */ +/* imsg-buffer.c */ struct ibuf *ibuf_open(size_t); struct ibuf *ibuf_dynamic(size_t, size_t); int ibuf_add(struct ibuf *, const void *, size_t); +int ibuf_add_buf(struct ibuf *, const struct ibuf *); +int ibuf_add_zero(struct ibuf *, size_t); +int ibuf_add_n8(struct ibuf *, uint64_t); +int ibuf_add_n16(struct ibuf *, uint64_t); +int ibuf_add_n32(struct ibuf *, uint64_t); +int ibuf_add_n64(struct ibuf *, uint64_t); void *ibuf_reserve(struct ibuf *, size_t); void *ibuf_seek(struct ibuf *, size_t, size_t); +int ibuf_set(struct ibuf *, size_t, const void *, size_t); +int ibuf_set_n8(struct ibuf *, size_t, uint64_t); +int ibuf_set_n16(struct ibuf *, size_t, uint64_t); +int ibuf_set_n32(struct ibuf *, size_t, uint64_t); +int ibuf_set_n64(struct ibuf *, size_t, uint64_t); +void *ibuf_data(struct ibuf *); size_t ibuf_size(struct ibuf *); size_t ibuf_left(struct ibuf *); void ibuf_close(struct msgbuf *, struct ibuf *); -int ibuf_write(struct msgbuf *); void ibuf_free(struct ibuf *); +int ibuf_fd_avail(struct ibuf *); +int ibuf_fd_get(struct ibuf *); +void ibuf_fd_set(struct ibuf *, int); +int ibuf_write(struct msgbuf *); void msgbuf_init(struct msgbuf *); void msgbuf_clear(struct msgbuf *); int msgbuf_write(struct msgbuf *); -void msgbuf_drain(struct msgbuf *, size_t); /* imsg.c */ void imsg_init(struct imsgbuf *, int); @@ -104,6 +118,8 @@ int imsg_compose(struct imsgbuf *, uint32_t, uint32_t const void *, uint16_t); int imsg_composev(struct imsgbuf *, uint32_t, uint32_t, pid_t, int, const struct iovec *, int); +int imsg_compose_ibuf(struct imsgbuf *, uint32_t, uint32_t, pid_t, + struct ibuf *); struct ibuf *imsg_create(struct imsgbuf *, uint32_t, uint32_t, pid_t, uint16_t); int imsg_add(struct ibuf *, const void *, uint16_t); void imsg_close(struct imsgbuf *, struct ibuf *);