From 1f433cb0ffd0b0b44de38180ecf6d4b7f38a8273 Mon Sep 17 00:00:00 2001 From: Sharvil Nanavati Date: Mon, 20 Jun 2016 19:16:12 -0700 Subject: [PATCH] DO NOT MERGE Fix potential DoS caused by delivering signal to BT process Bug: 28885210 Change-Id: I63866d894bfca47464d6e42e3fb0357c4f94d360 --- audio_a2dp_hw/audio_a2dp_hw.c | 22 +++++------ btif/co/bta_hh_co.c | 10 ++--- btif/co/bta_hl_co.c | 3 +- btif/src/btif_core.c | 5 ++- btif/src/btif_dm.c | 3 +- btif/src/btif_hh.c | 4 +- btif/src/btif_hl.c | 14 +++---- btif/src/btif_pan.c | 22 +++++------ btif/src/btif_rc.c | 19 ++++----- btif/src/btif_sock_l2cap.c | 10 ++--- btif/src/btif_sock_rfc.c | 14 +++---- btif/src/btif_sock_thread.c | 20 +++++----- btif/src/btif_sock_util.c | 6 +-- gki/ulinux/gki_ulinux.c | 2 +- hci/src/btsnoop.c | 6 +-- hci/src/btsnoop_net.c | 6 +-- hci/src/hci_hal_h4.c | 2 +- hci/src/hci_hal_mct.c | 2 +- hci/src/hci_layer.c | 3 +- hci/test/hci_hal_h4_test.cpp | 16 ++++---- hci/test/hci_hal_mct_test.cpp | 8 ++-- osi/src/config.c | 90 +++++++++++++++++++++++++++++++++++------- osi/src/eager_reader.c | 4 +- osi/src/reactor.c | 2 +- osi/src/semaphore.c | 6 +-- osi/src/socket.c | 10 ++--- osi/test/alarm_test.cpp | 2 +- osi/test/atomic_test.cpp | 6 +-- osi/test/eager_reader_test.cpp | 4 +- osi/test/reactor_test.cpp | 4 +- test/suite/support/callbacks.h | 6 ++- tools/hci/main.c | 9 +++-- udrv/ulinux/uipc.c | 20 +++++----- 33 files changed, 214 insertions(+), 146 deletions(-) diff --git a/audio_a2dp_hw/audio_a2dp_hw.c b/audio_a2dp_hw/audio_a2dp_hw.c index d0b36a0a9..4e58b3f9a 100644 --- a/audio_a2dp_hw/audio_a2dp_hw.c +++ b/audio_a2dp_hw/audio_a2dp_hw.c @@ -242,7 +242,7 @@ static int skt_read(int fd, void *p, size_t len) ts_log("skt_read recv", len, NULL); - if ((read = recv(fd, p, len, MSG_NOSIGNAL)) == -1) + if ((read = TEMP_FAILURE_RETRY(recv(fd, p, len, MSG_NOSIGNAL))) == -1) { ERROR("write failed with errno=%d\n", errno); return -1; @@ -264,12 +264,12 @@ static int skt_write(int fd, const void *p, size_t len) /* poll for 500 ms */ /* send time out */ - if (poll(&pfd, 1, 500) == 0) + if (TEMP_FAILURE_RETRY(poll(&pfd, 1, 500)) == 0) return 0; ts_log("skt_write", len, NULL); - if ((sent = send(fd, p, len, MSG_NOSIGNAL)) == -1) + if ((sent = TEMP_FAILURE_RETRY(send(fd, p, len, MSG_NOSIGNAL))) == -1) { ERROR("write failed with errno=%d\n", errno); return -1; @@ -300,14 +300,14 @@ static int skt_disconnect(int fd) static int a2dp_ctrl_receive(struct a2dp_stream_common *common, void* buffer, int length) { - int ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL); + int ret = TEMP_FAILURE_RETRY(recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL)); if (ret < 0) { ERROR("ack failed (%s)", strerror(errno)); if (errno == EINTR) { /* retry again */ - ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL); + ret = TEMP_FAILURE_RETRY(recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL)); if (ret < 0) { ERROR("ack failed (%s)", strerror(errno)); @@ -334,7 +334,7 @@ static int a2dp_command(struct a2dp_stream_common *common, char cmd) DEBUG("A2DP COMMAND %s", dump_a2dp_ctrl_event(cmd)); /* send command */ - if (send(common->ctrl_fd, &cmd, 1, MSG_NOSIGNAL) == -1) + if (TEMP_FAILURE_RETRY(send(common->ctrl_fd, &cmd, 1, MSG_NOSIGNAL)) == -1) { ERROR("cmd failed (%s)", strerror(errno)); skt_disconnect(common->ctrl_fd); @@ -407,13 +407,13 @@ static void a2dp_open_ctrl_path(struct a2dp_stream_common *common) break; ERROR("error : a2dp not ready, wait 250 ms and retry"); - usleep(250000); + TEMP_FAILURE_RETRY(usleep(250000)); skt_disconnect(common->ctrl_fd); common->ctrl_fd = AUDIO_SKT_DISCONNECTED; } /* ctrl channel not ready, wait a bit */ - usleep(250000); + TEMP_FAILURE_RETRY(usleep(250000)); } } @@ -576,7 +576,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, DEBUG("emulate a2dp write delay (%d us)", us_delay); - usleep(us_delay); + TEMP_FAILURE_RETRY(usleep(us_delay)); pthread_mutex_unlock(&out->common.lock); return -1; } @@ -950,7 +950,7 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, DEBUG("emulate a2dp read delay (%d us)", us_delay); - usleep(us_delay); + TEMP_FAILURE_RETRY(usleep(us_delay)); pthread_mutex_unlock(&in->common.lock); return -1; } @@ -1077,7 +1077,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev, DEBUG("success"); /* Delay to ensure Headset is in proper state when START is initiated from DUT immediately after the connection due to ongoing music playback. */ - usleep(250000); + TEMP_FAILURE_RETRY(usleep(250000)); return 0; err_open: diff --git a/btif/co/bta_hh_co.c b/btif/co/bta_hh_co.c index 31dfde1ab..b2fbb5f45 100644 --- a/btif/co/bta_hh_co.c +++ b/btif/co/bta_hh_co.c @@ -47,7 +47,7 @@ static tBTA_HH_RPT_CACHE_ENTRY sReportCache[BTA_HH_NV_LOAD_MAX]; static int uhid_write(int fd, const struct uhid_event *ev) { ssize_t ret; - ret = write(fd, ev, sizeof(*ev)); + ret = TEMP_FAILURE_RETRY(write(fd, ev, sizeof(*ev))); if (ret < 0){ int rtn = -errno; APPL_TRACE_ERROR("%s: Cannot write to uhid:%s", @@ -73,7 +73,7 @@ static int uhid_event(btif_hh_device_t *p_dev) APPL_TRACE_ERROR("%s: Device not found",__FUNCTION__) return -1; } - ret = read(p_dev->fd, &ev, sizeof(ev)); + ret = TEMP_FAILURE_RETRY(read(p_dev->fd, &ev, sizeof(ev))); if (ret == 0) { APPL_TRACE_ERROR("%s: Read HUP on uhid-cdev %s", __FUNCTION__, strerror(errno)); @@ -184,7 +184,7 @@ static void *btif_hh_poll_event_thread(void *arg) pfds[0].events = POLLIN; while(p_dev->hh_keep_polling){ - ret = poll(pfds, 1, 50); + ret = TEMP_FAILURE_RETRY(poll(pfds, 1, 50)); if (ret < 0) { APPL_TRACE_ERROR("%s: Cannot poll for fds: %s\n", __FUNCTION__, strerror(errno)); break; @@ -276,7 +276,7 @@ void bta_hh_co_open(UINT8 dev_handle, UINT8 sub_class, tBTA_HH_ATTR_MASK attr_ma __FUNCTION__, p_dev->attr_mask, p_dev->sub_class, p_dev->app_id); if(p_dev->fd<0) { - p_dev->fd = open(dev_path, O_RDWR | O_CLOEXEC); + p_dev->fd = TEMP_FAILURE_RETRY(open(dev_path, O_RDWR | O_CLOEXEC)); if (p_dev->fd < 0){ APPL_TRACE_ERROR("%s: Error: failed to open uhid, err:%s", __FUNCTION__,strerror(errno)); @@ -303,7 +303,7 @@ void bta_hh_co_open(UINT8 dev_handle, UINT8 sub_class, tBTA_HH_ATTR_MASK attr_ma btif_hh_cb.device_num++; // This is a new device,open the uhid driver now. - p_dev->fd = open(dev_path, O_RDWR | O_CLOEXEC); + p_dev->fd = TEMP_FAILURE_RETRY(open(dev_path, O_RDWR | O_CLOEXEC)); if (p_dev->fd < 0){ APPL_TRACE_ERROR("%s: Error: failed to open uhid, err:%s", __FUNCTION__,strerror(errno)); diff --git a/btif/co/bta_hl_co.c b/btif/co/bta_hl_co.c index 9aa91f7a0..f1331459a 100644 --- a/btif/co/bta_hl_co.c +++ b/btif/co/bta_hl_co.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "bta_api.h" #include "btm_api.h" #include "bta_sys.h" @@ -384,7 +385,7 @@ void bta_hl_co_put_rx_data (UINT8 app_id, tBTA_HL_MDL_HANDLE mdl_handle, { BTIF_TRACE_DEBUG("app_idx=%d mcl_idx=0x%x mdl_idx=0x%x data_size=%d", app_idx, mcl_idx, mdl_idx, data_size); - r = send(p_dcb->p_scb->socket_id[1], p_dcb->p_rx_pkt, data_size, 0); + r = TEMP_FAILURE_RETRY(send(p_dcb->p_scb->socket_id[1], p_dcb->p_rx_pkt, data_size, 0)); if (r == data_size) { diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c index d552e5ca7..bbd75ee66 100644 --- a/btif/src/btif_core.c +++ b/btif/src/btif_core.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -330,10 +331,10 @@ static void btif_fetch_local_bdaddr(bt_bdaddr_t *local_addr) BTIF_TRACE_DEBUG("local bdaddr is stored in %s", val); - if ((addr_fd = open(val, O_RDONLY)) != -1) + if ((addr_fd = TEMP_FAILURE_RETRY(open(val, O_RDONLY))) != -1) { memset(val, 0, sizeof(val)); - read(addr_fd, val, FACTORY_BT_BDADDR_STORAGE_LEN); + TEMP_FAILURE_RETRY(read(addr_fd, val, FACTORY_BT_BDADDR_STORAGE_LEN)); string_to_bdaddr(val, local_addr); /* If this is not a reserved/special bda, then use it */ if (memcmp(local_addr->address, null_bdaddr, BD_ADDR_LEN) != 0) diff --git a/btif/src/btif_dm.c b/btif/src/btif_dm.c index cf317d6a5..190770365 100644 --- a/btif/src/btif_dm.c +++ b/btif/src/btif_dm.c @@ -28,6 +28,7 @@ #define LOG_TAG "bt_btif_dm" #include +#include #include #include #include @@ -1782,7 +1783,7 @@ static void btif_dm_upstreams_evt(UINT16 event, char* p_param) BTIF_TRACE_ERROR("Received H/W Error. "); /* Flush storage data */ btif_config_flush(); - usleep(100000); /* 100milliseconds */ + TEMP_FAILURE_RETRY(usleep(100000)); /* 100milliseconds */ /* Killing the process to force a restart as part of fault tolerance */ kill(getpid(), SIGKILL); break; diff --git a/btif/src/btif_hh.c b/btif/src/btif_hh.c index d0aaf2689..9d6c9e046 100644 --- a/btif/src/btif_hh.c +++ b/btif/src/btif_hh.c @@ -234,7 +234,7 @@ static void toggle_os_keylockstates(int fd, int changedlockstates) BTIF_TRACE_DEBUG("%s: %x %x %x", __FUNCTION__, hidreport[6], hidreport[7], hidreport[8]); bta_hh_co_write(fd , hidreport, sizeof(hidreport)); - usleep(200000); + TEMP_FAILURE_RETRY(usleep(200000)); memset(hidreport,0,9); hidreport[0]=1; BTIF_TRACE_DEBUG("Writing hidreport #2 to os: "\ @@ -329,7 +329,7 @@ static void sync_lockstate_on_connect(btif_hh_device_t *p_dev) BTIF_TRACE_DEBUG("%s: Sending hid report to kernel "\ "indicating lock key state 0x%x",__FUNCTION__, keylockstates); - usleep(200000); + TEMP_FAILURE_RETRY(usleep(200000)); toggle_os_keylockstates(p_dev->fd, keylockstates); } else diff --git a/btif/src/btif_hl.c b/btif/src/btif_hl.c index 9d0c0d730..995146e8e 100644 --- a/btif/src/btif_hl.c +++ b/btif/src/btif_hl.c @@ -4795,8 +4795,8 @@ void btif_hl_select_monitor_callback(fd_set *p_cur_set ,fd_set *p_org_set) { } p_dcb->p_tx_pkt = btif_hl_get_buf (p_dcb->mtu); if (p_dcb) { - int r = (int)recv(p_scb->socket_id[1], p_dcb->p_tx_pkt, - p_dcb->mtu, MSG_DONTWAIT); + int r = (int)TEMP_FAILURE_RETRY(recv(p_scb->socket_id[1], p_dcb->p_tx_pkt, + p_dcb->mtu, MSG_DONTWAIT)); if (r > 0) { BTIF_TRACE_DEBUG("btif_hl_select_monitor_callback send data r =%d", r); p_dcb->tx_size = r; @@ -4852,7 +4852,7 @@ static inline int btif_hl_select_wakeup_init(fd_set* set){ static inline int btif_hl_select_wakeup(void){ char sig_on = btif_hl_signal_select_wakeup; BTIF_TRACE_DEBUG("btif_hl_select_wakeup"); - return send(signal_fds[1], &sig_on, sizeof(sig_on), 0); + return TEMP_FAILURE_RETRY(send(signal_fds[1], &sig_on, sizeof(sig_on), 0)); } /******************************************************************************* @@ -4867,7 +4867,7 @@ static inline int btif_hl_select_wakeup(void){ static inline int btif_hl_select_close_connected(void){ char sig_on = btif_hl_signal_select_close_connected; BTIF_TRACE_DEBUG("btif_hl_select_close_connected"); - return send(signal_fds[1], &sig_on, sizeof(sig_on), 0); + return TEMP_FAILURE_RETRY(send(signal_fds[1], &sig_on, sizeof(sig_on), 0)); } /******************************************************************************* @@ -4884,7 +4884,7 @@ static inline int btif_hl_close_select_thread(void) int result = 0; char sig_on = btif_hl_signal_select_exit; BTIF_TRACE_DEBUG("btif_hl_signal_select_exit"); - result = send(signal_fds[1], &sig_on, sizeof(sig_on), 0); + result = TEMP_FAILURE_RETRY(send(signal_fds[1], &sig_on, sizeof(sig_on), 0)); if (btif_is_enabled()) { /* Wait for the select_thread_id to exit if BT is still enabled @@ -4911,7 +4911,7 @@ static inline int btif_hl_select_wake_reset(void){ char sig_recv = 0; BTIF_TRACE_DEBUG("btif_hl_select_wake_reset"); - recv(signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL); + TEMP_FAILURE_RETRY(recv(signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL)); return(int)sig_recv; } /******************************************************************************* @@ -4972,7 +4972,7 @@ static void *btif_hl_select_thread(void *arg){ BTIF_TRACE_DEBUG("set curr_set = org_set "); curr_set = org_set; max_curr_s = max_org_s; - int ret = select((max_curr_s + 1), &curr_set, NULL, NULL, NULL); + int ret = TEMP_FAILURE_RETRY(select((max_curr_s + 1), &curr_set, NULL, NULL, NULL)); BTIF_TRACE_DEBUG("select unblocked ret=%d", ret); if (ret == -1) { diff --git a/btif/src/btif_pan.c b/btif/src/btif_pan.c index c3dec2acc..e2e391a83 100644 --- a/btif/src/btif_pan.c +++ b/btif/src/btif_pan.c @@ -312,7 +312,7 @@ static int tap_if_up(const char *devname, const bt_bdaddr_t *addr) //set mac addr memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, devname, IFNAMSIZ - 1); - err = ioctl(sk, SIOCGIFHWADDR, &ifr); + err = TEMP_FAILURE_RETRY(ioctl(sk, SIOCGIFHWADDR, &ifr)); if (err < 0) { BTIF_TRACE_ERROR("Could not get network hardware for interface:%s, errno:%s", devname, strerror(errno)); @@ -333,7 +333,7 @@ static int tap_if_up(const char *devname, const bt_bdaddr_t *addr) ifr.ifr_hwaddr.sa_data[0] &= ~0x01; } - err = ioctl(sk, SIOCSIFHWADDR, (caddr_t)&ifr); + err = TEMP_FAILURE_RETRY(ioctl(sk, SIOCSIFHWADDR, (caddr_t)&ifr)); if (err < 0) { BTIF_TRACE_ERROR("Could not set bt address for interface:%s, errno:%s", devname, strerror(errno)); @@ -348,7 +348,7 @@ static int tap_if_up(const char *devname, const bt_bdaddr_t *addr) ifr.ifr_flags |= IFF_UP; ifr.ifr_flags |= IFF_MULTICAST; - err = ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr); + err = TEMP_FAILURE_RETRY(ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr)); if (err < 0) { @@ -375,7 +375,7 @@ static int tap_if_down(const char *devname) ifr.ifr_flags &= ~IFF_UP; - ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr); + TEMP_FAILURE_RETRY(ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr)); close(sk); @@ -401,7 +401,7 @@ int btpan_tap_open() /* open the clone device */ - if ((fd = open(clonedev, O_RDWR)) < 0) + if ((fd = TEMP_FAILURE_RETRY(open(clonedev, O_RDWR))) < 0) { BTIF_TRACE_DEBUG("could not open %s, err:%d", clonedev, errno); return fd; @@ -413,7 +413,7 @@ int btpan_tap_open() strncpy(ifr.ifr_name, TAP_IF_NAME, IFNAMSIZ); /* try to create the device */ - if ((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0) + if ((err = TEMP_FAILURE_RETRY(ioctl(fd, TUNSETIFF, (void *) &ifr))) < 0) { BTIF_TRACE_DEBUG("ioctl error:%d, errno:%s", err, strerror(errno)); close(fd); @@ -421,8 +421,8 @@ int btpan_tap_open() } if (tap_if_up(TAP_IF_NAME, controller_get_interface()->get_address()) == 0) { - int flags = fcntl(fd, F_GETFL, 0); - fcntl(fd, F_SETFL, flags | O_NONBLOCK); + int flags = TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL, 0)); + TEMP_FAILURE_RETRY(fcntl(fd, F_SETFL, flags | O_NONBLOCK)); return fd; } BTIF_TRACE_ERROR("can not bring up tap interface:%s", TAP_IF_NAME); @@ -451,7 +451,7 @@ int btpan_tap_send(int tap_fd, const BD_ADDR src, const BD_ADDR dst, UINT16 prot memcpy(packet + sizeof(tETH_HDR), buf, len); /* Send data to network interface */ - int ret = write(tap_fd, packet, len + sizeof(tETH_HDR)); + int ret = TEMP_FAILURE_RETRY(write(tap_fd, packet, len + sizeof(tETH_HDR))); BTIF_TRACE_DEBUG("ret:%d", ret); return ret; } @@ -682,7 +682,7 @@ static void btu_exec_tap_fd_read(void *p_param) { // We save it in the congest_packet right away in case we can't deliver it in this // attempt. if (!btpan_cb.congest_packet_size) { - ssize_t ret = read(fd, btpan_cb.congest_packet, sizeof(btpan_cb.congest_packet)); + ssize_t ret = TEMP_FAILURE_RETRY(read(fd, btpan_cb.congest_packet, sizeof(btpan_cb.congest_packet))); switch (ret) { case -1: BTIF_TRACE_ERROR("%s unable to read from driver: %s", __func__, strerror(errno)); @@ -726,7 +726,7 @@ static void btu_exec_tap_fd_read(void *p_param) { ufd.fd = fd; ufd.events = POLLIN; ufd.revents = 0; - if (poll(&ufd, 1, 0) <= 0 || IS_EXCEPTION(ufd.revents)) + if (TEMP_FAILURE_RETRY(poll(&ufd, 1, 0)) <= 0 || IS_EXCEPTION(ufd.revents)) break; } //add fd back to monitor thread diff --git a/btif/src/btif_rc.c b/btif/src/btif_rc.c index 1b5696cf0..476d8f1ce 100644 --- a/btif/src/btif_rc.c +++ b/btif/src/btif_rc.c @@ -24,6 +24,7 @@ * Description: Bluetooth AVRC implementation * *****************************************************************************/ +#include #include #include #include @@ -235,7 +236,7 @@ int send_event (int fd, uint16_t type, uint16_t code, int32_t value) event.code = code; event.value = value; - return write(fd, &event, sizeof(event)); + return TEMP_FAILURE_RETRY(write(fd, &event, sizeof(event))); } void send_key (int fd, uint16_t key, int pressed) @@ -274,7 +275,7 @@ int uinput_create(char *name) for(x=0; x < MAX_UINPUT_PATHS; x++) { - fd = open(uinput_dev_path[x], O_RDWR); + fd = TEMP_FAILURE_RETRY(open(uinput_dev_path[x], O_RDWR)); if (fd < 0) continue; break; @@ -292,20 +293,20 @@ int uinput_create(char *name) dev.id.product = 0x0000; dev.id.version = 0x0000; - if (write(fd, &dev, sizeof(dev)) < 0) { + if (TEMP_FAILURE_RETRY(write(fd, &dev, sizeof(dev))) < 0) { BTIF_TRACE_ERROR("%s Unable to write device information", __FUNCTION__); close(fd); return -1; } - ioctl(fd, UI_SET_EVBIT, EV_KEY); - ioctl(fd, UI_SET_EVBIT, EV_REL); - ioctl(fd, UI_SET_EVBIT, EV_SYN); + TEMP_FAILURE_RETRY(ioctl(fd, UI_SET_EVBIT, EV_KEY)); + TEMP_FAILURE_RETRY(ioctl(fd, UI_SET_EVBIT, EV_REL)); + TEMP_FAILURE_RETRY(ioctl(fd, UI_SET_EVBIT, EV_SYN)); for (x = 0; key_map[x].name != NULL; x++) - ioctl(fd, UI_SET_KEYBIT, key_map[x].mapped_id); + TEMP_FAILURE_RETRY(ioctl(fd, UI_SET_KEYBIT, key_map[x].mapped_id)); - if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) { + if (TEMP_FAILURE_RETRY(ioctl(fd, UI_DEV_CREATE, NULL)) < 0) { BTIF_TRACE_ERROR("%s Unable to create uinput device", __FUNCTION__); close(fd); return -1; @@ -333,7 +334,7 @@ void close_uinput (void) { BTIF_TRACE_DEBUG("%s", __FUNCTION__); if (uinput_fd > 0) { - ioctl(uinput_fd, UI_DEV_DESTROY); + TEMP_FAILURE_RETRY(ioctl(uinput_fd, UI_DEV_DESTROY)); close(uinput_fd); uinput_fd = -1; diff --git a/btif/src/btif_sock_l2cap.c b/btif/src/btif_sock_l2cap.c index 04c5b676b..7b1a5cf02 100644 --- a/btif/src/btif_sock_l2cap.c +++ b/btif/src/btif_sock_l2cap.c @@ -968,7 +968,7 @@ static BOOLEAN flush_incoming_que_on_wr_signal_l(l2cap_socket *sock) uint32_t len; while (packet_get_head_l(sock, &buf, &len)) { - int sent = send(sock->our_fd, buf, len, MSG_DONTWAIT); + int sent = TEMP_FAILURE_RETRY(send(sock->our_fd, buf, len, MSG_DONTWAIT)); if (sent == (signed)len) osi_free(buf); @@ -1002,7 +1002,7 @@ void btsock_l2cap_signaled(int fd, int flags, uint32_t user_id) if (sock->connected) { int size = 0; - if (!(flags & SOCK_THREAD_FD_EXCEPTION) || (ioctl(sock->our_fd, FIONREAD, &size) + if (!(flags & SOCK_THREAD_FD_EXCEPTION) || (TEMP_FAILURE_RETRY(ioctl(sock->our_fd, FIONREAD, &size)) == 0 && size)) { uint8_t *buffer = osi_malloc(L2CAP_MAX_SDU_LENGTH); //uint8_t *buffer = (uint8_t*)GKI_getbuf(L2CAP_MAX_SDU_LENGTH); @@ -1028,8 +1028,8 @@ void btsock_l2cap_signaled(int fd, int flags, uint32_t user_id) * UPDATE: Since we are responsible for freeing the buffer in the * write_complete_ind, it is OK to use malloc. */ - int count = recv(fd, buffer, L2CAP_MAX_SDU_LENGTH, - MSG_NOSIGNAL | MSG_DONTWAIT); + int count = TEMP_FAILURE_RETRY(recv(fd, buffer, L2CAP_MAX_SDU_LENGTH, + MSG_NOSIGNAL | MSG_DONTWAIT)); APPL_TRACE_DEBUG("btsock_l2cap_signaled - %d bytes received from socket", count); if (sock->fixed_chan) { @@ -1061,7 +1061,7 @@ void btsock_l2cap_signaled(int fd, int flags, uint32_t user_id) } if (drop_it || (flags & SOCK_THREAD_FD_EXCEPTION)) { int size = 0; - if (drop_it || ioctl(sock->our_fd, FIONREAD, &size) != 0 || size == 0) + if (drop_it || TEMP_FAILURE_RETRY(ioctl(sock->our_fd, FIONREAD, &size)) != 0 || size == 0) btsock_l2cap_free_l(sock); } } diff --git a/btif/src/btif_sock_rfc.c b/btif/src/btif_sock_rfc.c index f80ed562f..605099e96 100644 --- a/btif/src/btif_sock_rfc.c +++ b/btif/src/btif_sock_rfc.c @@ -720,7 +720,7 @@ static sent_status_t send_data_to_app(int fd, BT_HDR *p_buf) { if (p_buf->len == 0) return SENT_ALL; - ssize_t sent = send(fd, p_buf->data + p_buf->offset, p_buf->len, MSG_DONTWAIT); + ssize_t sent = TEMP_FAILURE_RETRY(send(fd, p_buf->data + p_buf->offset, p_buf->len, MSG_DONTWAIT)); if (sent == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) @@ -783,11 +783,9 @@ void btsock_rfc_signaled(UNUSED_ATTR int fd, int flags, uint32_t user_id) { if (slot->f.connected) { // Make sure there's data pending in case the peer closed the socket. int size = 0; - if (!(flags & SOCK_THREAD_FD_EXCEPTION) || (ioctl(slot->fd, FIONREAD, &size) == 0 && size)) - //unlock before BTA_JvRfcommWrite to avoid deadlock on concurrnet multi rfcomm connectoins - //concurrnet multi rfcomm connectoins - pthread_mutex_unlock(&slot_lock); + if (!(flags & SOCK_THREAD_FD_EXCEPTION) || (TEMP_FAILURE_RETRY(ioctl(slot->fd, FIONREAD, &size)) == 0 && size)) { BTA_JvRfcommWrite(slot->rfc_handle, slot->id); + } } else { LOG_ERROR("%s socket signaled for read while disconnected, slot: %d, channel: %d", __func__, slot->id, slot->scn); need_close = true; @@ -805,7 +803,7 @@ void btsock_rfc_signaled(UNUSED_ATTR int fd, int flags, uint32_t user_id) { if (need_close || (flags & SOCK_THREAD_FD_EXCEPTION)) { // Clean up if there's no data pending. int size = 0; - if (need_close || ioctl(slot->fd, FIONREAD, &size) != 0 || !size) + if (need_close || TEMP_FAILURE_RETRY(ioctl(slot->fd, FIONREAD, &size)) != 0 || !size) cleanup_rfc_slot(slot); } @@ -859,7 +857,7 @@ int bta_co_rfc_data_outgoing_size(void *user_data, int *size) { if (!slot) goto out; - if (ioctl(slot->fd, FIONREAD, size) == 0) { + if (TEMP_FAILURE_RETRY(ioctl(slot->fd, FIONREAD, size)) == 0) { ret = true; } else { LOG_ERROR("%s unable to determine bytes remaining to be read on fd %d: %s", __func__, slot->fd, strerror(errno)); @@ -880,7 +878,7 @@ int bta_co_rfc_data_outgoing(void *user_data, uint8_t *buf, uint16_t size) { if (!slot) goto out; - int received = recv(slot->fd, buf, size, 0); + int received = TEMP_FAILURE_RETRY(recv(slot->fd, buf, size, 0)); if(received == size) { ret = true; } else { diff --git a/btif/src/btif_sock_thread.c b/btif/src/btif_sock_thread.c index 459aebac2..ebf636d36 100644 --- a/btif/src/btif_sock_thread.c +++ b/btif/src/btif_sock_thread.c @@ -114,12 +114,12 @@ static pthread_mutex_t thread_slot_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP static inline void set_socket_blocking(int s, int blocking) { int opts; - opts = fcntl(s, F_GETFL); + opts = TEMP_FAILURE_RETRY(fcntl(s, F_GETFL)); if (opts<0) APPL_TRACE_ERROR("set blocking (%s)", strerror(errno)); if(blocking) opts &= ~O_NONBLOCK; else opts |= O_NONBLOCK; - if (fcntl(s, F_SETFL, opts) < 0) + if (TEMP_FAILURE_RETRY(fcntl(s, F_SETFL, opts)) < 0) APPL_TRACE_ERROR("set blocking (%s)", strerror(errno)); } @@ -161,7 +161,7 @@ static inline int accept_server_socket(int s) { struct sockaddr_un client_address; socklen_t clen; - int fd = accept(s, (struct sockaddr*)&client_address, &clen); + int fd = TEMP_FAILURE_RETRY(accept(s, (struct sockaddr*)&client_address, &clen)); APPL_TRACE_DEBUG("accepted fd:%d for server fd:%d", fd, s); return fd; } @@ -325,7 +325,7 @@ int btsock_thread_add_fd(int h, int fd, int type, int flags, uint32_t user_id) } sock_cmd_t cmd = {CMD_ADD_FD, fd, type, flags, user_id}; APPL_TRACE_DEBUG("adding fd:%d, flags:0x%x", fd, flags); - return send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd); + return TEMP_FAILURE_RETRY(send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0)) == sizeof(cmd); } bool btsock_thread_remove_fd_and_close(int thread_handle, int fd) @@ -342,7 +342,7 @@ bool btsock_thread_remove_fd_and_close(int thread_handle, int fd) } sock_cmd_t cmd = {CMD_REMOVE_FD, fd, 0, 0, 0}; - return send(ts[thread_handle].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd); + return TEMP_FAILURE_RETRY(send(ts[thread_handle].cmd_fdw, &cmd, sizeof(cmd), 0)) == sizeof(cmd); } int btsock_thread_post_cmd(int h, int type, const unsigned char* data, int size, uint32_t user_id) @@ -376,7 +376,7 @@ int btsock_thread_post_cmd(int h, int type, const unsigned char* data, int size, return FALSE; } } - return send(ts[h].cmd_fdw, cmd_send, size_send, 0) == size_send; + return TEMP_FAILURE_RETRY(send(ts[h].cmd_fdw, cmd_send, size_send, 0)) == size_send; } int btsock_thread_wakeup(int h) { @@ -391,7 +391,7 @@ int btsock_thread_wakeup(int h) return FALSE; } sock_cmd_t cmd = {CMD_WAKEUP, 0, 0, 0, 0}; - return send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd); + return TEMP_FAILURE_RETRY(send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0)) == sizeof(cmd); } int btsock_thread_exit(int h) { @@ -406,7 +406,7 @@ int btsock_thread_exit(int h) return FALSE; } sock_cmd_t cmd = {CMD_EXIT, 0, 0, 0, 0}; - if(send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd)) + if(TEMP_FAILURE_RETRY(send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0)) == sizeof(cmd)) { pthread_join(ts[h].thread_id, 0); pthread_mutex_lock(&thread_slot_lock); @@ -501,7 +501,7 @@ static int process_cmd_sock(int h) { sock_cmd_t cmd = {-1, 0, 0, 0, 0}; int fd = ts[h].cmd_fdr; - if(recv(fd, &cmd, sizeof(cmd), MSG_WAITALL) != sizeof(cmd)) + if(TEMP_FAILURE_RETRY(recv(fd, &cmd, sizeof(cmd), MSG_WAITALL)) != sizeof(cmd)) { APPL_TRACE_ERROR("recv cmd errno:%d", errno); return FALSE; @@ -608,7 +608,7 @@ static void *sock_poll_thread(void *arg) for(;;) { prepare_poll_fds(h, pfds); - int ret = poll(pfds, ts[h].poll_count, -1); + int ret = TEMP_FAILURE_RETRY(poll(pfds, ts[h].poll_count, -1)); if(ret == -1) { APPL_TRACE_ERROR("poll ret -1, exit the thread, errno:%d, err:%s", errno, strerror(errno)); diff --git a/btif/src/btif_sock_util.c b/btif/src/btif_sock_util.c index baa3ed3d9..ead113f13 100644 --- a/btif/src/btif_sock_util.c +++ b/btif/src/btif_sock_util.c @@ -74,7 +74,7 @@ int sock_send_all(int sock_fd, const uint8_t* buf, int len) int ret; while(s) { - do ret = send(sock_fd, buf, s, 0); + do ret = TEMP_FAILURE_RETRY(send(sock_fd, buf, s, 0)); while(ret < 0 && errno == EINTR); if(ret <= 0) { @@ -92,7 +92,7 @@ int sock_recv_all(int sock_fd, uint8_t* buf, int len) int ret = -1; while(r) { - do ret = recv(sock_fd, buf, r, MSG_WAITALL); + do ret = TEMP_FAILURE_RETRY(recv(sock_fd, buf, r, MSG_WAITALL)); while(ret < 0 && errno == EINTR); if(ret <= 0) { @@ -140,7 +140,7 @@ int sock_send_fd(int sock_fd, const uint8_t* buf, int len, int send_fd) msg.msg_iovlen = 1; do { - ret = sendmsg(sock_fd, &msg, MSG_NOSIGNAL); + ret = TEMP_FAILURE_RETRY(sendmsg(sock_fd, &msg, MSG_NOSIGNAL)); } while (ret < 0 && errno == EINTR); if (ret < 0) { diff --git a/gki/ulinux/gki_ulinux.c b/gki/ulinux/gki_ulinux.c index 72ad479e0..703e99278 100644 --- a/gki/ulinux/gki_ulinux.c +++ b/gki/ulinux/gki_ulinux.c @@ -76,7 +76,7 @@ void GKI_delay(UINT32 timeout_ms) { int err; do { - err = nanosleep(&delay, &delay); + err = TEMP_FAILURE_RETRY(nanosleep(&delay, &delay)); } while (err == -1 && errno == EINTR); } diff --git a/hci/src/btsnoop.c b/hci/src/btsnoop.c index d859e6842..7b6b97f30 100644 --- a/hci/src/btsnoop.c +++ b/hci/src/btsnoop.c @@ -169,14 +169,14 @@ static void update_logging() { LOG_ERROR("%s unable to rename '%s' to '%s': %s", __func__, log_path, last_log_path, strerror(errno)); } - logfile_fd = open(log_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); + logfile_fd = TEMP_FAILURE_RETRY(open(log_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH)); if (logfile_fd == INVALID_FD) { LOG_ERROR("%s unable to open '%s': %s", __func__, log_path, strerror(errno)); is_logging = false; return; } - write(logfile_fd, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16); + TEMP_FAILURE_RETRY(write(logfile_fd, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16)); } else { if (logfile_fd != INVALID_FD) close(logfile_fd); @@ -188,7 +188,7 @@ static void update_logging() { static void btsnoop_write(const void *data, size_t length) { if (logfile_fd != INVALID_FD) - write(logfile_fd, data, length); + TEMP_FAILURE_RETRY(write(logfile_fd, data, length)); btsnoop_net_write(data, length); } diff --git a/hci/src/btsnoop_net.c b/hci/src/btsnoop_net.c index c6a9cd61a..1aff83290 100644 --- a/hci/src/btsnoop_net.c +++ b/hci/src/btsnoop_net.c @@ -77,7 +77,7 @@ void btsnoop_net_write(const void *data, size_t length) { pthread_mutex_lock(&client_socket_lock_); if (client_socket_ != -1) { - if (send(client_socket_, data, length, 0) == -1 && errno == ECONNRESET) { + if (TEMP_FAILURE_RETRY(send(client_socket_, data, length, 0)) == -1 && errno == ECONNRESET) { safe_close_(&client_socket_); } } @@ -115,7 +115,7 @@ static void *listen_fn_(UNUSED_ATTR void *context) { } for (;;) { - int client_socket = accept(listen_socket_, NULL, NULL); + int client_socket = TEMP_FAILURE_RETRY(accept(listen_socket_, NULL, NULL)); if (client_socket == -1) { if (errno == EINVAL || errno == EBADF) { break; @@ -129,7 +129,7 @@ static void *listen_fn_(UNUSED_ATTR void *context) { pthread_mutex_lock(&client_socket_lock_); safe_close_(&client_socket_); client_socket_ = client_socket; - send(client_socket_, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16, 0); + TEMP_FAILURE_RETRY(send(client_socket_, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16, 0)); pthread_mutex_unlock(&client_socket_lock_); } diff --git a/hci/src/hci_hal_h4.c b/hci/src/hci_hal_h4.c index 4fc4274f4..86c0dc70b 100644 --- a/hci/src/hci_hal_h4.c +++ b/hci/src/hci_hal_h4.c @@ -139,7 +139,7 @@ static uint16_t transmit_data(serial_data_type_t type, uint8_t *data, uint16_t l uint16_t transmitted_length = 0; while (length > 0) { - ssize_t ret = write(uart_fd, data + transmitted_length, length); + ssize_t ret = TEMP_FAILURE_RETRY(write(uart_fd, data + transmitted_length, length)); switch (ret) { case -1: LOG_ERROR("In %s, error writing to the uart serial port: %s", __func__, strerror(errno)); diff --git a/hci/src/hci_hal_mct.c b/hci/src/hci_hal_mct.c index 9b3707c7f..5219e039b 100644 --- a/hci/src/hci_hal_mct.c +++ b/hci/src/hci_hal_mct.c @@ -159,7 +159,7 @@ static uint16_t transmit_data_on(int fd, uint8_t *data, uint16_t length) { uint16_t transmitted_length = 0; while (length > 0) { - ssize_t ret = write(fd, data + transmitted_length, length); + ssize_t ret = TEMP_FAILURE_RETRY(write(fd, data + transmitted_length, length)); switch (ret) { case -1: LOG_ERROR("In %s, error writing to the serial port with fd %d: %s", __func__, fd, strerror(errno)); diff --git a/hci/src/hci_layer.c b/hci/src/hci_layer.c index 5138ce6e1..16f72c606 100644 --- a/hci/src/hci_layer.c +++ b/hci/src/hci_layer.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -517,7 +518,7 @@ static void command_timed_out(UNUSED_ATTR void *context) { } LOG_ERROR("%s restarting the bluetooth process.", __func__); - usleep(10000); + TEMP_FAILURE_RETRY(usleep(10000)); kill(getpid(), SIGKILL); } diff --git a/hci/test/hci_hal_h4_test.cpp b/hci/test/hci_hal_h4_test.cpp index 2c4030d4f..6b421115f 100644 --- a/hci/test/hci_hal_h4_test.cpp +++ b/hci/test/hci_hal_h4_test.cpp @@ -177,26 +177,26 @@ static void expect_socket_data(int fd, char first_byte, char *data) { fd_set read_fds; FD_ZERO(&read_fds); FD_SET(fd, &read_fds); - select(fd + 1, &read_fds, NULL, NULL, NULL); + TEMP_FAILURE_RETRY(select(fd + 1, &read_fds, NULL, NULL, NULL)); char byte; - read(fd, &byte, 1); + TEMP_FAILURE_RETRY(read(fd, &byte, 1)); EXPECT_EQ(i == 0 ? first_byte : data[i - 1], byte); } } static void write_packet(int fd, char first_byte, char *data) { - write(fd, &first_byte, 1); - write(fd, data, strlen(data)); + TEMP_FAILURE_RETRY(write(fd, &first_byte, 1)); + TEMP_FAILURE_RETRY(write(fd, data, strlen(data))); } static void write_packet_reentry(int fd, char first_byte, char *data) { - write(fd, &first_byte, 1); + TEMP_FAILURE_RETRY(write(fd, &first_byte, 1)); int length = strlen(data); for (int i = 0; i < length; i++) { - write(fd, &data[i], 1); + TEMP_FAILURE_RETRY(write(fd, &data[i], 1)); semaphore_wait(reentry_semaphore); } } @@ -245,7 +245,7 @@ TEST_F(HciHalH4Test, test_type_byte_only_must_not_signal_data_ready) { reset_for(type_byte_only); char byte = DATA_TYPE_ACL; - write(sockfd[1], &byte, 1); + TEMP_FAILURE_RETRY(write(sockfd[1], &byte, 1)); fd_set read_fds; @@ -258,6 +258,6 @@ TEST_F(HciHalH4Test, test_type_byte_only_must_not_signal_data_ready) { timeout.tv_sec = 0; timeout.tv_usec = 0; - select(sockfd[0] + 1, &read_fds, NULL, NULL, &timeout); + TEMP_FAILURE_RETRY(select(sockfd[0] + 1, &read_fds, NULL, NULL, &timeout)); } while(FD_ISSET(sockfd[0], &read_fds)); } diff --git a/hci/test/hci_hal_mct_test.cpp b/hci/test/hci_hal_mct_test.cpp index 911aabcfd..a857629b3 100644 --- a/hci/test/hci_hal_mct_test.cpp +++ b/hci/test/hci_hal_mct_test.cpp @@ -186,23 +186,23 @@ static void expect_socket_data(int fd, char *data) { fd_set read_fds; FD_ZERO(&read_fds); FD_SET(fd, &read_fds); - select(fd + 1, &read_fds, NULL, NULL, NULL); + TEMP_FAILURE_RETRY(select(fd + 1, &read_fds, NULL, NULL, NULL)); char byte; - read(fd, &byte, 1); + TEMP_FAILURE_RETRY(read(fd, &byte, 1)); EXPECT_EQ(data[i], byte); } } static void write_packet(int fd, char *data) { - write(fd, data, strlen(data)); + TEMP_FAILURE_RETRY(write(fd, data, strlen(data))); } static void write_packet_reentry(int fd, char *data) { int length = strlen(data); for (int i = 0; i < length; i++) { - write(fd, &data[i], 1); + TEMP_FAILURE_RETRY(write(fd, &data[i], 1)); semaphore_wait(reentry_semaphore); } } diff --git a/osi/src/config.c b/osi/src/config.c index c87f5310a..3d5d87ff3 100644 --- a/osi/src/config.c +++ b/osi/src/config.c @@ -21,10 +21,13 @@ #include #include #include +#include +#include #include #include #include #include +#include #include "osi/include/allocator.h" #include "osi/include/config.h" @@ -275,16 +278,39 @@ bool config_save(const config_t *config, const char *filename) { assert(filename != NULL); assert(*filename != '\0'); - char *temp_filename = osi_calloc(strlen(filename) + 5); - if (!temp_filename) { - LOG_ERROR("%s unable to allocate memory for filename.", __func__); - return false; + // Steps to ensure content of config file gets to disk: + // + // 1) Open and write to temp file (e.g. bt_config.conf.new). + // 2) Sync the temp file to disk with fsync(). + // 3) Rename temp file to actual config file (e.g. bt_config.conf). + // This ensures atomic update. + // 4) Sync directory that has the conf file with fsync(). + // This ensures directory entries are up-to-date. + int dir_fd = -1; + FILE *fp = NULL; + + // Build temp config file based on config file (e.g. bt_config.conf.new). + static const char *temp_file_ext = ".new"; + const int filename_len = strlen(filename); + const int temp_filename_len = filename_len + strlen(temp_file_ext) + 1; + char *temp_filename = osi_calloc(temp_filename_len); + snprintf(temp_filename, temp_filename_len, "%s%s", filename, temp_file_ext); + + // Extract directory from file path (e.g. /data/misc/bluedroid). + char *temp_dirname = osi_strdup(filename); + const char *directoryname = dirname(temp_dirname); + if (!directoryname) { + LOG_ERROR("%s error extracting directory from '%s': %s", __func__, filename, strerror(errno)); + goto error; } - strcpy(temp_filename, filename); - strcat(temp_filename, ".new"); + dir_fd = TEMP_FAILURE_RETRY(open(directoryname, O_RDONLY)); + if (dir_fd < 0) { + LOG_ERROR("%s unable to open dir '%s': %s", __func__, directoryname, strerror(errno)); + goto error; + } - FILE *fp = fopen(temp_filename, "wt"); + fp = fopen(temp_filename, "wt"); if (!fp) { LOG_ERROR("%s unable to write file '%s': %s", __func__, temp_filename, strerror(errno)); goto error; @@ -292,20 +318,38 @@ bool config_save(const config_t *config, const char *filename) { for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) { const section_t *section = (const section_t *)list_node(node); - fprintf(fp, "[%s]\n", section->name); + if (fprintf(fp, "[%s]\n", section->name) < 0) { + LOG_ERROR("%s unable to write to file '%s': %s", __func__, temp_filename, strerror(errno)); + goto error; + } for (const list_node_t *enode = list_begin(section->entries); enode != list_end(section->entries); enode = list_next(enode)) { const entry_t *entry = (const entry_t *)list_node(enode); - fprintf(fp, "%s = %s\n", entry->key, entry->value); + if (fprintf(fp, "%s = %s\n", entry->key, entry->value) < 0) { + LOG_ERROR("%s unable to write to file '%s': %s", __func__, temp_filename, strerror(errno)); + goto error; + } } // Only add a separating newline if there are more sections. - if (list_next(node) != list_end(config->sections)) - fputc('\n', fp); + if (list_next(node) != list_end(config->sections)) { + if (fputc('\n', fp) == EOF) { + LOG_ERROR("%s unable to write to file '%s': %s", __func__, temp_filename, strerror(errno)); + goto error; + } + } } - fflush(fp); - fclose(fp); + // Sync written temp file out to disk. fsync() is blocking until data makes it to disk. + if (fsync(fileno(fp)) < 0) { + LOG_WARN("%s unable to fsync file '%s': %s", __func__, temp_filename, strerror(errno)); + } + + if (fclose(fp) == EOF) { + LOG_ERROR("%s unable to close file '%s': %s", __func__, temp_filename, strerror(errno)); + goto error; + } + fp = NULL; // Change the file's permissions to Read/Write by User and Group if (chmod(temp_filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) == -1) { @@ -313,17 +357,35 @@ bool config_save(const config_t *config, const char *filename) { goto error; } + // Rename written temp file to the actual config file. if (rename(temp_filename, filename) == -1) { LOG_ERROR("%s unable to commit file '%s': %s", __func__, filename, strerror(errno)); goto error; } + // This should ensure the directory is updated as well. + if (fsync(dir_fd) < 0) { + LOG_WARN("%s unable to fsync dir '%s': %s", __func__, directoryname, strerror(errno)); + } + + if (close(dir_fd) < 0) { + LOG_ERROR("%s unable to close dir '%s': %s", __func__, directoryname, strerror(errno)); + goto error; + } + osi_free(temp_filename); + osi_free(temp_dirname); return true; -error:; +error: + // This indicates there is a write issue. Unlink as partial data is not acceptable. unlink(temp_filename); + if (fp) + fclose(fp); + if (dir_fd != -1) + close(dir_fd); osi_free(temp_filename); + osi_free(temp_dirname); return false; } diff --git a/osi/src/eager_reader.c b/osi/src/eager_reader.c index 63b190ea6..e90a35eb1 100644 --- a/osi/src/eager_reader.c +++ b/osi/src/eager_reader.c @@ -224,7 +224,7 @@ static bool has_byte(const eager_reader_t *reader) { timeout.tv_sec = 0; timeout.tv_usec = 0; - select(reader->bytes_available_fd + 1, &read_fds, NULL, NULL, &timeout); + TEMP_FAILURE_RETRY(select(reader->bytes_available_fd + 1, &read_fds, NULL, NULL, &timeout)); return FD_ISSET(reader->bytes_available_fd, &read_fds); } @@ -240,7 +240,7 @@ static void inbound_data_waiting(void *context) { buffer->length = 0; buffer->offset = 0; - int bytes_read = read(reader->inbound_fd, buffer->data, reader->buffer_size); + int bytes_read = TEMP_FAILURE_RETRY(read(reader->inbound_fd, buffer->data, reader->buffer_size)); if (bytes_read > 0) { // Save the data for later buffer->length = bytes_read; diff --git a/osi/src/reactor.c b/osi/src/reactor.c index 08b50982e..32bd1bef1 100644 --- a/osi/src/reactor.c +++ b/osi/src/reactor.c @@ -241,7 +241,7 @@ static reactor_status_t run_reactor(reactor_t *reactor, int iterations) { int ret; do { - ret = epoll_wait(reactor->epoll_fd, events, MAX_EVENTS, -1); + ret = TEMP_FAILURE_RETRY(epoll_wait(reactor->epoll_fd, events, MAX_EVENTS, -1)); } while (ret == -1 && errno == EINTR); if (ret == -1) { diff --git a/osi/src/semaphore.c b/osi/src/semaphore.c index 5ee992649..76fba0d55 100644 --- a/osi/src/semaphore.c +++ b/osi/src/semaphore.c @@ -73,12 +73,12 @@ bool semaphore_try_wait(semaphore_t *semaphore) { assert(semaphore != NULL); assert(semaphore->fd != INVALID_FD); - int flags = fcntl(semaphore->fd, F_GETFL); + int flags = TEMP_FAILURE_RETRY(fcntl(semaphore->fd, F_GETFL)); if (flags == -1) { LOG_ERROR("%s unable to get flags for semaphore fd: %s", __func__, strerror(errno)); return false; } - if (fcntl(semaphore->fd, F_SETFL, flags | O_NONBLOCK) == -1) { + if (TEMP_FAILURE_RETRY(fcntl(semaphore->fd, F_SETFL, flags | O_NONBLOCK)) == -1) { LOG_ERROR("%s unable to set O_NONBLOCK for semaphore fd: %s", __func__, strerror(errno)); return false; } @@ -87,7 +87,7 @@ bool semaphore_try_wait(semaphore_t *semaphore) { if (eventfd_read(semaphore->fd, &value) == -1) return false; - if (fcntl(semaphore->fd, F_SETFL, flags) == -1) + if (TEMP_FAILURE_RETRY(fcntl(semaphore->fd, F_SETFL, flags)) == -1) LOG_ERROR("%s unable to resetore flags for semaphore fd: %s", __func__, strerror(errno)); return true; } diff --git a/osi/src/socket.c b/osi/src/socket.c index 91f084e79..9905ae300 100644 --- a/osi/src/socket.c +++ b/osi/src/socket.c @@ -121,7 +121,7 @@ bool socket_listen(const socket_t *socket, port_t port) { socket_t *socket_accept(const socket_t *socket) { assert(socket != NULL); - int fd = accept(socket->fd, NULL, NULL); + int fd = TEMP_FAILURE_RETRY(accept(socket->fd, NULL, NULL)); if (fd == INVALID_FD) { LOG_ERROR("%s unable to accept socket: %s", __func__, strerror(errno)); return NULL; @@ -142,14 +142,14 @@ ssize_t socket_read(const socket_t *socket, void *buf, size_t count) { assert(socket != NULL); assert(buf != NULL); - return recv(socket->fd, buf, count, MSG_DONTWAIT); + return TEMP_FAILURE_RETRY(recv(socket->fd, buf, count, MSG_DONTWAIT)); } ssize_t socket_write(const socket_t *socket, const void *buf, size_t count) { assert(socket != NULL); assert(buf != NULL); - return send(socket->fd, buf, count, MSG_DONTWAIT); + return TEMP_FAILURE_RETRY(send(socket->fd, buf, count, MSG_DONTWAIT)); } ssize_t socket_write_and_transfer_fd(const socket_t *socket, const void *buf, size_t count, int fd) { @@ -179,7 +179,7 @@ ssize_t socket_write_and_transfer_fd(const socket_t *socket, const void *buf, si header->cmsg_len = CMSG_LEN(sizeof(int)); *(int *)CMSG_DATA(header) = fd; - ssize_t ret = sendmsg(socket->fd, &msg, MSG_DONTWAIT); + ssize_t ret = TEMP_FAILURE_RETRY(sendmsg(socket->fd, &msg, MSG_DONTWAIT)); close(fd); return ret; } @@ -188,7 +188,7 @@ ssize_t socket_bytes_available(const socket_t *socket) { assert(socket != NULL); int size = 0; - if (ioctl(socket->fd, FIONREAD, &size) == -1) + if (TEMP_FAILURE_RETRY(ioctl(socket->fd, FIONREAD, &size)) == -1) return -1; return size; } diff --git a/osi/test/alarm_test.cpp b/osi/test/alarm_test.cpp index 287d40812..fec828f90 100644 --- a/osi/test/alarm_test.cpp +++ b/osi/test/alarm_test.cpp @@ -32,7 +32,7 @@ static int cb_counter; static const uint64_t EPSILON_MS = 5; static void msleep(uint64_t ms) { - usleep(ms * 1000); + TEMP_FAILURE_RETRY(usleep(ms * 1000)); } class AlarmTest : public AlarmTestHarness { diff --git a/osi/test/atomic_test.cpp b/osi/test/atomic_test.cpp index b0039ab3f..6cde546e5 100644 --- a/osi/test/atomic_test.cpp +++ b/osi/test/atomic_test.cpp @@ -17,7 +17,7 @@ struct atomic_test_s32_s { void *atomic_thread(void *context) { struct atomic_test_s32_s *at = (struct atomic_test_s32_s *)context; for (int i = 0; i < at->max_val; i++) { - usleep(1); + TEMP_FAILURE_RETRY(usleep(1)); atomic_inc_prefix_s32(&at->data[i]); } return NULL; @@ -26,9 +26,9 @@ void *atomic_thread(void *context) { void *atomic_thread_inc_dec(void *context) { struct atomic_test_s32_s *at = (struct atomic_test_s32_s *)context; for (int i = 0; i < at->max_val; i++) { - usleep(1); + TEMP_FAILURE_RETRY(usleep(1)); atomic_inc_prefix_s32(&at->data[i]); - usleep(1); + TEMP_FAILURE_RETRY(usleep(1)); atomic_dec_prefix_s32(&at->data[i]); } return NULL; diff --git a/osi/test/eager_reader_test.cpp b/osi/test/eager_reader_test.cpp index ad00e17b0..d979f42a6 100644 --- a/osi/test/eager_reader_test.cpp +++ b/osi/test/eager_reader_test.cpp @@ -126,7 +126,7 @@ TEST_F(EagerReaderTest, test_small_data) { thread_t *read_thread = thread_new("read_thread"); eager_reader_register(reader, thread_get_reactor(read_thread), expect_data, (void *)small_data); - write(pipefd[1], small_data, strlen(small_data)); + TEMP_FAILURE_RETRY(write(pipefd[1], small_data, strlen(small_data))); semaphore_wait(done); eager_reader_free(reader); @@ -139,7 +139,7 @@ TEST_F(EagerReaderTest, test_large_data_multibyte) { thread_t *read_thread = thread_new("read_thread"); eager_reader_register(reader, thread_get_reactor(read_thread), expect_data_multibyte, (void *)large_data); - write(pipefd[1], large_data, strlen(large_data)); + TEMP_FAILURE_RETRY(write(pipefd[1], large_data, strlen(large_data))); semaphore_wait(done); eager_reader_free(reader); diff --git a/osi/test/reactor_test.cpp b/osi/test/reactor_test.cpp index 6e3a0092a..73a6ae07b 100644 --- a/osi/test/reactor_test.cpp +++ b/osi/test/reactor_test.cpp @@ -64,7 +64,7 @@ TEST_F(ReactorTest, reactor_start_wait_stop) { reactor_t *reactor = reactor_new(); spawn_reactor_thread(reactor); - usleep(50 * 1000); + TEMP_FAILURE_RETRY(usleep(50 * 1000)); EXPECT_TRUE(thread_running); reactor_stop(reactor); @@ -108,7 +108,7 @@ TEST_F(ReactorTest, reactor_unregister_from_separate_thread) { reactor_object_t *object = reactor_register(reactor, fd, NULL, NULL, NULL); spawn_reactor_thread(reactor); - usleep(50 * 1000); + TEMP_FAILURE_RETRY(usleep(50 * 1000)); reactor_unregister(object); reactor_stop(reactor); diff --git a/test/suite/support/callbacks.h b/test/suite/support/callbacks.h index e01de39a2..2ef35156c 100644 --- a/test/suite/support/callbacks.h +++ b/test/suite/support/callbacks.h @@ -20,12 +20,14 @@ #include "base.h" +#include #include +#include #define WAIT(callback) \ do { \ sem_t *semaphore = callbacks_get_semaphore(#callback); \ - sem_wait(semaphore); \ + TEMP_FAILURE_RETRY(sem_wait(semaphore)); \ } while (0) #define CALL_AND_WAIT(expression, callback) \ @@ -33,7 +35,7 @@ sem_t *semaphore = callbacks_get_semaphore(#callback); \ while (!sem_trywait(semaphore)); \ expression; \ - sem_wait(semaphore); \ + TEMP_FAILURE_RETRY(sem_wait(semaphore)); \ } while(0) // To be called from every exit point of the callback. This macro diff --git a/tools/hci/main.c b/tools/hci/main.c index fc433bcda..97fbef1e7 100644 --- a/tools/hci/main.c +++ b/tools/hci/main.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -149,16 +150,16 @@ static bool write_hci_command(hci_packet_t type, const void *packet, size_t leng addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(0x7F000001); addr.sin_port = htons(8873); - if (connect(sock, (const struct sockaddr *)&addr, sizeof(addr)) == -1) + if (TEMP_FAILURE_RETRY(connect(sock, (const struct sockaddr *)&addr, sizeof(addr))) == -1) goto error; - if (send(sock, &type, 1, 0) != 1) + if (TEMP_FAILURE_RETRY(send(sock, &type, 1, 0)) != 1) goto error; - if (send(sock, &length, 2, 0) != 2) + if (TEMP_FAILURE_RETRY(send(sock, &length, 2, 0)) != 2) goto error; - if (send(sock, packet, length, 0) != (ssize_t)length) + if (TEMP_FAILURE_RETRY(send(sock, packet, length, 0)) != (ssize_t)length) goto error; close(sock); diff --git a/udrv/ulinux/uipc.c b/udrv/ulinux/uipc.c index f3c746e09..5a94d73c8 100644 --- a/udrv/ulinux/uipc.c +++ b/udrv/ulinux/uipc.c @@ -184,7 +184,7 @@ static int accept_server_socket(int sfd) pfd.fd = sfd; pfd.events = POLLIN; - if (poll(&pfd, 1, 0) == 0) + if (TEMP_FAILURE_RETRY(poll(&pfd, 1, 0)) == 0) { BTIF_TRACE_EVENT("accept poll timeout"); return -1; @@ -192,7 +192,7 @@ static int accept_server_socket(int sfd) //BTIF_TRACE_EVENT("poll revents 0x%x", pfd.revents); - if ((fd = accept(sfd, (struct sockaddr *)&remote, &len)) == -1) + if ((fd = TEMP_FAILURE_RETRY(accept(sfd, (struct sockaddr *)&remote, &len))) == -1) { BTIF_TRACE_ERROR("sock accept failed (%s)", strerror(errno)); return -1; @@ -330,7 +330,7 @@ static void uipc_check_interrupt_locked(void) { char sig_recv = 0; //BTIF_TRACE_EVENT("UIPC INTERRUPT"); - recv(uipc_main.signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL); + TEMP_FAILURE_RETRY(recv(uipc_main.signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL)); } } @@ -338,7 +338,7 @@ static inline void uipc_wakeup_locked(void) { char sig_on = 1; BTIF_TRACE_EVENT("UIPC SEND WAKE UP"); - send(uipc_main.signal_fds[1], &sig_on, sizeof(sig_on), 0); + TEMP_FAILURE_RETRY(send(uipc_main.signal_fds[1], &sig_on, sizeof(sig_on), 0)); } static int uipc_setup_server_locked(tUIPC_CH_ID ch_id, char *name, tUIPC_RCV_CBACK *cback) @@ -394,7 +394,7 @@ static void uipc_flush_ch_locked(tUIPC_CH_ID ch_id) while (1) { - ret = poll(&pfd, 1, 1); + ret = TEMP_FAILURE_RETRY(poll(&pfd, 1, 1)); BTIF_TRACE_VERBOSE("%s() - polling fd %d, revents: 0x%x, ret %d", __FUNCTION__, pfd.fd, pfd.revents, ret); @@ -412,7 +412,7 @@ static void uipc_flush_ch_locked(tUIPC_CH_ID ch_id) /* read sufficiently large buffer to ensure flush empties socket faster than it is getting refilled */ - read(pfd.fd, &buf, UIPC_FLUSH_BUFFER_SIZE); + TEMP_FAILURE_RETRY(read(pfd.fd, &buf, UIPC_FLUSH_BUFFER_SIZE)); } } @@ -502,7 +502,7 @@ static void uipc_read_task(void *arg) { uipc_main.read_set = uipc_main.active_set; - result = select(uipc_main.max_fd+1, &uipc_main.read_set, NULL, NULL, NULL); + result = TEMP_FAILURE_RETRY(select(uipc_main.max_fd+1, &uipc_main.read_set, NULL, NULL, NULL)); if (result == 0) { @@ -715,7 +715,7 @@ BOOLEAN UIPC_Send(tUIPC_CH_ID ch_id, UINT16 msg_evt, UINT8 *p_buf, UIPC_LOCK(); - if (write(uipc_main.ch[ch_id].fd, p_buf, msglen) < 0) + if (TEMP_FAILURE_RETRY(write(uipc_main.ch[ch_id].fd, p_buf, msglen)) < 0) { BTIF_TRACE_ERROR("failed to write (%s)", strerror(errno)); } @@ -784,7 +784,7 @@ UINT32 UIPC_Read(tUIPC_CH_ID ch_id, UINT16 *p_msg_evt, UINT8 *p_buf, UINT32 len) /* make sure there is data prior to attempting read to avoid blocking a read for more than poll timeout */ - if (poll(&pfd, 1, uipc_main.ch[ch_id].read_poll_tmo_ms) == 0) + if (TEMP_FAILURE_RETRY(poll(&pfd, 1, uipc_main.ch[ch_id].read_poll_tmo_ms)) == 0) { BTIF_TRACE_EVENT("poll timeout (%d ms)", uipc_main.ch[ch_id].read_poll_tmo_ms); break; @@ -801,7 +801,7 @@ UINT32 UIPC_Read(tUIPC_CH_ID ch_id, UINT16 *p_msg_evt, UINT8 *p_buf, UINT32 len) return 0; } - n = recv(fd, p_buf+n_read, len-n_read, 0); + n = TEMP_FAILURE_RETRY(recv(fd, p_buf+n_read, len-n_read, 0)); //BTIF_TRACE_EVENT("read %d bytes", n); -- 2.11.0