Prevent potential double-free if srtp_create fails.

If srtp_create fails while adding streams, it deallocates the session
but doesn't clear the passed pointer which then could lead to a
double-free in the SrtpSession dtor.

The CL also adds locking for libsrtp initialization / shutdown.

BUG=4042
R=jiayl@webrtc.org, juberti@google.com, pthatcher@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/47319004

Cr-Commit-Position: refs/heads/master@{#9300}
This commit is contained in:
Joachim Bauch 2015-05-27 23:41:43 +02:00
parent 10602605f8
commit fec2c6d7eb
4 changed files with 27 additions and 0 deletions

View File

@ -474,6 +474,7 @@ bool SrtpFilter::ParseKeyParams(const std::string& key_params,
#ifdef HAVE_SRTP
bool SrtpSession::inited_ = false;
rtc::GlobalLockPod SrtpSession::lock_;
SrtpSession::SrtpSession()
: session_(NULL),
@ -691,6 +692,7 @@ bool SrtpSession::SetKey(int type, const std::string& cs,
int err = srtp_create(&session_, &policy);
if (err != err_status_ok) {
session_ = NULL;
LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err;
return false;
}
@ -702,6 +704,8 @@ bool SrtpSession::SetKey(int type, const std::string& cs,
}
bool SrtpSession::Init() {
rtc::GlobalLockScope ls(&lock_);
if (!inited_) {
int err;
err = srtp_init();
@ -729,6 +733,8 @@ bool SrtpSession::Init() {
}
void SrtpSession::Terminate() {
rtc::GlobalLockScope ls(&lock_);
if (inited_) {
int err = srtp_shutdown();
if (err) {

View File

@ -36,6 +36,7 @@
#include "talk/media/base/cryptoparams.h"
#include "webrtc/p2p/base/sessiondescription.h"
#include "webrtc/base/basictypes.h"
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/sigslotrepeater.h"
@ -242,6 +243,7 @@ class SrtpSession {
int rtcp_auth_tag_len_;
rtc::scoped_ptr<SrtpStat> srtp_stat_;
static bool inited_;
static rtc::GlobalLockPod lock_;
int last_send_seq_num_;
DISALLOW_COPY_AND_ASSIGN(SrtpSession);
};

View File

@ -152,4 +152,13 @@ GlobalLock::GlobalLock() {
lock_acquired = 0;
}
GlobalLockScope::GlobalLockScope(GlobalLockPod* lock)
: lock_(lock) {
lock_->Lock();
}
GlobalLockScope::~GlobalLockScope() {
lock_->Unlock();
}
} // namespace rtc

View File

@ -114,6 +114,16 @@ class GlobalLock : public GlobalLockPod {
GlobalLock();
};
// GlobalLockScope, for serializing execution through a scope.
class SCOPED_LOCKABLE GlobalLockScope {
public:
explicit GlobalLockScope(GlobalLockPod* lock) EXCLUSIVE_LOCK_FUNCTION(lock);
~GlobalLockScope() UNLOCK_FUNCTION();
private:
GlobalLockPod* const lock_;
DISALLOW_COPY_AND_ASSIGN(GlobalLockScope);
};
} // namespace rtc
#endif // WEBRTC_BASE_CRITICALSECTION_H_