protect sf_buffer from overrun in receive_samples

this patch adds a buffer len paramter to the receive_samples() call
that protects the (also) provided buffer from overflowing.

currently each call to srslte_ue_sync_zerocopy() which then calls receive_samples()
relies on a buffer that is "big enough". But that buffer is sometimes
2 subframes, sometimes 3 or 5, sometimes has space for the maximum PRB size, sometimes
only for 6 PRBs (i.e. during cell search).

By extending the interface to pass the buffer size we can make sure that
only samples are received that actually fit inside the provided buffer.
master
Andre Puschmann 5 years ago
parent 23bab1f207
commit c7343cf6d8

@ -564,8 +564,9 @@ int main(int argc, char** argv)
#endif
}
uint32_t max_num_samples = 3 * SRSLTE_SF_LEN_PRB(cell.nof_prb); /// Length in complex samples
for (int i = 0; i < prog_args.rf_nof_rx_ant; i++) {
sf_buffer[i] = srslte_vec_malloc(3 * sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
sf_buffer[i] = srslte_vec_cf_malloc(max_num_samples);
}
srslte_ue_mib_t ue_mib;
if (srslte_ue_mib_init(&ue_mib, sf_buffer, cell.nof_prb)) {
@ -710,7 +711,7 @@ int main(int argc, char** argv)
for (int p = 0; p < SRSLTE_MAX_PORTS; p++) {
buffers[p] = sf_buffer[p];
}
ret = srslte_ue_sync_zerocopy(&ue_sync, buffers);
ret = srslte_ue_sync_zerocopy(&ue_sync, buffers, max_num_samples);
if (ret < 0) {
ERROR("Error calling srslte_ue_sync_work()\n");
}

@ -132,8 +132,9 @@ int main(int argc, char** argv)
exit(-1);
}
uint32_t max_num_samples = 3 * SRSLTE_SF_LEN_MAX;
for (int i = 0; i < nof_rx_antennas; i++) {
buffer[i] = srslte_vec_malloc(3 * sizeof(cf_t) * SRSLTE_SF_LEN_PRB(100));
buffer[i] = srslte_vec_cf_malloc(max_num_samples);
}
sigset_t sigset;
@ -176,7 +177,7 @@ int main(int argc, char** argv)
bool start_capture = false;
bool stop_capture = false;
while ((subframe_count < nof_subframes || nof_subframes == -1) && !stop_capture) {
n = srslte_ue_sync_zerocopy(&ue_sync, buffer);
n = srslte_ue_sync_zerocopy(&ue_sync, buffer, max_num_samples);
if (n < 0) {
ERROR("Error receiving samples\n");
exit(-1);

@ -50,7 +50,6 @@
#include "srslte/phy/phch/pbch.h"
#include "srslte/phy/dft/ofdm.h"
#define SRSLTE_UE_MIB_NOF_PRB 6
#define SRSLTE_UE_MIB_FOUND 1

@ -205,13 +205,12 @@ SRSLTE_API int srslte_ue_sync_start_agc(srslte_ue_sync_t* q,
float max_gain,
float init_gain_value);
SRSLTE_API uint32_t srslte_ue_sync_sf_len(srslte_ue_sync_t *q);
SRSLTE_API uint32_t srslte_ue_sync_sf_len(srslte_ue_sync_t* q);
SRSLTE_API void srslte_ue_sync_set_agc_period(srslte_ue_sync_t *q,
uint32_t period);
SRSLTE_API void srslte_ue_sync_set_agc_period(srslte_ue_sync_t* q, uint32_t period);
/* CAUTION: input_buffer MUST have space for 2 subframes */
SRSLTE_API int srslte_ue_sync_zerocopy(srslte_ue_sync_t* q, cf_t* input_buffer[SRSLTE_MAX_PORTS]);
SRSLTE_API int
srslte_ue_sync_zerocopy(srslte_ue_sync_t* q, cf_t* input_buffer[SRSLTE_MAX_PORTS], const uint32_t max_num_samples);
SRSLTE_API void srslte_ue_sync_set_cfo_tol(srslte_ue_sync_t* q, float tol);

@ -31,6 +31,8 @@
#include "srslte/phy/utils/debug.h"
#include "srslte/phy/utils/vector.h"
#define CELL_SEARCH_BUFFER_MAX_SAMPLES (3 * SRSLTE_SF_LEN_MAX)
int srslte_ue_cellsearch_init(srslte_ue_cellsearch_t* q,
uint32_t max_frames,
int(recv_callback)(void*, void*, uint32_t, srslte_timestamp_t*),
@ -61,7 +63,7 @@ int srslte_ue_cellsearch_init(srslte_ue_cellsearch_t* q,
for (int p = 0; p < SRSLTE_MAX_PORTS; p++) {
q->sf_buffer[p] = NULL;
}
q->sf_buffer[0] = srslte_vec_malloc(3 * sizeof(cf_t) * SRSLTE_SF_LEN_PRB(100));
q->sf_buffer[0] = srslte_vec_cf_malloc(CELL_SEARCH_BUFFER_MAX_SAMPLES);
q->nof_rx_antennas = 1;
q->candidates = calloc(sizeof(srslte_ue_cellsearch_result_t), max_frames);
@ -121,8 +123,7 @@ int srslte_ue_cellsearch_init_multi(srslte_ue_cellsearch_t* q,
}
for (int i = 0; i < nof_rx_antennas; i++) {
q->sf_buffer[i] = srslte_vec_malloc(3 * sizeof(cf_t) * SRSLTE_SF_LEN_PRB(100));
bzero(q->sf_buffer[i], 3 * sizeof(cf_t) * SRSLTE_SF_LEN_PRB(100));
q->sf_buffer[i] = srslte_vec_cf_malloc(CELL_SEARCH_BUFFER_MAX_SAMPLES);
}
q->nof_rx_antennas = nof_rx_antennas;
@ -305,7 +306,7 @@ int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t* q,
srslte_ue_sync_set_nof_find_frames(&q->ue_sync, q->max_frames);
do {
ret = srslte_ue_sync_zerocopy(&q->ue_sync, q->sf_buffer);
ret = srslte_ue_sync_zerocopy(&q->ue_sync, q->sf_buffer, CELL_SEARCH_BUFFER_MAX_SAMPLES);
if (ret < 0) {
ERROR("Error calling srslte_ue_sync_work()\n");
return -1;

@ -31,6 +31,8 @@
#include "srslte/phy/utils/debug.h"
#include "srslte/phy/utils/vector.h"
#define MIB_BUFFER_MAX_SAMPLES (3 * SRSLTE_SF_LEN_PRB(SRSLTE_UE_MIB_NOF_PRB))
int srslte_ue_mib_init(srslte_ue_mib_t* q, cf_t* in_buffer[SRSLTE_MAX_PORTS], uint32_t max_prb)
{
int ret = SRSLTE_ERROR_INVALID_INPUTS;
@ -172,7 +174,7 @@ int srslte_ue_mib_sync_init_multi(srslte_ue_mib_sync_t* q,
void* stream_handler)
{
for (int i = 0; i < nof_rx_antennas; i++) {
q->sf_buffer[i] = srslte_vec_malloc(3 * sizeof(cf_t) * SRSLTE_SF_LEN_PRB(SRSLTE_UE_MIB_NOF_PRB));
q->sf_buffer[i] = srslte_vec_cf_malloc(MIB_BUFFER_MAX_SAMPLES);
}
q->nof_rx_antennas = nof_rx_antennas;
@ -243,7 +245,7 @@ int srslte_ue_mib_sync_decode(srslte_ue_mib_sync_t* q,
ret = SRSLTE_SUCCESS;
do {
mib_ret = SRSLTE_UE_MIB_NOTFOUND;
ret = srslte_ue_sync_zerocopy(&q->ue_sync, q->sf_buffer);
ret = srslte_ue_sync_zerocopy(&q->ue_sync, q->sf_buffer, MIB_BUFFER_MAX_SAMPLES);
if (ret < 0) {
ERROR("Error calling srslte_ue_sync_work()\n");
return -1;

@ -676,32 +676,36 @@ static int track_peak_no(srslte_ue_sync_t* q)
}
}
static int receive_samples(srslte_ue_sync_t* q, cf_t* input_buffer[SRSLTE_MAX_PORTS])
static int receive_samples(srslte_ue_sync_t* q, cf_t* input_buffer[SRSLTE_MAX_PORTS], const uint32_t max_num_samples)
{
/* A negative time offset means there are samples in our buffer for the next subframe,
because we are sampling too fast.
*/
///< A negative time offset means there are samples in our buffer for the next subframe bc we are sampling too fast
if (q->next_rf_sample_offset < 0) {
q->next_rf_sample_offset = -q->next_rf_sample_offset;
}
/* Get N subframes from the USRP getting more samples and keeping the previous samples, if any */
cf_t* ptr[SRSLTE_MAX_PORTS];
///< Make sure receive buffer is big enough
if (q->frame_len - q->next_rf_sample_offset > max_num_samples) {
fprintf(stderr, "Receive buffer too small (%d < %d)n", max_num_samples, q->frame_len - q->next_rf_sample_offset);
return SRSLTE_ERROR;
}
///< Get N subframes from the USRP getting more samples and keeping the previous samples, if any
cf_t* ptr[SRSLTE_MAX_PORTS] = {NULL};
for (int i = 0; i < q->nof_rx_antennas; i++) {
ptr[i] = &input_buffer[i][q->next_rf_sample_offset];
}
if (q->recv_callback(q->stream, ptr, q->frame_len - q->next_rf_sample_offset, &q->last_timestamp) < 0) {
return SRSLTE_ERROR;
}
/* reset time offset */
///< reset time offset
q->next_rf_sample_offset = 0;
return SRSLTE_SUCCESS;
}
/* Returns 1 if the subframe is synchronized in time, 0 otherwise */
int srslte_ue_sync_zerocopy(srslte_ue_sync_t* q, cf_t* input_buffer[SRSLTE_MAX_PORTS])
int srslte_ue_sync_zerocopy(srslte_ue_sync_t* q, cf_t* input_buffer[SRSLTE_MAX_PORTS], const uint32_t max_num_samples)
{
int ret = SRSLTE_ERROR_INVALID_INPUTS;
uint32_t track_idx;
@ -740,7 +744,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t* q, cf_t* input_buffer[SRSLTE_MAX_P
ret = 1;
} else {
if (receive_samples(q, input_buffer)) {
if (receive_samples(q, input_buffer, max_num_samples)) {
ERROR("Error receiving samples\n");
return SRSLTE_ERROR;
}

@ -40,6 +40,7 @@ public:
/* Functions used by main PHY thread */
cf_t* get_rx_buffer(uint32_t antenna_idx);
cf_t* get_tx_buffer(uint32_t antenna_idx);
uint32_t get_buffer_len();
void set_tti(uint32_t tti);
void set_cfo(float cfo);
@ -100,6 +101,7 @@ private:
bool cell_initiated = false;
cf_t* signal_buffer_rx[SRSLTE_MAX_PORTS] = {};
cf_t* signal_buffer_tx[SRSLTE_MAX_PORTS] = {};
uint32_t signal_buffer_max_samples = 0;
/* Objects for DL */
srslte_ue_dl_t ue_dl = {};

@ -32,6 +32,8 @@
namespace srsue {
namespace scell {
#define SF_BUFFER_MAX_SAMPLES (5 * SRSLTE_SF_LEN_MAX)
class async_scell_recv : private thread
{
public:
@ -84,7 +86,7 @@ private:
{
for (uint32_t i = 0; i < nof_ports; i++) {
// It needs to support cell search
buffer[i] = (cf_t*)srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_MAX * 5);
buffer[i] = srslte_vec_cf_malloc(SF_BUFFER_MAX_SAMPLES);
if (!buffer[i]) {
fprintf(stderr, "Error allocating buffer\n");
}

@ -53,6 +53,7 @@ public:
/* Functions used by main PHY thread */
cf_t* get_buffer(uint32_t cc_idx, uint32_t antenna_idx);
uint32_t get_buffer_len();
void set_tti(uint32_t tti);
void set_tx_time(uint32_t radio_idx, srslte_timestamp_t tx_time, int next_offset);
void set_prach(cf_t* prach_ptr, float prach_power);
@ -90,11 +91,11 @@ private:
std::vector<cc_worker*> cc_workers;
phy_common* phy = nullptr;
;
srslte::log* log_h = nullptr;
;
srslte::log* log_phy_lib_h = nullptr;
;
chest_feedback_itf* chest_loop = nullptr;
std::mutex mutex;

@ -124,6 +124,7 @@ private:
~sfn_sync();
void init(srslte_ue_sync_t* ue_sync,
cf_t* buffer[SRSLTE_MAX_PORTS],
uint32_t buffer_max_samples_,
srslte::log* log_h,
uint32_t nof_subframes = SFN_SYNC_NOF_SUBFRAMES);
void reset();
@ -146,6 +147,7 @@ private:
srslte::log* log_h = nullptr;
srslte_ue_sync_t* ue_sync = nullptr;
cf_t* buffer[SRSLTE_MAX_PORTS] = {};
uint32_t buffer_max_samples = 0;
srslte_ue_mib_t ue_mib = {};
};

@ -56,13 +56,15 @@ cc_worker::cc_worker(uint32_t cc_idx_, uint32_t max_prb, srsue::phy_common* phy_
phy = phy_;
log_h = log_h_;
signal_buffer_max_samples = 3 * SRSLTE_SF_LEN_PRB(max_prb);
for (uint32_t i = 0; i < phy->args->nof_rx_ant; i++) {
signal_buffer_rx[i] = (cf_t*)srslte_vec_malloc(3 * sizeof(cf_t) * SRSLTE_SF_LEN_PRB(max_prb));
signal_buffer_rx[i] = srslte_vec_cf_malloc(signal_buffer_max_samples);
if (!signal_buffer_rx[i]) {
Error("Allocating memory\n");
return;
}
signal_buffer_tx[i] = (cf_t*)srslte_vec_malloc(3 * sizeof(cf_t) * SRSLTE_SF_LEN_PRB(max_prb));
signal_buffer_tx[i] = srslte_vec_cf_malloc(signal_buffer_max_samples);
if (!signal_buffer_tx[i]) {
Error("Allocating memory\n");
return;
@ -154,6 +156,11 @@ bool cc_worker::set_cell(srslte_cell_t cell_)
return true;
}
uint32_t cc_worker::get_buffer_len()
{
return signal_buffer_max_samples;
}
cf_t* cc_worker::get_rx_buffer(uint32_t antenna_idx)
{
return signal_buffer_rx[antenna_idx];

@ -100,7 +100,7 @@ void async_scell_recv::init(srslte::radio_interface_phy* _radio_handler, phy_com
}
for (uint32_t i = 0; i < nof_rf_channels; i++) {
sf_buffer[i] = (cf_t*)srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_MAX * 5);
sf_buffer[i] = srslte_vec_cf_malloc(SF_BUFFER_MAX_SAMPLES);
if (!sf_buffer[i]) {
fprintf(stderr, "Error allocating buffer\n");
return;
@ -456,7 +456,8 @@ void async_scell_recv::run_thread()
pthread_mutex_lock(&mutex_uesync);
// Get RF base-band
int ret = srslte_ue_sync_zerocopy(&ue_sync, (state == DECODE_MIB) ? sf_buffer : buffer->get_buffer_ptr());
int ret = srslte_ue_sync_zerocopy(
&ue_sync, (state == DECODE_MIB) ? sf_buffer : buffer->get_buffer_ptr(), SF_BUFFER_MAX_SAMPLES);
if (ret < 0) {
fprintf(stderr, "Error calling srslte_ue_sync_work()\n");
}

@ -115,6 +115,14 @@ cf_t* sf_worker::get_buffer(uint32_t carrier_idx, uint32_t antenna_idx)
return cc_workers[carrier_idx]->get_rx_buffer(antenna_idx);
}
uint32_t sf_worker::get_buffer_len()
{
if (cc_workers.empty()) {
return 0;
}
return cc_workers.at(0)->get_buffer_len();
}
void sf_worker::set_tti(uint32_t tti_)
{
tti = tti_;

@ -75,7 +75,7 @@ void sync::init(srslte::radio_interface_phy* _radio,
uint32_t nof_rf_channels = worker_com->args->nof_rf_channels * worker_com->args->nof_rx_ant;
for (uint32_t r = 0; r < worker_com->args->nof_radios; r++) {
for (uint32_t p = 0; p < nof_rf_channels; p++) {
sf_buffer[r][p] = (cf_t*)srslte_vec_malloc(sizeof(cf_t) * 3 * SRSLTE_SF_LEN_PRB(100));
sf_buffer[r][p] = srslte_vec_cf_malloc(SF_BUFFER_MAX_SAMPLES);
}
}
@ -95,7 +95,7 @@ void sync::init(srslte::radio_interface_phy* _radio,
search_p.init(sf_buffer[0], log_h, nof_rf_channels, this);
// Initialize SFN synchronizer, it uses only pcell buffer
sfn_p.init(&ue_sync, sf_buffer[0], log_h);
sfn_p.init(&ue_sync, sf_buffer[0], SF_BUFFER_MAX_SAMPLES, log_h);
// Start intra-frequency measurement
for (uint32_t i = 0; i < worker_com->args->nof_carriers; i++) {
@ -447,7 +447,7 @@ void sync::run_thread()
}
// Primary Cell (PCell) Synchronization
switch (srslte_ue_sync_zerocopy(&ue_sync, buffer[0])) {
switch (srslte_ue_sync_zerocopy(&ue_sync, buffer[0], worker->get_buffer_len())) {
case 1:
// Check tti is synched with ue_sync
@ -1148,6 +1148,7 @@ sync::sfn_sync::~sfn_sync()
void sync::sfn_sync::init(srslte_ue_sync_t* ue_sync_,
cf_t* buffer_[SRSLTE_MAX_PORTS],
uint32_t buffer_max_samples_,
srslte::log* log_h_,
uint32_t nof_subframes)
{
@ -1158,6 +1159,7 @@ void sync::sfn_sync::init(srslte_ue_sync_t* ue_sync_,
for (int p = 0; p < SRSLTE_MAX_PORTS; p++) {
buffer[p] = buffer_[p];
}
buffer_max_samples = buffer_max_samples_;
if (srslte_ue_mib_init(&ue_mib, buffer, SRSLTE_MAX_PRB)) {
Error("SYNC: Initiating UE MIB decoder\n");
@ -1185,8 +1187,7 @@ sync::sfn_sync::ret_code sync::sfn_sync::run_subframe(srslte_cell_t*
std::array<uint8_t, SRSLTE_BCH_PAYLOAD_LEN>& bch_payload,
bool sfidx_only)
{
int ret = srslte_ue_sync_zerocopy(ue_sync, buffer);
int ret = srslte_ue_sync_zerocopy(ue_sync, buffer, buffer_max_samples);
if (ret < 0) {
Error("SYNC: Error calling ue_sync_get_buffer.\n");
return ERROR;

Loading…
Cancel
Save