mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	builder: make deref safer
Don't try to deref objects that did not fit into the memory. Deref now returns the object
This commit is contained in:
		
							parent
							
								
									101d2af1be
								
							
						
					
					
						commit
						737b428077
					
				
					 8 changed files with 32 additions and 26 deletions
				
			
		| 
						 | 
				
			
			@ -67,10 +67,16 @@ static inline void spa_pod_builder_init(struct spa_pod_builder *builder, void *d
 | 
			
		|||
static inline void *
 | 
			
		||||
spa_pod_builder_deref(struct spa_pod_builder *builder, uint32_t ref)
 | 
			
		||||
{
 | 
			
		||||
	if (builder->deref)
 | 
			
		||||
	if (ref == -1)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	else if (builder->deref)
 | 
			
		||||
		return builder->deref(builder, ref);
 | 
			
		||||
	else
 | 
			
		||||
		return SPA_MEMBER(builder->data, ref, void);
 | 
			
		||||
	else if (ref + 8 <= builder->size) {
 | 
			
		||||
		struct spa_pod *pod = SPA_MEMBER(builder->data, ref, struct spa_pod);
 | 
			
		||||
		if (SPA_POD_SIZE(pod) <= builder->size)
 | 
			
		||||
			return pod;
 | 
			
		||||
	}
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint32_t
 | 
			
		||||
| 
						 | 
				
			
			@ -126,25 +132,23 @@ spa_pod_builder_raw_padded(struct spa_pod_builder *builder, const void *data, ui
 | 
			
		|||
	return ref;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint32_t spa_pod_builder_pop(struct spa_pod_builder *builder)
 | 
			
		||||
static inline void *spa_pod_builder_pop(struct spa_pod_builder *builder)
 | 
			
		||||
{
 | 
			
		||||
	struct spa_pod_frame *frame = &builder->frame[--builder->depth], *top;
 | 
			
		||||
	struct spa_pod_frame *frame, *top;
 | 
			
		||||
	struct spa_pod *pod;
 | 
			
		||||
 | 
			
		||||
	if (frame->ref != -1) {
 | 
			
		||||
		struct spa_pod *pod = spa_pod_builder_deref(builder, frame->ref);
 | 
			
		||||
	frame = &builder->frame[--builder->depth];
 | 
			
		||||
	if ((pod = spa_pod_builder_deref(builder, frame->ref)) != NULL)
 | 
			
		||||
		*pod = frame->pod;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	top = builder->depth > 0 ? &builder->frame[builder->depth-1] : NULL;
 | 
			
		||||
	builder->in_array = (top && (top->pod.type == SPA_POD_TYPE_ARRAY ||
 | 
			
		||||
				     top->pod.type == SPA_POD_TYPE_PROP));
 | 
			
		||||
	spa_pod_builder_pad(builder, builder->offset);
 | 
			
		||||
 | 
			
		||||
	return frame->ref;
 | 
			
		||||
	return pod;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define spa_pod_builder_pop_deref(b)				\
 | 
			
		||||
	spa_pod_builder_deref((b), spa_pod_builder_pop(b))
 | 
			
		||||
 | 
			
		||||
static inline uint32_t
 | 
			
		||||
spa_pod_builder_primitive(struct spa_pod_builder *builder, const struct spa_pod *p)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -189,7 +189,7 @@ spa_alsa_enum_format(struct state *state, uint32_t *index,
 | 
			
		|||
	}
 | 
			
		||||
	spa_pod_builder_pop(&b);
 | 
			
		||||
 | 
			
		||||
	fmt = spa_pod_builder_pop_deref(&b);
 | 
			
		||||
	fmt = spa_pod_builder_pop(&b);
 | 
			
		||||
 | 
			
		||||
	(*index)++;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -503,7 +503,7 @@ static int port_get_format(struct spa_node *node,
 | 
			
		|||
	} else
 | 
			
		||||
		return -EIO;
 | 
			
		||||
 | 
			
		||||
	*param = spa_pod_builder_pop_deref(builder);
 | 
			
		||||
	*param = spa_pod_builder_pop(builder);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -315,7 +315,7 @@ int main(int argc, char *argv[])
 | 
			
		|||
	spa_pod_builder_raw(&b, rate_min_max, sizeof(rate_min_max));
 | 
			
		||||
	spa_pod_builder_pop(&b);
 | 
			
		||||
 | 
			
		||||
	fmt = spa_pod_builder_pop_deref(&b);
 | 
			
		||||
	fmt = spa_pod_builder_pop(&b);
 | 
			
		||||
 | 
			
		||||
	spa_debug_pod(&fmt->pod, 0);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -84,7 +84,7 @@ int main(int argc, char *argv[])
 | 
			
		|||
	spa_pod_builder_pop(&b);
 | 
			
		||||
	spa_pod_builder_pop(&b);
 | 
			
		||||
	spa_pod_builder_pop(&b);
 | 
			
		||||
	obj = spa_pod_builder_pop_deref(&b);
 | 
			
		||||
	obj = spa_pod_builder_pop(&b);
 | 
			
		||||
 | 
			
		||||
	spa_debug_pod(obj, 0);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -348,7 +348,7 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
 | 
			
		|||
									2, &SPA_RECTANGLE(0,1),
 | 
			
		||||
									   &SPA_RECTANGLE(30,1),
 | 
			
		||||
			NULL);
 | 
			
		||||
		params[0] = spa_pod_builder_pop_deref(&b);
 | 
			
		||||
		params[0] = spa_pod_builder_pop(&b);
 | 
			
		||||
 | 
			
		||||
		printf("supported formats:\n");
 | 
			
		||||
		spa_debug_pod(¶ms[0]->pod, SPA_DEBUG_FLAG_FORMAT);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -390,7 +390,7 @@ handle_video_fields (ConvertData *d)
 | 
			
		|||
      if (idx < SPA_N_ELEMENTS (video_format_map))
 | 
			
		||||
        spa_pod_builder_id (&d->b, *video_format_map[idx]);
 | 
			
		||||
    }
 | 
			
		||||
    prop = spa_pod_builder_pop_deref(&d->b);
 | 
			
		||||
    prop = spa_pod_builder_pop(&d->b);
 | 
			
		||||
    if (i > 1)
 | 
			
		||||
      prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -406,7 +406,7 @@ handle_video_fields (ConvertData *d)
 | 
			
		|||
 | 
			
		||||
      spa_pod_builder_rectangle (&d->b, v.width, v.height);
 | 
			
		||||
    }
 | 
			
		||||
    prop = spa_pod_builder_pop_deref(&d->b);
 | 
			
		||||
    prop = spa_pod_builder_pop(&d->b);
 | 
			
		||||
    if (i > 1)
 | 
			
		||||
      prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -422,7 +422,7 @@ handle_video_fields (ConvertData *d)
 | 
			
		|||
 | 
			
		||||
      spa_pod_builder_fraction (&d->b, v.num, v.denom);
 | 
			
		||||
    }
 | 
			
		||||
    prop = spa_pod_builder_pop_deref(&d->b);
 | 
			
		||||
    prop = spa_pod_builder_pop(&d->b);
 | 
			
		||||
    if (i > 1)
 | 
			
		||||
      prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -438,7 +438,7 @@ handle_video_fields (ConvertData *d)
 | 
			
		|||
 | 
			
		||||
      spa_pod_builder_fraction (&d->b, v.num, v.denom);
 | 
			
		||||
    }
 | 
			
		||||
    prop = spa_pod_builder_pop_deref(&d->b);
 | 
			
		||||
    prop = spa_pod_builder_pop(&d->b);
 | 
			
		||||
    if (i > 1)
 | 
			
		||||
      prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -466,7 +466,7 @@ handle_audio_fields (ConvertData *d)
 | 
			
		|||
      if (idx < SPA_N_ELEMENTS (audio_format_map))
 | 
			
		||||
        spa_pod_builder_id (&d->b, *audio_format_map[idx]);
 | 
			
		||||
    }
 | 
			
		||||
    prop = spa_pod_builder_pop_deref(&d->b);
 | 
			
		||||
    prop = spa_pod_builder_pop(&d->b);
 | 
			
		||||
    if (i > 1)
 | 
			
		||||
      prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -491,7 +491,7 @@ handle_audio_fields (ConvertData *d)
 | 
			
		|||
 | 
			
		||||
      spa_pod_builder_int (&d->b, layout);
 | 
			
		||||
    }
 | 
			
		||||
    prop = spa_pod_builder_pop_deref(&d->b);
 | 
			
		||||
    prop = spa_pod_builder_pop(&d->b);
 | 
			
		||||
    if (i > 1)
 | 
			
		||||
      prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -506,7 +506,7 @@ handle_audio_fields (ConvertData *d)
 | 
			
		|||
 | 
			
		||||
      spa_pod_builder_int (&d->b, v);
 | 
			
		||||
    }
 | 
			
		||||
    prop = spa_pod_builder_pop_deref(&d->b);
 | 
			
		||||
    prop = spa_pod_builder_pop(&d->b);
 | 
			
		||||
    if (i > 1)
 | 
			
		||||
      prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -521,7 +521,7 @@ handle_audio_fields (ConvertData *d)
 | 
			
		|||
 | 
			
		||||
      spa_pod_builder_int (&d->b, v);
 | 
			
		||||
    }
 | 
			
		||||
    prop = spa_pod_builder_pop_deref(&d->b);
 | 
			
		||||
    prop = spa_pod_builder_pop(&d->b);
 | 
			
		||||
    if (i > 1)
 | 
			
		||||
      prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -536,6 +536,8 @@ write_pod (struct spa_pod_builder *b, const void *data, uint32_t size)
 | 
			
		|||
  if (b->size <= b->offset) {
 | 
			
		||||
    b->size = SPA_ROUND_UP_N (b->offset + size, 512);
 | 
			
		||||
    b->data = realloc (b->data, b->size);
 | 
			
		||||
    if (b->data == NULL)
 | 
			
		||||
	    return -1;
 | 
			
		||||
  }
 | 
			
		||||
  memcpy (b->data + ref, data, size);
 | 
			
		||||
  return ref;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -247,7 +247,7 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink)
 | 
			
		|||
							       max_buffers ? max_buffers : INT32_MAX),
 | 
			
		||||
      ":", t->param_buffers.align,   "i", 16,
 | 
			
		||||
      NULL);
 | 
			
		||||
  port_params[0] = spa_pod_builder_pop_deref (&b);
 | 
			
		||||
  port_params[0] = spa_pod_builder_pop (&b);
 | 
			
		||||
 | 
			
		||||
  port_params[1] = spa_pod_builder_object (&b,
 | 
			
		||||
      t->param.idMeta, t->param_meta.Meta,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue