Segfault in pri_schedule_del() - ctrl value is invalid.
Validate the given call pointer in libpri API calls. If the call pointer is not an active call record then a complaint message is issued and the API call aborts. The call pointer is likely stale. This patch is defensive. More information is needed to figure out why Asterisk still has a call pointer during its hangup sequence. (closes issue #17522) (closes issue #18032) Reported by: schmoozecom Patches: issue_18032_v1.4.patch uploaded by rmudgett (license 664) Tested by: rmudgett git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@2015 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
104
pri.c
104
pri.c
@@ -416,8 +416,15 @@ struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master,
|
||||
|
||||
void pri_call_set_useruser(q931_call *c, const char *userchars)
|
||||
{
|
||||
if (userchars)
|
||||
libpri_copy_string(c->useruserinfo, userchars, sizeof(c->useruserinfo));
|
||||
/*
|
||||
* There is a slight risk here if c is actually stale. However,
|
||||
* if it is stale then it is better to catch it here than to
|
||||
* write with it.
|
||||
*/
|
||||
if (!userchars || !pri_is_call_valid(NULL, c)) {
|
||||
return;
|
||||
}
|
||||
libpri_copy_string(c->useruserinfo, userchars, sizeof(c->useruserinfo));
|
||||
}
|
||||
|
||||
void pri_sr_set_useruser(struct pri_sr *sr, const char *userchars)
|
||||
@@ -642,80 +649,89 @@ void pri_facility_enable(struct pri *pri)
|
||||
|
||||
int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_alerting(pri, call, channel, info);
|
||||
}
|
||||
|
||||
int pri_proceeding(struct pri *pri, q931_call *call, int channel, int info)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_call_proceeding(pri, call, channel, info);
|
||||
}
|
||||
|
||||
int pri_progress_with_cause(struct pri *pri, q931_call *call, int channel, int info, int cause)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return q931_call_progress_with_cause(pri, call, channel, info, cause);
|
||||
}
|
||||
|
||||
int pri_progress(struct pri *pri, q931_call *call, int channel, int info)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return q931_call_progress(pri, call, channel, info);
|
||||
}
|
||||
|
||||
int pri_information(struct pri *pri, q931_call *call, char digit)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_information(pri, call, digit);
|
||||
}
|
||||
|
||||
int pri_keypad_facility(struct pri *pri, q931_call *call, const char *digits)
|
||||
{
|
||||
if (!pri || !call || !digits || !digits[0])
|
||||
if (!pri || !pri_is_call_valid(pri, call) || !digits || !digits[0]) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return q931_keypad_facility(pri, call, digits);
|
||||
}
|
||||
|
||||
int pri_notify(struct pri *pri, q931_call *call, int channel, int info)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_notify(pri, call, channel, info);
|
||||
}
|
||||
|
||||
void pri_destroycall(struct pri *pri, q931_call *call)
|
||||
{
|
||||
if (pri && call)
|
||||
if (pri && pri_is_call_valid(pri, call)) {
|
||||
q931_destroycall(pri, call);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int nonisdn)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_setup_ack(pri, call, channel, nonisdn);
|
||||
}
|
||||
|
||||
int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_connect(pri, call, channel, nonisdn);
|
||||
}
|
||||
|
||||
int pri_connect_ack(struct pri *ctrl, q931_call *call, int channel)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_connect_acknowledge(ctrl, call, channel);
|
||||
@@ -821,7 +837,7 @@ int pri_connected_line_update(struct pri *ctrl, q931_call *call, const struct pr
|
||||
unsigned idx;
|
||||
struct q931_call *subcall;
|
||||
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -887,7 +903,7 @@ int pri_redirecting_update(struct pri *ctrl, q931_call *call, const struct pri_p
|
||||
unsigned idx;
|
||||
struct q931_call *subcall;
|
||||
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1037,15 +1053,17 @@ void pri_status_req_rsp(struct pri *ctrl, int invoke_id, int status)
|
||||
/* deprecated routines, use pri_hangup */
|
||||
int pri_release(struct pri *pri, q931_call *call, int cause)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_release(pri, call, cause);
|
||||
}
|
||||
|
||||
int pri_disconnect(struct pri *pri, q931_call *call, int cause)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_disconnect(pri, call, cause);
|
||||
}
|
||||
#endif
|
||||
@@ -1054,8 +1072,14 @@ int pri_channel_bridge(q931_call *call1, q931_call *call2)
|
||||
{
|
||||
struct q931_call *winner;
|
||||
|
||||
if (!call1 || !call2)
|
||||
/*
|
||||
* There is a slight risk here if call1 or call2 is actually
|
||||
* stale. However, if they are stale then it is better to catch
|
||||
* it here than to write with these pointers.
|
||||
*/
|
||||
if (!pri_is_call_valid(NULL, call1) || !pri_is_call_valid(NULL, call2)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
winner = q931_find_winning_call(call1);
|
||||
if (!winner) {
|
||||
@@ -1122,8 +1146,9 @@ void pri_hangup_fix_enable(struct pri *ctrl, int enable)
|
||||
|
||||
int pri_hangup(struct pri *pri, q931_call *call, int cause)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
if (cause == -1)
|
||||
/* normal clear cause */
|
||||
cause = PRI_CAUSE_NORMAL_CLEARING;
|
||||
@@ -1201,8 +1226,10 @@ int pri_mwi_activate(struct pri *pri, q931_call *c, char *caller, int callerplan
|
||||
int calledplan)
|
||||
{
|
||||
struct pri_sr req;
|
||||
if (!pri || !c)
|
||||
|
||||
if (!pri || !pri_is_call_valid(pri, c)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pri_sr_init(&req);
|
||||
pri_sr_set_connection_call_independent(&req);
|
||||
@@ -1221,8 +1248,10 @@ int pri_mwi_deactivate(struct pri *pri, q931_call *c, char *caller, int callerpl
|
||||
int calledplan)
|
||||
{
|
||||
struct pri_sr req;
|
||||
if (!pri || !c)
|
||||
|
||||
if (!pri || !pri_is_call_valid(pri, c)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pri_sr_init(&req);
|
||||
pri_sr_set_connection_call_independent(&req);
|
||||
@@ -1239,8 +1268,9 @@ int pri_mwi_deactivate(struct pri *pri, q931_call *c, char *caller, int callerpl
|
||||
|
||||
int pri_setup(struct pri *pri, q931_call *c, struct pri_sr *req)
|
||||
{
|
||||
if (!pri || !c)
|
||||
if (!pri || !pri_is_call_valid(pri, c)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return q931_setup(pri, c, req);
|
||||
}
|
||||
@@ -1250,8 +1280,11 @@ int pri_call(struct pri *pri, q931_call *c, int transmode, int channel, int excl
|
||||
int calledplan, int ulayer1)
|
||||
{
|
||||
struct pri_sr req;
|
||||
if (!pri || !c)
|
||||
|
||||
if (!pri || !pri_is_call_valid(pri, c)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pri_sr_init(&req);
|
||||
pri_sr_set_caller(&req, caller, callername, callerplan, callerpres);
|
||||
pri_sr_set_called(&req, called, calledplan, 0);
|
||||
@@ -1494,11 +1527,17 @@ char *pri_dump_info_str(struct pri *ctrl)
|
||||
|
||||
int pri_get_crv(struct pri *pri, q931_call *call, int *callmode)
|
||||
{
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_call_getcrv(pri, call, callmode);
|
||||
}
|
||||
|
||||
int pri_set_crv(struct pri *pri, q931_call *call, int crv, int callmode)
|
||||
{
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_call_setcrv(pri, call, crv, callmode);
|
||||
}
|
||||
|
||||
@@ -1655,7 +1694,7 @@ void pri_hold_enable(struct pri *ctrl, int enable)
|
||||
|
||||
int pri_hold(struct pri *ctrl, q931_call *call)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_send_hold(ctrl, call);
|
||||
@@ -1663,7 +1702,7 @@ int pri_hold(struct pri *ctrl, q931_call *call)
|
||||
|
||||
int pri_hold_ack(struct pri *ctrl, q931_call *call)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_send_hold_ack(ctrl, call);
|
||||
@@ -1671,7 +1710,7 @@ int pri_hold_ack(struct pri *ctrl, q931_call *call)
|
||||
|
||||
int pri_hold_rej(struct pri *ctrl, q931_call *call, int cause)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_send_hold_rej(ctrl, call, cause);
|
||||
@@ -1679,7 +1718,7 @@ int pri_hold_rej(struct pri *ctrl, q931_call *call, int cause)
|
||||
|
||||
int pri_retrieve(struct pri *ctrl, q931_call *call, int channel)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_send_retrieve(ctrl, call, channel);
|
||||
@@ -1687,7 +1726,7 @@ int pri_retrieve(struct pri *ctrl, q931_call *call, int channel)
|
||||
|
||||
int pri_retrieve_ack(struct pri *ctrl, q931_call *call, int channel)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_send_retrieve_ack(ctrl, call, channel);
|
||||
@@ -1695,7 +1734,7 @@ int pri_retrieve_ack(struct pri *ctrl, q931_call *call, int channel)
|
||||
|
||||
int pri_retrieve_rej(struct pri *ctrl, q931_call *call, int cause)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_send_retrieve_rej(ctrl, call, cause);
|
||||
@@ -1703,8 +1742,9 @@ int pri_retrieve_rej(struct pri *ctrl, q931_call *call, int cause)
|
||||
|
||||
int pri_callrerouting_facility(struct pri *pri, q931_call *call, const char *dest, const char* original, const char* reason)
|
||||
{
|
||||
if (!pri || !call || !dest)
|
||||
if (!pri || !pri_is_call_valid(pri, call) || !dest) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return qsig_cf_callrerouting(pri, call, dest, original, reason);
|
||||
}
|
||||
@@ -1723,7 +1763,7 @@ int pri_reroute_call(struct pri *ctrl, q931_call *call, const struct pri_party_i
|
||||
struct q931_party_id local_caller;
|
||||
struct q931_party_redirecting reroute;
|
||||
|
||||
if (!ctrl || !call || !deflection) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call) || !deflection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user