Print this page
NEX-16554 alloca() in libscf causes an iSCSI application to crash
Reviewed by: Yuri Pankon <yuri.pankov@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
*** 36,46 ****
#include "repcache_protocol.h"
#include "scf_type.h"
#include <assert.h>
- #include <alloca.h>
#include <door.h>
#include <errno.h>
#include <fcntl.h>
#include <fnmatch.h>
#include <libuutil.h>
--- 36,45 ----
*** 4080,4091 ****
assert(TX_SIZE(size) == size);
total += size;
}
request_size = REP_PROTOCOL_TRANSACTION_COMMIT_SIZE(total);
! request = alloca(request_size);
! (void) memset(request, '\0', request_size);
request->rpr_request = REP_PROTOCOL_PROPERTYGRP_TX_COMMIT;
request->rpr_entityid = tran->tran_pg.rd_d.rd_entity;
request->rpr_size = request_size;
cmd = (uintptr_t)request->rpr_cmd;
--- 4079,4094 ----
assert(TX_SIZE(size) == size);
total += size;
}
request_size = REP_PROTOCOL_TRANSACTION_COMMIT_SIZE(total);
! request = calloc(1, request_size);
! if (request == NULL) {
! (void) pthread_mutex_unlock(&h->rh_lock);
! return (scf_set_error(SCF_ERROR_NO_MEMORY));
! }
!
request->rpr_request = REP_PROTOCOL_PROPERTYGRP_TX_COMMIT;
request->rpr_entityid = tran->tran_pg.rd_d.rd_entity;
request->rpr_size = request_size;
cmd = (uintptr_t)request->rpr_cmd;
*** 4095,4105 ****
for (cur = uu_list_first(tran->tran_props); cur != NULL;
cur = uu_list_next(tran->tran_props, cur)) {
size = commit_process(cur, (void *)cmd);
if (size == BAD_SIZE) {
(void) pthread_mutex_unlock(&h->rh_lock);
! return (scf_set_error(SCF_ERROR_INTERNAL));
}
cmd += size;
new_total += size;
}
assert(new_total == total);
--- 4098,4109 ----
for (cur = uu_list_first(tran->tran_props); cur != NULL;
cur = uu_list_next(tran->tran_props, cur)) {
size = commit_process(cur, (void *)cmd);
if (size == BAD_SIZE) {
(void) pthread_mutex_unlock(&h->rh_lock);
! r = (scf_set_error(SCF_ERROR_INTERNAL));
! goto out;
}
cmd += size;
new_total += size;
}
assert(new_total == total);
*** 4113,4128 ****
}
if (response.rpr_response != REP_PROTOCOL_SUCCESS &&
response.rpr_response != REP_PROTOCOL_FAIL_NOT_LATEST) {
(void) pthread_mutex_unlock(&h->rh_lock);
! return (scf_set_error(proto_error(response.rpr_response)));
}
tran->tran_state = TRAN_STATE_COMMITTED;
(void) pthread_mutex_unlock(&h->rh_lock);
! return (response.rpr_response == REP_PROTOCOL_SUCCESS);
}
static void
transaction_reset(scf_transaction_t *tran)
{
--- 4117,4137 ----
}
if (response.rpr_response != REP_PROTOCOL_SUCCESS &&
response.rpr_response != REP_PROTOCOL_FAIL_NOT_LATEST) {
(void) pthread_mutex_unlock(&h->rh_lock);
! r = (scf_set_error(proto_error(response.rpr_response)));
! goto out;
}
tran->tran_state = TRAN_STATE_COMMITTED;
(void) pthread_mutex_unlock(&h->rh_lock);
! r = (response.rpr_response == REP_PROTOCOL_SUCCESS);
!
! out:
! free(request);
! return (r);
}
static void
transaction_reset(scf_transaction_t *tran)
{