mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
pod: enforce max pod size
Set a max pod size and add some more over and underflow checks
This commit is contained in:
parent
2011474936
commit
8554c9d02a
3 changed files with 36 additions and 19 deletions
|
|
@ -65,6 +65,11 @@ spa_pod_builder_get_state(struct spa_pod_builder *builder, struct spa_pod_builde
|
|||
*state = builder->state;
|
||||
}
|
||||
|
||||
SPA_API_POD_BUILDER bool spa_pod_builder_corrupted(const struct spa_pod_builder *builder)
|
||||
{
|
||||
return builder->state.offset > builder->size;
|
||||
}
|
||||
|
||||
SPA_API_POD_BUILDER void
|
||||
spa_pod_builder_set_callbacks(struct spa_pod_builder *builder,
|
||||
const struct spa_pod_builder_callbacks *callbacks, void *data)
|
||||
|
|
@ -79,7 +84,7 @@ spa_pod_builder_reset(struct spa_pod_builder *builder, struct spa_pod_builder_st
|
|||
uint32_t size = builder->state.offset - state->offset;
|
||||
builder->state = *state;
|
||||
for (f = builder->state.frame; f ; f = f->parent)
|
||||
f->pod.size -= size;
|
||||
f->pod.size -= SPA_MIN(size, f->pod.size);
|
||||
}
|
||||
|
||||
SPA_API_POD_BUILDER void spa_pod_builder_init(struct spa_pod_builder *builder, void *data, uint32_t size)
|
||||
|
|
@ -91,9 +96,10 @@ SPA_API_POD_BUILDER struct spa_pod *
|
|||
spa_pod_builder_deref(struct spa_pod_builder *builder, uint32_t offset)
|
||||
{
|
||||
uint32_t size = builder->size;
|
||||
if (offset + 8 <= size) {
|
||||
if (offset + UINT64_C(8) <= size) {
|
||||
struct spa_pod *pod = SPA_PTROFF(builder->data, offset, struct spa_pod);
|
||||
if (offset + SPA_POD_SIZE(pod) <= size)
|
||||
if (offset + (uint64_t)SPA_POD_SIZE(pod) <= size &&
|
||||
SPA_POD_IS_VALID(pod))
|
||||
return pod;
|
||||
}
|
||||
return NULL;
|
||||
|
|
@ -159,9 +165,9 @@ SPA_API_POD_BUILDER int spa_pod_builder_raw(struct spa_pod_builder *builder, con
|
|||
SPA_API_POD_BUILDER void spa_pod_builder_remove(struct spa_pod_builder *builder, uint32_t size)
|
||||
{
|
||||
struct spa_pod_frame *f;
|
||||
builder->state.offset -= size;
|
||||
builder->state.offset -= SPA_MIN(size, builder->state.offset);
|
||||
for (f = builder->state.frame; f ; f = f->parent)
|
||||
f->pod.size -= size;
|
||||
f->pod.size -= SPA_MIN(size, f->pod.size);
|
||||
}
|
||||
|
||||
SPA_API_POD_BUILDER int spa_pod_builder_pad(struct spa_pod_builder *builder, uint32_t size)
|
||||
|
|
|
|||
|
|
@ -34,12 +34,25 @@ struct spa_pod_frame {
|
|||
uint32_t flags;
|
||||
};
|
||||
|
||||
#define SPA_POD_IS_VALID(pod) \
|
||||
(SPA_POD_BODY_SIZE(pod) < SPA_POD_MAX_SIZE && \
|
||||
SPA_IS_ALIGNED(pod, SPA_POD_ALIGN))
|
||||
|
||||
#define SPA_POD_CHECK_TYPE(pod,_type) \
|
||||
(SPA_POD_IS_VALID(pod) && \
|
||||
(pod)->type == (_type))
|
||||
|
||||
#define SPA_POD_CHECK(pod,_type,_size) \
|
||||
(SPA_POD_CHECK_TYPE(pod,_type) && (pod)->size >= (_size))
|
||||
|
||||
|
||||
SPA_API_POD_ITER bool spa_pod_is_inside(const void *pod, uint32_t size, const void *iter)
|
||||
{
|
||||
size_t remaining;
|
||||
|
||||
return spa_ptr_type_inside(pod, size, iter, struct spa_pod, &remaining) &&
|
||||
remaining >= SPA_POD_BODY_SIZE(iter);
|
||||
SPA_POD_IS_VALID((struct spa_pod*)iter) &&
|
||||
remaining >= SPA_POD_BODY_SIZE(iter);
|
||||
}
|
||||
|
||||
SPA_API_POD_ITER void *spa_pod_next(const void *iter)
|
||||
|
|
@ -58,7 +71,7 @@ SPA_API_POD_ITER bool spa_pod_prop_is_inside(const struct spa_pod_object_body *b
|
|||
size_t remaining;
|
||||
|
||||
return spa_ptr_type_inside(body, size, iter, struct spa_pod_prop, &remaining) &&
|
||||
remaining >= iter->value.size;
|
||||
SPA_POD_IS_VALID(&iter->value) && remaining >= iter->value.size;
|
||||
}
|
||||
|
||||
SPA_API_POD_ITER struct spa_pod_prop *spa_pod_prop_next(const struct spa_pod_prop *iter)
|
||||
|
|
@ -77,7 +90,7 @@ SPA_API_POD_ITER bool spa_pod_control_is_inside(const struct spa_pod_sequence_bo
|
|||
size_t remaining;
|
||||
|
||||
return spa_ptr_type_inside(body, size, iter, struct spa_pod_control, &remaining) &&
|
||||
remaining >= iter->value.size;
|
||||
SPA_POD_IS_VALID(&iter->value) && remaining >= iter->value.size;
|
||||
}
|
||||
|
||||
SPA_API_POD_ITER struct spa_pod_control *spa_pod_control_next(const struct spa_pod_control *iter)
|
||||
|
|
@ -136,20 +149,15 @@ SPA_API_POD_ITER void *spa_pod_from_data(void *data, size_t maxsize, off_t offse
|
|||
maxsize - size < (uint32_t)offset)
|
||||
return NULL;
|
||||
pod = SPA_PTROFF(data, offset, void);
|
||||
if (!SPA_IS_ALIGNED(pod, SPA_POD_ALIGN))
|
||||
if (!SPA_POD_IS_VALID(pod))
|
||||
return NULL;
|
||||
if (SPA_POD_BODY_SIZE(pod) > size - sizeof(struct spa_pod))
|
||||
return NULL;
|
||||
return pod;
|
||||
}
|
||||
|
||||
#define SPA_POD_CHECK_0(pod,_type) ((pod)->type == (_type) && SPA_IS_ALIGNED(pod, SPA_POD_ALIGN))
|
||||
#define SPA_POD_CHECK(pod,_type,_size) \
|
||||
(SPA_POD_CHECK_0(pod,_type) && (pod)->size >= (_size))
|
||||
|
||||
SPA_API_POD_ITER int spa_pod_is_none(const struct spa_pod *pod)
|
||||
{
|
||||
return SPA_POD_CHECK_0(pod, SPA_TYPE_None);
|
||||
return SPA_POD_CHECK_TYPE(pod, SPA_TYPE_None);
|
||||
}
|
||||
|
||||
SPA_API_POD_ITER int spa_pod_is_bool(const struct spa_pod *pod)
|
||||
|
|
@ -257,7 +265,7 @@ SPA_API_POD_ITER int spa_pod_copy_string(const struct spa_pod *pod, size_t maxle
|
|||
|
||||
SPA_API_POD_ITER int spa_pod_is_bytes(const struct spa_pod *pod)
|
||||
{
|
||||
return SPA_POD_CHECK_0(pod, SPA_TYPE_Bytes);
|
||||
return SPA_POD_CHECK_TYPE(pod, SPA_TYPE_Bytes);
|
||||
}
|
||||
|
||||
SPA_API_POD_ITER int spa_pod_get_bytes(const struct spa_pod *pod, const void **value, uint32_t *len)
|
||||
|
|
@ -328,7 +336,8 @@ SPA_API_POD_ITER int spa_pod_is_bitmap(const struct spa_pod *pod)
|
|||
|
||||
SPA_API_POD_ITER int spa_pod_is_array(const struct spa_pod *pod)
|
||||
{
|
||||
return SPA_POD_CHECK(pod, SPA_TYPE_Array, sizeof(struct spa_pod_array_body));
|
||||
return SPA_POD_CHECK(pod, SPA_TYPE_Array, sizeof(struct spa_pod_array_body)) &&
|
||||
SPA_POD_IS_VALID(SPA_POD_ARRAY_CHILD(pod));
|
||||
}
|
||||
|
||||
SPA_API_POD_ITER void *spa_pod_get_array(const struct spa_pod *pod, uint32_t *n_values)
|
||||
|
|
@ -352,7 +361,8 @@ SPA_API_POD_ITER uint32_t spa_pod_copy_array(const struct spa_pod *pod, uint32_t
|
|||
|
||||
SPA_API_POD_ITER int spa_pod_is_choice(const struct spa_pod *pod)
|
||||
{
|
||||
return SPA_POD_CHECK(pod, SPA_TYPE_Choice, sizeof(struct spa_pod_choice_body));
|
||||
return SPA_POD_CHECK(pod, SPA_TYPE_Choice, sizeof(struct spa_pod_choice_body)) &&
|
||||
SPA_POD_IS_VALID(SPA_POD_CHOICE_CHILD(pod));
|
||||
}
|
||||
|
||||
SPA_API_POD_ITER struct spa_pod *spa_pod_get_values(const struct spa_pod *pod, uint32_t *n_vals, uint32_t *choice)
|
||||
|
|
@ -372,7 +382,7 @@ SPA_API_POD_ITER struct spa_pod *spa_pod_get_values(const struct spa_pod *pod, u
|
|||
|
||||
SPA_API_POD_ITER int spa_pod_is_struct(const struct spa_pod *pod)
|
||||
{
|
||||
return SPA_POD_CHECK_0(pod, SPA_TYPE_Struct);
|
||||
return SPA_POD_CHECK_TYPE(pod, SPA_TYPE_Struct);
|
||||
}
|
||||
|
||||
SPA_API_POD_ITER int spa_pod_is_object(const struct spa_pod *pod)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ extern "C" {
|
|||
*/
|
||||
|
||||
#define SPA_POD_ALIGN 8
|
||||
#define SPA_POD_MAX_SIZE (1u<<20)
|
||||
|
||||
#define SPA_POD_BODY_SIZE(pod) (((struct spa_pod*)(pod))->size)
|
||||
#define SPA_POD_TYPE(pod) (((struct spa_pod*)(pod))->type)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue