| 493 | } |
| 494 | |
| 495 | void UMockdevDeviceManager::ueventProcessRead() |
| 496 | { |
| 497 | std::string buffer(4096, 0); |
| 498 | struct iovec iov[1]; |
| 499 | iov[0].iov_base = (void*)&buffer[0]; |
| 500 | iov[0].iov_len = buffer.capacity(); |
| 501 | struct sockaddr_nl peer_sockaddr = { }; |
| 502 | union { |
| 503 | struct cmsghdr header; |
| 504 | uint8_t ucred[CMSG_SPACE(sizeof(struct ucred))]; |
| 505 | } cmsg_un; |
| 506 | cmsg_un.header.cmsg_len = CMSG_LEN(sizeof(struct ucred)); |
| 507 | cmsg_un.header.cmsg_level = SOL_SOCKET; |
| 508 | cmsg_un.header.cmsg_type = SCM_CREDENTIALS; |
| 509 | struct msghdr msg_header = { }; |
| 510 | msg_header.msg_control = cmsg_un.ucred; |
| 511 | msg_header.msg_controllen = sizeof cmsg_un.ucred; |
| 512 | msg_header.msg_iov = iov; |
| 513 | msg_header.msg_iovlen = 1; |
| 514 | msg_header.msg_name = &peer_sockaddr; |
| 515 | msg_header.msg_namelen = sizeof peer_sockaddr; |
| 516 | const int rc = recvmsg(_uevent_fd, &msg_header, MSG_DONTWAIT); |
| 517 | |
| 518 | if (rc <= 0) { |
| 519 | const int saved_errno = errno; |
| 520 | |
| 521 | if (saved_errno == EAGAIN || saved_errno == EWOULDBLOCK) { |
| 522 | USBGUARD_LOG(Warning) << "Read: " |
| 523 | << "reading from uevent source would block thread execution"; |
| 524 | return; |
| 525 | } |
| 526 | else { |
| 527 | USBGUARD_LOG(Error) << "ueventProcessRead: " |
| 528 | << "failed to read pending uevent: " |
| 529 | << "rc=" << rc << " errno=" << saved_errno; |
| 530 | throw ErrnoException("UEvent device manager", "recvmsg", saved_errno); |
| 531 | } |
| 532 | } |
| 533 | |
| 534 | buffer.resize((size_t)rc); |
| 535 | const struct cmsghdr* const cmsg_header = CMSG_FIRSTHDR(&msg_header); |
| 536 | |
| 537 | if (cmsg_header == nullptr) { |
| 538 | /* ignore */ |
| 539 | USBGUARD_LOG(Warning) << "ueventProcessRead: " |
| 540 | << "received uevent without required control message: ignoring."; |
| 541 | return; |
| 542 | } |
| 543 | |
| 544 | if (cmsg_header->cmsg_len != CMSG_LEN(sizeof(struct ucred)) |
| 545 | || cmsg_header->cmsg_level != SOL_SOCKET |
| 546 | || cmsg_header->cmsg_type != SCM_CREDENTIALS) { |
| 547 | /* unexpected control message -- ignore */ |
| 548 | USBGUARD_LOG(Warning) << "ueventProcessRead: " |
| 549 | << "received uevent with an invalid control message: ignoring."; |
| 550 | return; |
| 551 | } |
| 552 |
nothing calls this directly
no test coverage detected