mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-10-29 05:40:27 -04:00 
			
		
		
		
	modules: support getting app_id in pw_check_flatpak
Support getting the Flatpak application ID from the .flatpak-info file, similarly as what xdg-desktop-portal does.
This commit is contained in:
		
							parent
							
								
									5e5339ce6c
								
							
						
					
					
						commit
						3730e54484
					
				
					 6 changed files with 89 additions and 5 deletions
				
			
		|  | @ -295,6 +295,11 @@ cdata.set('HAVE_LIBUSB', libusb_dep.found()) | |||
| cap_lib = dependency('libcap', required : false) | ||||
| cdata.set('HAVE_LIBCAP', cap_lib.found()) | ||||
| 
 | ||||
| glib2_dep = dependency('glib-2.0', required : get_option('flatpak')) | ||||
| summary({'GLib-2.0 (Flatpak support)': glib2_dep.found()}, bool_yn: true, section: 'Misc dependencies') | ||||
| flatpak_support = glib2_dep.found() | ||||
| cdata.set('HAVE_GLIB2', flatpak_support) | ||||
| 
 | ||||
| gst_option = get_option('gstreamer') | ||||
| gst_deps_def = { | ||||
|   'glib-2.0': {'version': '>=2.32.0'}, | ||||
|  |  | |||
|  | @ -253,3 +253,7 @@ option('avb', | |||
|        description: 'Enable AVB code', | ||||
|        type: 'feature', | ||||
|        value: 'auto') | ||||
| option('flatpak', | ||||
|        description: 'Enable Flatpak support', | ||||
|        type: 'feature', | ||||
|        value: 'enabled') | ||||
|  |  | |||
|  | @ -28,20 +28,64 @@ | |||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <fcntl.h> | ||||
| #include <sys/mman.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/vfs.h> | ||||
| 
 | ||||
| #include <spa/include/spa/utils/result.h> | ||||
| #include "config.h" | ||||
| 
 | ||||
| #ifdef HAVE_GLIB2 | ||||
| #include <glib.h> | ||||
| #endif | ||||
| 
 | ||||
| #include <spa/utils/result.h> | ||||
| #include <pipewire/log.h> | ||||
| 
 | ||||
| static int pw_check_flatpak_parse_metadata(const char *buf, size_t size, char **app_id, char **devices) | ||||
| { | ||||
| #ifdef HAVE_GLIB2 | ||||
| 	/*
 | ||||
| 	 * See flatpak-metadata(5) | ||||
| 	 * | ||||
| 	 * The .flatpak-info file is in GLib key_file .ini format. | ||||
| 	 */ | ||||
| 	g_autoptr(GKeyFile) metadata = NULL; | ||||
| 	char *s; | ||||
| 
 | ||||
| static int pw_check_flatpak(pid_t pid) | ||||
| 	metadata = g_key_file_new(); | ||||
| 	if (!g_key_file_load_from_data(metadata, buf, size, G_KEY_FILE_NONE, NULL)) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	if (app_id) { | ||||
| 		s = g_key_file_get_value(metadata, "Application", "name", NULL); | ||||
| 		*app_id = s ? strdup(s) : NULL; | ||||
| 		g_free(s); | ||||
| 	} | ||||
| 
 | ||||
| 	if (devices) { | ||||
| 		s = g_key_file_get_value(metadata, "Context", "devices", NULL); | ||||
| 		*devices = s ? strdup(s) : NULL; | ||||
| 		g_free(s); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| #else | ||||
| 	return -ENOTSUP; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| static int pw_check_flatpak(pid_t pid, char **app_id, char **devices) | ||||
| { | ||||
| #if defined(__linux__) | ||||
| 	char root_path[2048]; | ||||
| 	int root_fd, info_fd, res; | ||||
| 	struct stat stat_buf; | ||||
| 
 | ||||
| 	if (app_id) | ||||
| 		*app_id = NULL; | ||||
| 	if (devices) | ||||
| 		*devices = NULL; | ||||
| 
 | ||||
| 	snprintf(root_path, sizeof(root_path), "/proc/%d/root", (int)pid); | ||||
| 	root_fd = openat (AT_FDCWD, root_path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY); | ||||
| 	if (root_fd == -1) { | ||||
|  | @ -77,6 +121,28 @@ static int pw_check_flatpak(pid_t pid) | |||
| 	if (fstat (info_fd, &stat_buf) != 0 || !S_ISREG (stat_buf.st_mode)) { | ||||
| 		/* Some weird fd => failure, assume sandboxed */ | ||||
| 		pw_log_error("error fstat .flatpak-info: %m"); | ||||
| 	} else if (app_id || devices) { | ||||
| 		/* Parse the application ID if needed */ | ||||
| 		const size_t size = stat_buf.st_size; | ||||
| 
 | ||||
| 		if (size > 0) { | ||||
| 			void *buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, info_fd, 0); | ||||
| 			if (buf != MAP_FAILED) { | ||||
| 				res = pw_check_flatpak_parse_metadata(buf, size, app_id, devices); | ||||
| 				munmap(buf, size); | ||||
| 			} else { | ||||
| 				res = -errno; | ||||
| 			} | ||||
| 		} else { | ||||
| 			res = -EINVAL; | ||||
| 		} | ||||
| 
 | ||||
| 		if (res == -EINVAL) | ||||
| 			pw_log_error("PID %d .flatpak-info file is malformed", | ||||
| 					(int)pid); | ||||
| 		else if (res < 0) | ||||
| 			pw_log_error("PID %d .flatpak-info parsing failed: %s", | ||||
| 					(int)pid, spa_strerror(res)); | ||||
| 	} | ||||
| 	close(info_fd); | ||||
| 	return 1; | ||||
|  |  | |||
|  | @ -33,12 +33,17 @@ module_sources = [ | |||
|   'module-x11-bell.c', | ||||
| ] | ||||
| 
 | ||||
| pipewire_module_access_deps = [spa_dep, mathlib, dl_lib, pipewire_dep] | ||||
| if flatpak_support | ||||
|   pipewire_module_access_deps += glib2_dep | ||||
| endif | ||||
| 
 | ||||
| pipewire_module_access = shared_library('pipewire-module-access', [ 'module-access.c' ], | ||||
|   include_directories : [configinc], | ||||
|   install : true, | ||||
|   install_dir : modules_install_dir, | ||||
|   install_rpath: modules_install_dir, | ||||
|   dependencies : [spa_dep, mathlib, dl_lib, pipewire_dep], | ||||
|   dependencies : pipewire_module_access_deps | ||||
| ) | ||||
| 
 | ||||
| pipewire_module_loopback = shared_library('pipewire-module-loopback', | ||||
|  | @ -277,6 +282,10 @@ if avahi_dep.found() | |||
|   cdata.set('HAVE_AVAHI', true) | ||||
| endif | ||||
| 
 | ||||
| if flatpak_support | ||||
|   pipewire_module_protocol_pulse_deps += glib2_dep | ||||
| endif | ||||
| 
 | ||||
| pipewire_module_protocol_pulse = shared_library('pipewire-module-protocol-pulse', | ||||
|   pipewire_module_protocol_pulse_sources, | ||||
|   include_directories : [configinc], | ||||
|  |  | |||
|  | @ -252,7 +252,7 @@ context_check_access(void *data, struct pw_impl_client *client) | |||
| 	    (access = pw_properties_get(impl->properties, "access.force")) != NULL) | ||||
| 		goto wait_permissions; | ||||
| 
 | ||||
| 	res = pw_check_flatpak(pid); | ||||
| 	res = pw_check_flatpak(pid, NULL, NULL); | ||||
| 	if (res != 0) { | ||||
| 		if (res < 0) { | ||||
| 			if (res == -EACCES) { | ||||
|  |  | |||
|  | @ -424,7 +424,7 @@ on_connect(void *data, int fd, uint32_t mask) | |||
| 			pw_log_warn("setsockopt(SO_PRIORITY) failed: %m"); | ||||
| #endif | ||||
| 		pid = get_client_pid(client, client_fd); | ||||
| 		if (pid != 0 && pw_check_flatpak(pid) == 1) | ||||
| 		if (pid != 0 && pw_check_flatpak(pid, NULL, NULL) == 1) | ||||
| 			client_access = "flatpak"; | ||||
| 	} | ||||
| 	else if (server->addr.ss_family == AF_INET || server->addr.ss_family == AF_INET6) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Pauli Virtanen
						Pauli Virtanen