1 /* 2 * Copyright (C) 2011-2014 Felix Fietkau <nbd@openwrt.org> 3 * 4 * SPDX-License-Identifier: LGPL-2.1-only 5 */ 6 7 #define _GNU_SOURCE 8 9 #include <sys/socket.h> 10 #include <sys/stat.h> 11 #include <sys/types.h> 12 #ifdef FreeBSD 13 #include <sys/param.h> 14 #endif 15 #include <fcntl.h> 16 #include <string.h> 17 #include <syslog.h> 18 19 #include <libubox/usock.h> 20 21 #include "ubusd.h" 22 23 static void ubus_client_cmd_free(struct ubus_client_cmd *cmd); 24 25 static void handle_client_disconnect(struct ubus_client *cl) 26 { 27 struct ubus_msg_buf_list *ubl, *ubl2; 28 struct ubus_client_cmd *cmd, *cmd2; 29 30 list_for_each_entry_safe(cmd, cmd2, &cl->cmd_queue, list) 31 ubus_client_cmd_free(cmd); 32 33 ubusd_monitor_disconnect(cl); 34 ubusd_proto_free_client(cl); 35 36 /* 37 * Freeing the client's objects above can queue new messages for the 38 * disconnecting client itself (e.g. the subscribers-gone notification 39 * sent by ubus_unsubscribe), so the tx queue must be flushed last. 40 */ 41 list_for_each_entry_safe(ubl, ubl2, &cl->tx_queue, list) 42 ubus_msg_list_free(ubl); 43 if (cl->pending_msg_fd >= 0) 44 close(cl->pending_msg_fd); 45 if (cl->pending_msg) 46 ubus_msg_free(cl->pending_msg); 47 uloop_fd_delete(&cl->sock); 48 close(cl->sock.fd); 49 free(cl); 50 } 51 52 static void ubus_client_cmd_free(struct ubus_client_cmd *cmd) 53 { 54 list_del(&cmd->list); 55 ubus_msg_free(cmd->msg); 56 free(cmd->lookup_path); 57 free(cmd); 58 } 59 60 static void ubus_client_cmd_queue_process(struct ubus_client *cl) 61 { 62 struct ubus_client_cmd *cmd, *tmp; 63 64 list_for_each_entry_safe(cmd, tmp, &cl->cmd_queue, list) { 65 int ret = ubusd_cmd_lookup(cl, cmd); 66 67 /* Stop if the last command caused buffering again */ 68 if (ret == -2) 69 break; 70 71 ubus_client_cmd_free(cmd); 72 } 73 } 74 75 static int ubusd_recv_fd(struct msghdr *msghdr) 76 { 77 struct cmsghdr *cmsg; 78 79 for (cmsg = CMSG_FIRSTHDR(msghdr); cmsg; cmsg = CMSG_NXTHDR(msghdr, cmsg)) { 80 if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) 81 continue; 82 if (cmsg->cmsg_len < CMSG_LEN(sizeof(int))) 83 continue; 84 85 return *(int *) CMSG_DATA(cmsg); 86 } 87 88 return -1; 89 } 90 91 static void client_cb(struct uloop_fd *sock, unsigned int events) 92 { 93 struct ubus_client *cl = container_of(sock, struct ubus_client, sock); 94 uint8_t fd_buf[CMSG_SPACE(sizeof(int))] = { 0 }; 95 struct msghdr msghdr = { 0 }; 96 struct ubus_msg_buf *ub; 97 struct ubus_msg_buf_list *ubl, *ubl2; 98 static struct iovec iov; 99 100 msghdr.msg_iov = &iov; 101 msghdr.msg_iovlen = 1; 102 103 /* first try to tx more pending data */ 104 list_for_each_entry_safe(ubl, ubl2, &cl->tx_queue, list) { 105 ssize_t written; 106 107 ub = ubl->msg; 108 retry_writev: 109 written = ubus_msg_writev(sock->fd, ub, cl->txq_ofs); 110 if (written < 0) { 111 switch(errno) { 112 case EINTR: 113 goto retry_writev; 114 case EAGAIN: 115 case EACCES: 116 break; 117 default: 118 goto disconnect; 119 } 120 break; 121 } 122 123 cl->txq_ofs += written; 124 cl->txq_len -= written; 125 if (cl->txq_ofs < ub->len + sizeof(ub->hdr)) 126 goto retry_writev; 127 128 cl->txq_ofs = 0; 129 ubus_msg_list_free(ubl); 130 } 131 132 if (list_empty(&cl->tx_queue) && (events & ULOOP_WRITE)) { 133 /* Process queued commands */ 134 ubus_client_cmd_queue_process(cl); 135 136 /* prevent further ULOOP_WRITE events if we don't have data 137 * to send anymore */ 138 if (list_empty(&cl->tx_queue)) 139 uloop_fd_add(sock, ULOOP_READ | ULOOP_EDGE_TRIGGER); 140 } 141 142 retry: 143 if (!sock->eof && cl->pending_msg_offset < (int) sizeof(cl->hdrbuf)) { 144 int offset = cl->pending_msg_offset; 145 int bytes; 146 147 iov.iov_base = ((char *) &cl->hdrbuf) + offset; 148 iov.iov_len = sizeof(cl->hdrbuf) - offset; 149 150 msghdr.msg_control = fd_buf; 151 msghdr.msg_controllen = cl->pending_msg_fd < 0 ? sizeof(fd_buf) : 0; 152 153 bytes = recvmsg(sock->fd, &msghdr, 0); 154 if (bytes < 0) 155 goto out; 156 157 if (cl->pending_msg_fd < 0) { 158 int fd = ubusd_recv_fd(&msghdr); 159 160 if (fd >= 0) 161 cl->pending_msg_fd = fd; 162 } 163 164 cl->pending_msg_offset += bytes; 165 if (cl->pending_msg_offset < (int) sizeof(cl->hdrbuf)) 166 goto out; 167 168 if (blob_raw_len(&cl->hdrbuf.data) < sizeof(struct blob_attr)) 169 goto disconnect; 170 if (blob_pad_len(&cl->hdrbuf.data) > UBUS_MAX_MSGLEN) 171 goto disconnect; 172 173 cl->pending_msg = ubus_msg_new(NULL, blob_raw_len(&cl->hdrbuf.data), false); 174 if (!cl->pending_msg) 175 goto disconnect; 176 177 cl->hdrbuf.hdr.seq = be16_to_cpu(cl->hdrbuf.hdr.seq); 178 cl->hdrbuf.hdr.peer = be32_to_cpu(cl->hdrbuf.hdr.peer); 179 180 memcpy(&cl->pending_msg->hdr, &cl->hdrbuf.hdr, sizeof(cl->hdrbuf.hdr)); 181 memcpy(cl->pending_msg->data, &cl->hdrbuf.data, sizeof(cl->hdrbuf.data)); 182 } 183 184 ub = cl->pending_msg; 185 if (ub) { 186 /* 187 * offset and len derive from client-controlled input, but the 188 * read stays within bounds: ub->data was allocated with exactly 189 * blob_raw_len(ub->data) bytes (already capped at UBUS_MAX_MSGLEN 190 * when the header was received), and offset only grows until it 191 * reaches that total, at which point the message is accepted and 192 * pending_msg is reset below. So offset <= blob_raw_len(ub->data) 193 * and offset + len never exceed the allocation. 194 */ 195 int offset = cl->pending_msg_offset - sizeof(ub->hdr); 196 int len = blob_raw_len(ub->data) - offset; 197 int bytes = 0; 198 199 if (len > 0) { 200 bytes = read(sock->fd, (char *) ub->data + offset, len); 201 if (bytes <= 0) 202 goto out; 203 } 204 205 if (bytes < len) { 206 cl->pending_msg_offset += bytes; 207 goto out; 208 } 209 210 /* accept message */ 211 ub->fd = cl->pending_msg_fd; 212 cl->pending_msg_fd = -1; 213 cl->pending_msg_offset = 0; 214 cl->pending_msg = NULL; 215 ubusd_monitor_message(cl, ub, false); 216 ubusd_proto_receive_message(cl, ub); 217 goto retry; 218 } 219 220 out: 221 if (!sock->eof || !list_empty(&cl->tx_queue)) 222 return; 223 224 disconnect: 225 handle_client_disconnect(cl); 226 } 227 228 static bool get_next_connection(int fd) 229 { 230 struct ubus_client *cl; 231 int client_fd; 232 233 client_fd = accept(fd, NULL, 0); 234 if (client_fd < 0) { 235 switch (errno) { 236 case ECONNABORTED: 237 case EINTR: 238 return true; 239 default: 240 return false; 241 } 242 } 243 244 cl = ubusd_proto_new_client(client_fd, client_cb); 245 if (cl) 246 uloop_fd_add(&cl->sock, ULOOP_READ | ULOOP_EDGE_TRIGGER); 247 else 248 close(client_fd); 249 250 return true; 251 } 252 253 static void server_cb(struct uloop_fd *fd, unsigned int events) 254 { 255 bool next; 256 257 do { 258 next = get_next_connection(fd->fd); 259 } while (next); 260 } 261 262 static struct uloop_fd server_fd = { 263 .cb = server_cb, 264 }; 265 266 static int usage(const char *progname) 267 { 268 fprintf(stderr, "Usage: %s [<options>]\n" 269 "Options: \n" 270 " -A <path>: Set the path to ACL files\n" 271 " -s <socket>: Set the unix domain socket to listen on\n" 272 "\n", progname); 273 return 1; 274 } 275 276 static int sighup_pipe[2] = { -1, -1 }; 277 278 static void sighup_handler(int sig) 279 { 280 int saved_errno = errno; 281 char c = 0; 282 ssize_t r = write(sighup_pipe[1], &c, sizeof(c)); 283 (void)r; 284 errno = saved_errno; 285 } 286 287 static void sighup_fd_cb(struct uloop_fd *ufd, unsigned int events) 288 { 289 char buf[16]; 290 while (read(ufd->fd, buf, sizeof(buf)) > 0) 291 ; 292 ubusd_acl_load(); 293 } 294 295 static struct uloop_fd sighup_ufd = { 296 .cb = sighup_fd_cb, 297 }; 298 299 /* 300 * Best effort only: the -s option may point somewhere else entirely, and 301 * usock() reports a clear error if the requested socket path is unusable. 302 */ 303 static void mkdir_sockdir(void) 304 { 305 char *ubus_sock_dir, *tmp; 306 307 ubus_sock_dir = strdup(UBUS_UNIX_SOCKET); 308 if (!ubus_sock_dir) 309 return; 310 311 tmp = strrchr(ubus_sock_dir, '/'); 312 if (tmp) { 313 *tmp = '\0'; 314 if (mkdir(ubus_sock_dir, 0755) && errno == EEXIST) { 315 struct stat st; 316 317 if (stat(ubus_sock_dir, &st) || !S_ISDIR(st.st_mode)) 318 fprintf(stderr, "%s exists but is not a directory\n", 319 ubus_sock_dir); 320 } 321 } 322 323 free(ubus_sock_dir); 324 } 325 326 #include <libubox/ulog.h> 327 328 int main(int argc, char **argv) 329 { 330 const char *ubus_socket = UBUS_UNIX_SOCKET; 331 int ret = 0; 332 int ch; 333 334 signal(SIGPIPE, SIG_IGN); 335 336 #ifdef __linux__ 337 ret = pipe2(sighup_pipe, O_NONBLOCK | O_CLOEXEC); 338 #else 339 ret = pipe(sighup_pipe); 340 if (ret == 0) { 341 fcntl(sighup_pipe[0], F_SETFL, O_NONBLOCK); 342 fcntl(sighup_pipe[0], F_SETFD, FD_CLOEXEC); 343 fcntl(sighup_pipe[1], F_SETFL, O_NONBLOCK); 344 fcntl(sighup_pipe[1], F_SETFD, FD_CLOEXEC); 345 } 346 #endif 347 if (ret == 0) 348 signal(SIGHUP, sighup_handler); 349 else 350 signal(SIGHUP, SIG_IGN); 351 352 ulog_open(ULOG_KMSG | ULOG_SYSLOG, LOG_DAEMON, "ubusd"); 353 openlog("ubusd", LOG_PID, LOG_DAEMON); 354 uloop_init(); 355 356 if (sighup_pipe[0] >= 0) { 357 sighup_ufd.fd = sighup_pipe[0]; 358 uloop_fd_add(&sighup_ufd, ULOOP_READ); 359 } 360 361 while ((ch = getopt(argc, argv, "A:s:")) != -1) { 362 switch (ch) { 363 case 's': 364 ubus_socket = optarg; 365 break; 366 case 'A': 367 ubusd_acl_dir = optarg; 368 break; 369 default: 370 return usage(argv[0]); 371 } 372 } 373 374 mkdir_sockdir(); 375 unlink(ubus_socket); 376 umask(0111); 377 server_fd.fd = usock(USOCK_UNIX | USOCK_SERVER | USOCK_NONBLOCK, ubus_socket, NULL); 378 if (server_fd.fd < 0) { 379 perror("usock"); 380 ret = -1; 381 goto out; 382 } 383 uloop_fd_add(&server_fd, ULOOP_READ | ULOOP_EDGE_TRIGGER); 384 ubusd_acl_load(); 385 386 uloop_run(); 387 unlink(ubus_socket); 388 389 out: 390 uloop_done(); 391 return ret; 392 } 393
This page was automatically generated by LXR 0.3.1. • OpenWrt