mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	try to detect when stupid clients forks and refuse all service from then on
This commit is contained in:
		
							parent
							
								
									9d29b96ac0
								
							
						
					
					
						commit
						3122008704
					
				
					 9 changed files with 227 additions and 3 deletions
				
			
		| 
						 | 
				
			
			@ -74,6 +74,7 @@
 | 
			
		|||
#include "internal.h"
 | 
			
		||||
 | 
			
		||||
#include "client-conf.h"
 | 
			
		||||
#include "fork-detect.h"
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_X11
 | 
			
		||||
#include "client-conf-x11.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -127,6 +128,9 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *
 | 
			
		|||
 | 
			
		||||
    pa_assert(mainloop);
 | 
			
		||||
 | 
			
		||||
    if (pa_detect_fork())
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    pa_init_i18n();
 | 
			
		||||
 | 
			
		||||
    c = pa_xnew(pa_context, 1);
 | 
			
		||||
| 
						 | 
				
			
			@ -822,6 +826,7 @@ int pa_context_connect(
 | 
			
		|||
    pa_assert(c);
 | 
			
		||||
    pa_assert(PA_REFCNT_VALUE(c) >= 1);
 | 
			
		||||
 | 
			
		||||
    PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED);
 | 
			
		||||
    PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_UNCONNECTED, PA_ERR_BADSTATE);
 | 
			
		||||
    PA_CHECK_VALIDITY(c, !(flags & ~PA_CONTEXT_NOAUTOSPAWN), PA_ERR_INVALID);
 | 
			
		||||
    PA_CHECK_VALIDITY(c, !server || *server, PA_ERR_INVALID);
 | 
			
		||||
| 
						 | 
				
			
			@ -894,6 +899,9 @@ void pa_context_disconnect(pa_context *c) {
 | 
			
		|||
    pa_assert(c);
 | 
			
		||||
    pa_assert(PA_REFCNT_VALUE(c) >= 1);
 | 
			
		||||
 | 
			
		||||
    if (pa_detect_fork())
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (PA_CONTEXT_IS_GOOD(c->state))
 | 
			
		||||
        pa_context_set_state(c, PA_CONTEXT_TERMINATED);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -916,6 +924,9 @@ void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, voi
 | 
			
		|||
    pa_assert(c);
 | 
			
		||||
    pa_assert(PA_REFCNT_VALUE(c) >= 1);
 | 
			
		||||
 | 
			
		||||
    if (pa_detect_fork())
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (c->state == PA_CONTEXT_TERMINATED || c->state == PA_CONTEXT_FAILED)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -927,6 +938,9 @@ void pa_context_set_event_callback(pa_context *c, pa_context_event_cb_t cb, void
 | 
			
		|||
    pa_assert(c);
 | 
			
		||||
    pa_assert(PA_REFCNT_VALUE(c) >= 1);
 | 
			
		||||
 | 
			
		||||
    if (pa_detect_fork())
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (c->state == PA_CONTEXT_TERMINATED || c->state == PA_CONTEXT_FAILED)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -938,6 +952,7 @@ int pa_context_is_pending(pa_context *c) {
 | 
			
		|||
    pa_assert(c);
 | 
			
		||||
    pa_assert(PA_REFCNT_VALUE(c) >= 1);
 | 
			
		||||
 | 
			
		||||
    PA_CHECK_VALIDITY(c, !pa_detect_fork(), PA_ERR_FORKED);
 | 
			
		||||
    PA_CHECK_VALIDITY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE);
 | 
			
		||||
 | 
			
		||||
    return (c->pstream && pa_pstream_is_pending(c->pstream)) ||
 | 
			
		||||
| 
						 | 
				
			
			@ -994,6 +1009,7 @@ pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *u
 | 
			
		|||
    pa_assert(c);
 | 
			
		||||
    pa_assert(PA_REFCNT_VALUE(c) >= 1);
 | 
			
		||||
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, pa_context_is_pending(c), PA_ERR_BADSTATE);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1042,6 +1058,7 @@ pa_operation* pa_context_send_simple_command(pa_context *c, uint32_t command, pa
 | 
			
		|||
    pa_assert(c);
 | 
			
		||||
    pa_assert(PA_REFCNT_VALUE(c) >= 1);
 | 
			
		||||
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
 | 
			
		||||
 | 
			
		||||
    o = pa_operation_new(c, NULL, cb, userdata);
 | 
			
		||||
| 
						 | 
				
			
			@ -1068,6 +1085,7 @@ pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_co
 | 
			
		|||
    pa_assert(c);
 | 
			
		||||
    pa_assert(PA_REFCNT_VALUE(c) >= 1);
 | 
			
		||||
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
 | 
			
		||||
 | 
			
		||||
    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
 | 
			
		||||
| 
						 | 
				
			
			@ -1087,6 +1105,7 @@ pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_
 | 
			
		|||
    pa_assert(c);
 | 
			
		||||
    pa_assert(PA_REFCNT_VALUE(c) >= 1);
 | 
			
		||||
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
 | 
			
		||||
 | 
			
		||||
    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
 | 
			
		||||
| 
						 | 
				
			
			@ -1102,6 +1121,7 @@ int pa_context_is_local(pa_context *c) {
 | 
			
		|||
    pa_assert(c);
 | 
			
		||||
    pa_assert(PA_REFCNT_VALUE(c) >= 1);
 | 
			
		||||
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, -1);
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_ANY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE, -1);
 | 
			
		||||
 | 
			
		||||
    return !!c->is_local;
 | 
			
		||||
| 
						 | 
				
			
			@ -1114,6 +1134,7 @@ pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_su
 | 
			
		|||
    pa_assert(PA_REFCNT_VALUE(c) >= 1);
 | 
			
		||||
    pa_assert(name);
 | 
			
		||||
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
 | 
			
		||||
 | 
			
		||||
    if (c->version >= 13) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1144,8 +1165,8 @@ const char* pa_context_get_server(pa_context *c) {
 | 
			
		|||
    pa_assert(c);
 | 
			
		||||
    pa_assert(PA_REFCNT_VALUE(c) >= 1);
 | 
			
		||||
 | 
			
		||||
    if (!c->server)
 | 
			
		||||
        return NULL;
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, c->server, PA_ERR_NOENTITY);
 | 
			
		||||
 | 
			
		||||
    if (*c->server == '{') {
 | 
			
		||||
        char *e = strchr(c->server+1, '}');
 | 
			
		||||
| 
						 | 
				
			
			@ -1163,6 +1184,7 @@ uint32_t pa_context_get_server_protocol_version(pa_context *c) {
 | 
			
		|||
    pa_assert(c);
 | 
			
		||||
    pa_assert(PA_REFCNT_VALUE(c) >= 1);
 | 
			
		||||
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, PA_INVALID_INDEX);
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_ANY(c, PA_CONTEXT_IS_GOOD(c->state), PA_ERR_BADSTATE, PA_INVALID_INDEX);
 | 
			
		||||
 | 
			
		||||
    return c->version;
 | 
			
		||||
| 
						 | 
				
			
			@ -1185,6 +1207,7 @@ uint32_t pa_context_get_index(pa_context *c) {
 | 
			
		|||
    pa_assert(c);
 | 
			
		||||
    pa_assert(PA_REFCNT_VALUE(c) >= 1);
 | 
			
		||||
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_ANY(c, !pa_detect_fork(), PA_ERR_FORKED, PA_INVALID_INDEX);
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_ANY(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE, PA_INVALID_INDEX);
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_ANY(c, c->version >= 13, PA_ERR_NOTSUPPORTED, PA_INVALID_INDEX);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1199,6 +1222,7 @@ pa_operation *pa_context_proplist_update(pa_context *c, pa_update_mode_t mode, p
 | 
			
		|||
    pa_assert(c);
 | 
			
		||||
    pa_assert(PA_REFCNT_VALUE(c) >= 1);
 | 
			
		||||
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, mode == PA_UPDATE_SET || mode == PA_UPDATE_MERGE || mode == PA_UPDATE_REPLACE, PA_ERR_INVALID);
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 13, PA_ERR_NOTSUPPORTED);
 | 
			
		||||
| 
						 | 
				
			
			@ -1227,6 +1251,7 @@ pa_operation *pa_context_proplist_remove(pa_context *c, const char *const keys[]
 | 
			
		|||
    pa_assert(c);
 | 
			
		||||
    pa_assert(PA_REFCNT_VALUE(c) >= 1);
 | 
			
		||||
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, keys && keys[0], PA_ERR_INVALID);
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
 | 
			
		||||
    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 13, PA_ERR_NOTSUPPORTED);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue