mirror of
https://github.com/troglobit/finit.git
synced 2026-10-01 05:22:48 +07:00
A pass over the whole branch before merge, mostly in libink since that is the new code and the part exposed to the wire. Grouped here rather than scattered so the review is easy to read in one place. libink parser and dispatch: - Bound reader lengths so a 32-bit size_t can't wrap a wire length past the guard and read out of bounds. Reachable pre-auth on any bus, so it matters on the 32-bit targets Finit runs on. - Drop a peer when a reply send fails instead of limping on with a half-written frame; a built-in whose send failed used to fall through and put a second frame on the wire. initctl: - Copy a D-Bus error name out of the reply before closing the client; the reply points into memory the close frees. Both error paths now share one helper so this can't creep back. Authorization: - Take the caller's groups from the kernel (SO_PEERCRED plus SO_PEERGROUPS) rather than getpwuid()/getgrouplist(), which go through NSS and can block PID 1 on a slow LDAP or SSSD backend. The check is now a lookup against the group resolved once at init, with no NSS and no 256 KiB array on the stack. A caller reaching us through a broker carries no group set, so system-bus privileged methods are root-only; the local bus keeps group support. See libink/README.md for the note on lifting that. Shutdown: - Call dbus_exit() from the shutdown path so the server, its peers, and the socket are let go cleanly. The teardown existed but nobody called it. Tests, CI, docs: - A fuzz target for the message parser, run as a quick sweep in the suite and properly under libFuzzer in CI, with the corpus carried between runs. The -as-uid tests drop groups the way a login does so SO_PEERGROUPS sees the right set, and widen the test socket to reach the per-method check behind the 0660 gate. Bring the GitHub actions up to versions that run on Node 24, and tidy a few small things a /simplify pass turned up. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
114 lines
3.9 KiB
C
114 lines
3.9 KiB
C
/* libink — D-Bus wire protocol: message header parsing and building.
|
|
*
|
|
* Copyright (c) 2026 Joachim Wiberg <troglobit@gmail.com>
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
#ifndef LIBINK_PROTO_H_
|
|
#define LIBINK_PROTO_H_
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
#include "link.h" /* LINK_MSG_* type codes */
|
|
|
|
/* Fixed portion of the message header: endian, type, flags, version,
|
|
* body length, serial, and the field-array length -- 16 bytes before
|
|
* the variable header fields begin. */
|
|
#define LINK_HDR_FIXED_SIZE 16
|
|
|
|
/* Message flags. */
|
|
#define LINK_FLAG_NO_REPLY_EXPECTED 0x01
|
|
#define LINK_FLAG_NO_AUTO_START 0x02
|
|
#define LINK_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION 0x04
|
|
|
|
/* Header field codes. */
|
|
#define LINK_HDR_PATH 1
|
|
#define LINK_HDR_INTERFACE 2
|
|
#define LINK_HDR_MEMBER 3
|
|
#define LINK_HDR_ERROR_NAME 4
|
|
#define LINK_HDR_REPLY_SERIAL 5
|
|
#define LINK_HDR_DESTINATION 6
|
|
#define LINK_HDR_SENDER 7
|
|
#define LINK_HDR_SIGNATURE 8
|
|
#define LINK_HDR_UNIX_FDS 9
|
|
|
|
#define LINK_PROTOCOL_VERSION 1
|
|
|
|
/* Parsed view of an incoming message. Pointers reference bytes
|
|
* inside the receiver's own rx buffer; treat as borrowed and short-
|
|
* lived (until the next read of the same connection). */
|
|
struct link_msg {
|
|
uint8_t type;
|
|
uint8_t flags;
|
|
uint8_t endian; /* 'l' or 'B' */
|
|
uint32_t body_len;
|
|
uint32_t serial;
|
|
uint32_t reply_serial;
|
|
|
|
const char *path; /* object path, or NULL */
|
|
const char *interface; /* may be NULL on method calls */
|
|
const char *member;
|
|
const char *error_name;
|
|
const char *destination;
|
|
const char *sender;
|
|
const char *signature; /* may be NULL if body is empty */
|
|
|
|
/* Pointer into the rx buffer and length, after header padding. */
|
|
const uint8_t *body;
|
|
uint32_t body_avail;
|
|
};
|
|
|
|
/* Parse a complete D-Bus message from `buf` of size `len`. On
|
|
* success returns the total number of bytes consumed (header +
|
|
* padding + body) and fills *out. Returns 0 if more bytes are
|
|
* needed, -1 on malformed input. */
|
|
ssize_t __msg_parse(const uint8_t *buf, size_t len, struct link_msg *out);
|
|
|
|
/* Project a parsed message onto the public reply view. Shared by the
|
|
* synchronous client and the connection-side reply routing so the two
|
|
* cannot drift as link_reply_t grows. */
|
|
void __msg_to_reply(link_reply_t *r, const struct link_msg *m);
|
|
|
|
/* Compute the on-wire size of a future message header given the
|
|
* fields we'd populate. Used to size send buffers. */
|
|
size_t __msg_header_size(const struct link_msg *m);
|
|
|
|
/* Build a method-return header into `buf` (capacity `cap`).
|
|
* `reply_serial`/`destination` come from the call being replied to.
|
|
* `signature` is the body signature ("" if no args). `body_len`
|
|
* is the length of the body that will follow the header padding.
|
|
* Returns the number of bytes written, or -1 on overflow. */
|
|
ssize_t __msg_build_return(uint8_t *buf, size_t cap,
|
|
uint32_t serial, uint32_t reply_serial,
|
|
const char *destination,
|
|
const char *signature, uint32_t body_len);
|
|
|
|
/* Build an error reply header. */
|
|
ssize_t __msg_build_error(uint8_t *buf, size_t cap,
|
|
uint32_t serial, uint32_t reply_serial,
|
|
const char *destination,
|
|
const char *error_name,
|
|
const char *signature, uint32_t body_len);
|
|
|
|
/* Build a signal header (no reply expected, no destination). */
|
|
ssize_t __msg_build_signal(uint8_t *buf, size_t cap,
|
|
uint32_t serial,
|
|
const char *path,
|
|
const char *interface,
|
|
const char *member,
|
|
const char *signature, uint32_t body_len);
|
|
|
|
/* Build a method-call header (client side). `destination` is NULL
|
|
* when no broker routes the message. */
|
|
ssize_t __msg_build_method_call(uint8_t *buf, size_t cap,
|
|
uint32_t serial,
|
|
const char *path,
|
|
const char *interface,
|
|
const char *member,
|
|
const char *destination,
|
|
const char *signature,
|
|
uint32_t body_len);
|
|
|
|
#endif /* LIBINK_PROTO_H_ */
|