mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	alsa-ucm: Check UCM verb before working with device status
Some versions of the ALSA libraries run into a segmentation fault when we query a UCM device/modifier status without first setting a UCM verb. It's not a reasonable thing to do anyway, so check for this case and return an error. Also do the check in other helpers. Link: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/801 Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
This commit is contained in:
		
							parent
							
								
									a7e9f79cd0
								
							
						
					
					
						commit
						5b3dea6319
					
				
					 1 changed files with 30 additions and 0 deletions
				
			
		| 
						 | 
					@ -607,6 +607,11 @@ static long ucm_device_status(pa_alsa_ucm_config *ucm, pa_alsa_ucm_device *dev)
 | 
				
			||||||
    char *devstatus;
 | 
					    char *devstatus;
 | 
				
			||||||
    long status = 0;
 | 
					    long status = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!ucm->active_verb) {
 | 
				
			||||||
 | 
					        pa_log_error("Failed to get status for UCM device %s: no UCM verb set", dev_name);
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    devstatus = pa_sprintf_malloc("_devstatus/%s", dev_name);
 | 
					    devstatus = pa_sprintf_malloc("_devstatus/%s", dev_name);
 | 
				
			||||||
    if (snd_use_case_geti(ucm->ucm_mgr, devstatus, &status) < 0) {
 | 
					    if (snd_use_case_geti(ucm->ucm_mgr, devstatus, &status) < 0) {
 | 
				
			||||||
        pa_log_debug("Failed to get status for UCM device %s", dev_name);
 | 
					        pa_log_debug("Failed to get status for UCM device %s", dev_name);
 | 
				
			||||||
| 
						 | 
					@ -620,6 +625,11 @@ static long ucm_device_status(pa_alsa_ucm_config *ucm, pa_alsa_ucm_device *dev)
 | 
				
			||||||
static int ucm_device_disable(pa_alsa_ucm_config *ucm, pa_alsa_ucm_device *dev) {
 | 
					static int ucm_device_disable(pa_alsa_ucm_config *ucm, pa_alsa_ucm_device *dev) {
 | 
				
			||||||
    const char *dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME);
 | 
					    const char *dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!ucm->active_verb) {
 | 
				
			||||||
 | 
					        pa_log_error("Failed to disable UCM device %s: no UCM verb set", dev_name);
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* If any of dev's conflicting devices is enabled, trying to disable
 | 
					    /* If any of dev's conflicting devices is enabled, trying to disable
 | 
				
			||||||
     * dev gives an error despite the fact that it's already disabled.
 | 
					     * dev gives an error despite the fact that it's already disabled.
 | 
				
			||||||
     * Check that dev is enabled to avoid this error. */
 | 
					     * Check that dev is enabled to avoid this error. */
 | 
				
			||||||
| 
						 | 
					@ -640,6 +650,11 @@ static int ucm_device_disable(pa_alsa_ucm_config *ucm, pa_alsa_ucm_device *dev)
 | 
				
			||||||
static int ucm_device_enable(pa_alsa_ucm_config *ucm, pa_alsa_ucm_device *dev) {
 | 
					static int ucm_device_enable(pa_alsa_ucm_config *ucm, pa_alsa_ucm_device *dev) {
 | 
				
			||||||
    const char *dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME);
 | 
					    const char *dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_NAME);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!ucm->active_verb) {
 | 
				
			||||||
 | 
					        pa_log_error("Failed to enable UCM device %s: no UCM verb set", dev_name);
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* We don't need to enable devices that are already enabled */
 | 
					    /* We don't need to enable devices that are already enabled */
 | 
				
			||||||
    if (ucm_device_status(ucm, dev) > 0) {
 | 
					    if (ucm_device_status(ucm, dev) > 0) {
 | 
				
			||||||
        pa_log_debug("UCM device %s is already enabled", dev_name);
 | 
					        pa_log_debug("UCM device %s is already enabled", dev_name);
 | 
				
			||||||
| 
						 | 
					@ -690,6 +705,11 @@ static long ucm_modifier_status(pa_alsa_ucm_config *ucm, pa_alsa_ucm_modifier *m
 | 
				
			||||||
    char *modstatus;
 | 
					    char *modstatus;
 | 
				
			||||||
    long status = 0;
 | 
					    long status = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!ucm->active_verb) {
 | 
				
			||||||
 | 
					        pa_log_error("Failed to get status for UCM modifier %s: no UCM verb set", mod_name);
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    modstatus = pa_sprintf_malloc("_modstatus/%s", mod_name);
 | 
					    modstatus = pa_sprintf_malloc("_modstatus/%s", mod_name);
 | 
				
			||||||
    if (snd_use_case_geti(ucm->ucm_mgr, modstatus, &status) < 0) {
 | 
					    if (snd_use_case_geti(ucm->ucm_mgr, modstatus, &status) < 0) {
 | 
				
			||||||
        pa_log_debug("Failed to get status for UCM modifier %s", mod_name);
 | 
					        pa_log_debug("Failed to get status for UCM modifier %s", mod_name);
 | 
				
			||||||
| 
						 | 
					@ -703,6 +723,11 @@ static long ucm_modifier_status(pa_alsa_ucm_config *ucm, pa_alsa_ucm_modifier *m
 | 
				
			||||||
static int ucm_modifier_disable(pa_alsa_ucm_config *ucm, pa_alsa_ucm_modifier *mod) {
 | 
					static int ucm_modifier_disable(pa_alsa_ucm_config *ucm, pa_alsa_ucm_modifier *mod) {
 | 
				
			||||||
    const char *mod_name = pa_proplist_gets(mod->proplist, PA_ALSA_PROP_UCM_NAME);
 | 
					    const char *mod_name = pa_proplist_gets(mod->proplist, PA_ALSA_PROP_UCM_NAME);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!ucm->active_verb) {
 | 
				
			||||||
 | 
					        pa_log_error("Failed to disable UCM modifier %s: no UCM verb set", mod_name);
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* We don't need to disable modifiers that are already disabled */
 | 
					    /* We don't need to disable modifiers that are already disabled */
 | 
				
			||||||
    if (ucm_modifier_status(ucm, mod) == 0) {
 | 
					    if (ucm_modifier_status(ucm, mod) == 0) {
 | 
				
			||||||
        pa_log_debug("UCM modifier %s is already disabled", mod_name);
 | 
					        pa_log_debug("UCM modifier %s is already disabled", mod_name);
 | 
				
			||||||
| 
						 | 
					@ -721,6 +746,11 @@ static int ucm_modifier_disable(pa_alsa_ucm_config *ucm, pa_alsa_ucm_modifier *m
 | 
				
			||||||
static int ucm_modifier_enable(pa_alsa_ucm_config *ucm, pa_alsa_ucm_modifier *mod) {
 | 
					static int ucm_modifier_enable(pa_alsa_ucm_config *ucm, pa_alsa_ucm_modifier *mod) {
 | 
				
			||||||
    const char *mod_name = pa_proplist_gets(mod->proplist, PA_ALSA_PROP_UCM_NAME);
 | 
					    const char *mod_name = pa_proplist_gets(mod->proplist, PA_ALSA_PROP_UCM_NAME);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!ucm->active_verb) {
 | 
				
			||||||
 | 
					        pa_log_error("Failed to enable UCM modifier %s: no UCM verb set", mod_name);
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* We don't need to enable modifiers that are already enabled */
 | 
					    /* We don't need to enable modifiers that are already enabled */
 | 
				
			||||||
    if (ucm_modifier_status(ucm, mod) > 0) {
 | 
					    if (ucm_modifier_status(ucm, mod) > 0) {
 | 
				
			||||||
        pa_log_debug("UCM modifier %s is already enabled", mod_name);
 | 
					        pa_log_debug("UCM modifier %s is already enabled", mod_name);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue