LocIpc could be using data member from a deleted obj
startListeningBlocking is meant to be called under a reader thread, which is the case if startListeningNonBlocking calls it. A LocIpc client may delete the LocIpc obj, which would trigger sending an ABORT msg to the reader thread before it is subsequently deleted, in which case, it is possible that when the reader thread comes around to process the ABORT msg, referencing the data members of the possibly stale obj would cause unpredictable behaviors. Change-Id: I441af85c04d92b6fff695c020e3e0b4bd5e90409 CRs-Fixed: 2380093
This commit is contained in:
parent
400c1e8b57
commit
99e5e01b13
2 changed files with 53 additions and 67 deletions
117
utils/LocIpc.cpp
117
utils/LocIpc.cpp
|
@ -69,8 +69,9 @@ bool LocIpc::startListeningNonBlocking(const std::string& name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LocIpc::startListeningBlocking(const std::string& name) {
|
bool LocIpc::startListeningBlocking(const std::string& name) {
|
||||||
|
bool stopRequested = false;
|
||||||
int fd = socket(AF_UNIX, SOCK_DGRAM, 0);
|
int fd = socket(AF_UNIX, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
LOC_LOGe("create socket error. reason:%s", strerror(errno));
|
LOC_LOGe("create socket error. reason:%s", strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
|
@ -87,89 +88,75 @@ bool LocIpc::startListeningBlocking(const std::string& name) {
|
||||||
|
|
||||||
if (::bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
if (::bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||||
LOC_LOGe("bind socket error. reason:%s", strerror(errno));
|
LOC_LOGe("bind socket error. reason:%s", strerror(errno));
|
||||||
::close(fd);
|
} else {
|
||||||
fd = -1;
|
mIpcFd = fd;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mIpcFd = fd;
|
// inform that the socket is ready to receive message
|
||||||
|
onListenerReady();
|
||||||
|
|
||||||
// inform that the socket is ready to receive message
|
ssize_t nBytes = 0;
|
||||||
onListenerReady();
|
std::string msg = "";
|
||||||
|
std::string abort = LOC_MSG_ABORT;
|
||||||
ssize_t nBytes = 0;
|
while (1) {
|
||||||
std::string msg = "";
|
msg.resize(LOC_MSG_BUF_LEN);
|
||||||
std::string abort = LOC_MSG_ABORT;
|
nBytes = ::recvfrom(fd, (void*)(msg.data()), msg.size(), 0, NULL, NULL);
|
||||||
while (1) {
|
if (nBytes < 0) {
|
||||||
msg.resize(LOC_MSG_BUF_LEN);
|
LOC_LOGe("cannot read socket. reason:%s", strerror(errno));
|
||||||
nBytes = ::recvfrom(mIpcFd, (void*)(msg.data()), msg.size(), 0, NULL, NULL);
|
break;
|
||||||
if (nBytes < 0) {
|
} else if (0 == nBytes) {
|
||||||
break;
|
continue;
|
||||||
} else if (nBytes == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strncmp(msg.data(), abort.c_str(), abort.length()) == 0) {
|
|
||||||
LOC_LOGi("recvd abort msg.data %s", msg.data());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strncmp(msg.data(), LOC_MSG_HEAD, sizeof(LOC_MSG_HEAD) - 1)) {
|
|
||||||
// short message
|
|
||||||
msg.resize(nBytes);
|
|
||||||
onReceive(msg);
|
|
||||||
} else {
|
|
||||||
// long message
|
|
||||||
size_t msgLen = 0;
|
|
||||||
sscanf(msg.data(), LOC_MSG_HEAD"%zu", &msgLen);
|
|
||||||
msg.resize(msgLen);
|
|
||||||
size_t msgLenReceived = 0;
|
|
||||||
while ((msgLenReceived < msgLen) && (nBytes > 0)) {
|
|
||||||
nBytes = recvfrom(mIpcFd, (void*)&(msg[msgLenReceived]),
|
|
||||||
msg.size() - msgLenReceived, 0, NULL, NULL);
|
|
||||||
msgLenReceived += nBytes;
|
|
||||||
}
|
}
|
||||||
if (nBytes > 0) {
|
|
||||||
onReceive(msg);
|
if (strncmp(msg.data(), abort.c_str(), abort.length()) == 0) {
|
||||||
} else {
|
LOC_LOGi("recvd abort msg.data %s", msg.data());
|
||||||
|
stopRequested = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strncmp(msg.data(), LOC_MSG_HEAD, sizeof(LOC_MSG_HEAD) - 1)) {
|
||||||
|
// short message
|
||||||
|
msg.resize(nBytes);
|
||||||
|
onReceive(msg);
|
||||||
|
} else {
|
||||||
|
// long message
|
||||||
|
size_t msgLen = 0;
|
||||||
|
sscanf(msg.data(), LOC_MSG_HEAD"%zu", &msgLen);
|
||||||
|
msg.resize(msgLen);
|
||||||
|
size_t msgLenReceived = 0;
|
||||||
|
while ((msgLenReceived < msgLen) && (nBytes > 0)) {
|
||||||
|
nBytes = recvfrom(fd, (void*)&(msg[msgLenReceived]),
|
||||||
|
msg.size() - msgLenReceived, 0, NULL, NULL);
|
||||||
|
msgLenReceived += nBytes;
|
||||||
|
}
|
||||||
|
if (nBytes > 0) {
|
||||||
|
onReceive(msg);
|
||||||
|
} else {
|
||||||
|
LOC_LOGe("cannot read socket. reason:%s", strerror(errno));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mStopRequested) {
|
if (::close(fd)) {
|
||||||
mStopRequested = false;
|
LOC_LOGe("cannot close socket:%s", strerror(errno));
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
LOC_LOGe("cannot read socket. reason:%s", strerror(errno));
|
|
||||||
(void)::close(mIpcFd);
|
|
||||||
mIpcFd = -1;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
unlink(name.c_str());
|
||||||
|
|
||||||
|
return stopRequested;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocIpc::stopListening() {
|
void LocIpc::stopListening() {
|
||||||
|
|
||||||
const char *socketName = nullptr;
|
const char *socketName = nullptr;
|
||||||
mStopRequested = true;
|
|
||||||
|
|
||||||
if (mRunnable) {
|
if (mIpcFd >= 0) {
|
||||||
std::string abort = LOC_MSG_ABORT;
|
std::string abort = LOC_MSG_ABORT;
|
||||||
socketName = (reinterpret_cast<LocIpcRunnable *>(mRunnable))->mIpcName.c_str();
|
socketName = (reinterpret_cast<LocIpcRunnable *>(mRunnable))->mIpcName.c_str();
|
||||||
send(socketName, abort);
|
send(socketName, abort);
|
||||||
mRunnable = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mIpcFd >= 0) {
|
|
||||||
if (::close(mIpcFd)) {
|
|
||||||
LOC_LOGe("cannot close socket:%s", strerror(errno));
|
|
||||||
}
|
|
||||||
mIpcFd = -1;
|
mIpcFd = -1;
|
||||||
}
|
}
|
||||||
|
if (mRunnable) {
|
||||||
//delete from the file system at the end
|
mRunnable = nullptr;
|
||||||
if (socketName) {
|
|
||||||
unlink(socketName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ class LocIpcSender;
|
||||||
class LocIpc {
|
class LocIpc {
|
||||||
friend LocIpcSender;
|
friend LocIpcSender;
|
||||||
public:
|
public:
|
||||||
inline LocIpc() : mIpcFd(-1), mStopRequested(false), mRunnable(nullptr) {}
|
inline LocIpc() : mIpcFd(-1), mRunnable(nullptr) {}
|
||||||
inline virtual ~LocIpc() { stopListening(); }
|
inline virtual ~LocIpc() { stopListening(); }
|
||||||
|
|
||||||
// Listen for new messages in current thread. Calling this funciton will
|
// Listen for new messages in current thread. Calling this funciton will
|
||||||
|
@ -93,7 +93,6 @@ private:
|
||||||
const uint8_t data[], uint32_t length);
|
const uint8_t data[], uint32_t length);
|
||||||
|
|
||||||
int mIpcFd;
|
int mIpcFd;
|
||||||
bool mStopRequested;
|
|
||||||
LocThread mThread;
|
LocThread mThread;
|
||||||
LocRunnable *mRunnable;
|
LocRunnable *mRunnable;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue