gtlv: check memory bounds 3/3: encoding to str
See Id8d997c9d5e655ff1842ec69eab6c073875c6330 Related: CID#275417 Related: SYS#5599 Change-Id: I63d52a4f5dba32d3a3887dd9c5e42e1695fb2aa3
This commit is contained in:
parent
92860a29cd
commit
035b692673
|
@ -191,10 +191,12 @@ int osmo_gtlvs_encode(struct osmo_gtlv_put *gtlv, const void *decoded_struct, si
|
||||||
unsigned int obj_ofs, const struct osmo_gtlv_coding *ie_coding, osmo_gtlv_err_cb err_cb,
|
unsigned int obj_ofs, const struct osmo_gtlv_coding *ie_coding, osmo_gtlv_err_cb err_cb,
|
||||||
void *err_cb_data, const struct value_string *iei_strs);
|
void *err_cb_data, const struct value_string *iei_strs);
|
||||||
|
|
||||||
int osmo_gtlvs_encode_to_str_buf(char *buf, size_t buflen, const void *decoded_struct, unsigned int obj_ofs,
|
int osmo_gtlvs_encode_to_str_buf(char *buf, size_t buflen,
|
||||||
const struct osmo_gtlv_coding *ie_coding, const struct value_string *iei_strs);
|
const void *decoded_struct, size_t decoded_struct_size, unsigned int obj_ofs,
|
||||||
char *osmo_gtlvs_encode_to_str_c(void *ctx, const void *decoded_struct, unsigned int obj_ofs,
|
const struct osmo_gtlv_coding *ie_coding, const struct value_string *iei_strs);
|
||||||
const struct osmo_gtlv_coding *ie_coding, const struct value_string *iei_strs);
|
char *osmo_gtlvs_encode_to_str_c(void *ctx,
|
||||||
|
const void *decoded_struct, size_t decoded_struct_size, unsigned int obj_ofs,
|
||||||
|
const struct osmo_gtlv_coding *ie_coding, const struct value_string *iei_strs);
|
||||||
|
|
||||||
static inline bool osmo_gtlv_coding_end(const struct osmo_gtlv_coding *iec)
|
static inline bool osmo_gtlv_coding_end(const struct osmo_gtlv_coding *iec)
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,9 +28,6 @@
|
||||||
|
|
||||||
#include <osmocom/gtlv/gtlv_dec_enc.h>
|
#include <osmocom/gtlv/gtlv_dec_enc.h>
|
||||||
|
|
||||||
/* Reverse offsetof(): return the address of the struct member for a given osmo_gtlv_msg and member ofs_foo value. */
|
|
||||||
#define MEMB(M, MEMB_OFS) ((void *)((char *)(M) + (MEMB_OFS)))
|
|
||||||
|
|
||||||
#define RETURN_ERROR(RC, TAG_INST, FMT, ARGS...) \
|
#define RETURN_ERROR(RC, TAG_INST, FMT, ARGS...) \
|
||||||
do {\
|
do {\
|
||||||
if (err_cb) { \
|
if (err_cb) { \
|
||||||
|
@ -486,19 +483,23 @@ int osmo_gtlvs_encode(struct osmo_gtlv_put *gtlv, const void *decoded_struct, si
|
||||||
* \param[in] iei_strs value_string array to give IEI names in tag headers, or NULL.
|
* \param[in] iei_strs value_string array to give IEI names in tag headers, or NULL.
|
||||||
* \return number of characters that would be written if the buffer is large enough, like snprintf().
|
* \return number of characters that would be written if the buffer is large enough, like snprintf().
|
||||||
*/
|
*/
|
||||||
int osmo_gtlvs_encode_to_str_buf(char *buf, size_t buflen, const void *decoded_struct, unsigned int obj_ofs,
|
int osmo_gtlvs_encode_to_str_buf(char *buf, size_t buflen,
|
||||||
const struct osmo_gtlv_coding *ie_coding, const struct value_string *iei_strs)
|
const void *decoded_struct, size_t decoded_struct_size, unsigned int obj_ofs,
|
||||||
|
const struct osmo_gtlv_coding *ie_coding, const struct value_string *iei_strs)
|
||||||
{
|
{
|
||||||
struct osmo_strbuf sb = { .buf = buf, .len = buflen };
|
struct osmo_strbuf sb = { .buf = buf, .len = buflen };
|
||||||
|
|
||||||
void *obj = MEMB(decoded_struct, obj_ofs);
|
const void *obj = membof_const(decoded_struct, decoded_struct_size, obj_ofs);
|
||||||
|
size_t obj_maxlen = decoded_struct_size - obj_ofs;
|
||||||
|
|
||||||
if (!ie_coding)
|
if (!ie_coding)
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
|
|
||||||
for (; !osmo_gtlv_coding_end(ie_coding); ie_coding++) {
|
for (; !osmo_gtlv_coding_end(ie_coding); ie_coding++) {
|
||||||
bool *presence_flag_p = ie_coding->has_presence_flag ? MEMB(obj, ie_coding->presence_flag_ofs) : NULL;
|
const bool *presence_flag_p = ie_coding->has_presence_flag ?
|
||||||
unsigned int *multi_count_p = ie_coding->has_count ? MEMB(obj, ie_coding->count_ofs) : NULL;
|
membof_const(obj, obj_maxlen, ie_coding->presence_flag_ofs) : NULL;
|
||||||
|
const unsigned int *multi_count_p = ie_coding->has_count ?
|
||||||
|
membof_const(obj, obj_maxlen, ie_coding->count_ofs) : NULL;
|
||||||
unsigned int n;
|
unsigned int n;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
@ -531,12 +532,14 @@ int osmo_gtlvs_encode_to_str_buf(char *buf, size_t buflen, const void *decoded_s
|
||||||
|
|
||||||
if (ie_coding->nested_ies) {
|
if (ie_coding->nested_ies) {
|
||||||
OSMO_STRBUF_PRINTF(sb, "{");
|
OSMO_STRBUF_PRINTF(sb, "{");
|
||||||
OSMO_STRBUF_APPEND(sb, osmo_gtlvs_encode_to_str_buf, decoded_struct, obj_ofs + memb_ofs,
|
OSMO_STRBUF_APPEND(sb, osmo_gtlvs_encode_to_str_buf,
|
||||||
|
decoded_struct, decoded_struct_size, obj_ofs + memb_ofs,
|
||||||
ie_coding->nested_ies, iei_strs);
|
ie_coding->nested_ies, iei_strs);
|
||||||
OSMO_STRBUF_PRINTF(sb, " }");
|
OSMO_STRBUF_PRINTF(sb, " }");
|
||||||
} else {
|
} else {
|
||||||
if (ie_coding->enc_to_str_func)
|
if (ie_coding->enc_to_str_func)
|
||||||
OSMO_STRBUF_APPEND(sb, ie_coding->enc_to_str_func, MEMB(obj, memb_ofs));
|
OSMO_STRBUF_APPEND(sb, ie_coding->enc_to_str_func,
|
||||||
|
membof_const(obj, obj_maxlen, memb_ofs));
|
||||||
else
|
else
|
||||||
OSMO_STRBUF_PRINTF(sb, "(enc_to_str_func==NULL)");
|
OSMO_STRBUF_PRINTF(sb, "(enc_to_str_func==NULL)");
|
||||||
}
|
}
|
||||||
|
@ -557,8 +560,10 @@ int osmo_gtlvs_encode_to_str_buf(char *buf, size_t buflen, const void *decoded_s
|
||||||
* \param[in] iei_strs value_string array to give IEI names in tag headers, or NULL.
|
* \param[in] iei_strs value_string array to give IEI names in tag headers, or NULL.
|
||||||
* \return human readable string.
|
* \return human readable string.
|
||||||
*/
|
*/
|
||||||
char *osmo_gtlvs_encode_to_str_c(void *ctx, const void *decoded_struct, unsigned int obj_ofs,
|
char *osmo_gtlvs_encode_to_str_c(void *ctx,
|
||||||
const struct osmo_gtlv_coding *ie_coding, const struct value_string *iei_strs)
|
const void *decoded_struct, size_t decoded_struct_size, unsigned int obj_ofs,
|
||||||
|
const struct osmo_gtlv_coding *ie_coding, const struct value_string *iei_strs)
|
||||||
{
|
{
|
||||||
OSMO_NAME_C_IMPL(ctx, 256, "ERROR", osmo_gtlvs_encode_to_str_buf, decoded_struct, obj_ofs, ie_coding, iei_strs)
|
OSMO_NAME_C_IMPL(ctx, 256, "ERROR", osmo_gtlvs_encode_to_str_buf, decoded_struct, decoded_struct_size,
|
||||||
|
obj_ofs, ie_coding, iei_strs)
|
||||||
}
|
}
|
||||||
|
|
|
@ -397,7 +397,7 @@ static void write_c()
|
||||||
"int %s_ies_encode_to_str(char *buf, size_t buflen, const union %s_ies *src,\n"
|
"int %s_ies_encode_to_str(char *buf, size_t buflen, const union %s_ies *src,\n"
|
||||||
" %s message_type, const struct value_string *iei_strs)\n"
|
" %s message_type, const struct value_string *iei_strs)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return osmo_gtlvs_encode_to_str_buf(buf, buflen, src, 0, %s_get_msg_coding(message_type), iei_strs);\n"
|
" return osmo_gtlvs_encode_to_str_buf(buf, buflen, src, sizeof(*src), 0, %s_get_msg_coding(message_type), iei_strs);\n"
|
||||||
"}\n",
|
"}\n",
|
||||||
g_cfg->proto_name, g_cfg->proto_name, g_cfg->message_type_enum ? : "int", g_cfg->proto_name);
|
g_cfg->proto_name, g_cfg->proto_name, g_cfg->message_type_enum ? : "int", g_cfg->proto_name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -286,7 +286,7 @@ struct osmo_gtlv_coding msg_ie_coding[] = {
|
||||||
|
|
||||||
char *decoded_msg_to_str(const struct decoded_msg *m)
|
char *decoded_msg_to_str(const struct decoded_msg *m)
|
||||||
{
|
{
|
||||||
return osmo_gtlvs_encode_to_str_c(ctx, m, 0, msg_ie_coding, tag_names);
|
return osmo_gtlvs_encode_to_str_c(ctx, m, sizeof(*m), 0, msg_ie_coding, tag_names);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -203,8 +203,8 @@ int myproto_msg_to_str_buf(char *buf, size_t buflen, const struct myproto_msg *m
|
||||||
{
|
{
|
||||||
struct osmo_strbuf sb = { .buf = buf, .len = buflen };
|
struct osmo_strbuf sb = { .buf = buf, .len = buflen };
|
||||||
OSMO_STRBUF_PRINTF(sb, "%s={", get_value_string(myproto_msg_type_names, m->type));
|
OSMO_STRBUF_PRINTF(sb, "%s={", get_value_string(myproto_msg_type_names, m->type));
|
||||||
OSMO_STRBUF_APPEND(sb, osmo_gtlvs_encode_to_str_buf, &m->ies, 0, myproto_get_msg_coding(m->type),
|
OSMO_STRBUF_APPEND(sb, osmo_gtlvs_encode_to_str_buf, &m->ies, sizeof(m->ies), 0,
|
||||||
myproto_iei_names);
|
myproto_get_msg_coding(m->type), myproto_iei_names);
|
||||||
OSMO_STRBUF_PRINTF(sb, " }");
|
OSMO_STRBUF_PRINTF(sb, " }");
|
||||||
return sb.chars_needed;
|
return sb.chars_needed;
|
||||||
|
|
||||||
|
|
|
@ -101,8 +101,8 @@ int myproto_msg_to_str_buf(char *buf, size_t buflen, const struct myproto_msg *m
|
||||||
{
|
{
|
||||||
struct osmo_strbuf sb = { .buf = buf, .len = buflen };
|
struct osmo_strbuf sb = { .buf = buf, .len = buflen };
|
||||||
OSMO_STRBUF_PRINTF(sb, "%s={", get_value_string(myproto_msg_type_names, m->type));
|
OSMO_STRBUF_PRINTF(sb, "%s={", get_value_string(myproto_msg_type_names, m->type));
|
||||||
OSMO_STRBUF_APPEND(sb, osmo_gtlvs_encode_to_str_buf, &m->ies, 0, myproto_get_msg_coding(m->type),
|
OSMO_STRBUF_APPEND(sb, osmo_gtlvs_encode_to_str_buf, &m->ies, sizeof(m->ies), 0,
|
||||||
myproto_iei_names);
|
myproto_get_msg_coding(m->type), myproto_iei_names);
|
||||||
OSMO_STRBUF_PRINTF(sb, " }");
|
OSMO_STRBUF_PRINTF(sb, " }");
|
||||||
return sb.chars_needed;
|
return sb.chars_needed;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue