mirror of
				https://github.com/libvirt/libvirt.git
				synced 2025-02-25 18:55:26 -06:00 
			
		
		
		
	daemon: Fix core dumps if unix_sock_group is set
Setting unix_sock_group to something else than default "root" in /etc/libvirt/libvirtd.conf prevents system libvirtd from dumping core on crash. This is because we used setgid(unix_sock_group) before binding to /var/run/libvirt/libvirt-sock* and setgid() back to original group. However, if a process changes its effective or filesystem group ID, it will be forbidden from leaving core dumps unless fs.suid_dumpable sysctl is set to something else then 0 (and it is 0 by default). Changing socket's group ownership after bind works better. And we can do so without introducing a race condition since we loosen access rights by changing the group from root to something else.
This commit is contained in:
		| @@ -542,7 +542,6 @@ static int qemudListenUnix(struct qemud_server *server, | |||||||
|                            char *path, int readonly, int auth) { |                            char *path, int readonly, int auth) { | ||||||
|     struct qemud_socket *sock; |     struct qemud_socket *sock; | ||||||
|     mode_t oldmask; |     mode_t oldmask; | ||||||
|     gid_t oldgrp; |  | ||||||
|     char ebuf[1024]; |     char ebuf[1024]; | ||||||
|  |  | ||||||
|     if (VIR_ALLOC(sock) < 0) { |     if (VIR_ALLOC(sock) < 0) { | ||||||
| @@ -579,21 +578,21 @@ static int qemudListenUnix(struct qemud_server *server, | |||||||
|     if (sock->addr.data.un.sun_path[0] == '@') |     if (sock->addr.data.un.sun_path[0] == '@') | ||||||
|         sock->addr.data.un.sun_path[0] = '\0'; |         sock->addr.data.un.sun_path[0] = '\0'; | ||||||
|  |  | ||||||
|     oldgrp = getgid(); |  | ||||||
|     oldmask = umask(readonly ? ~unix_sock_ro_mask : ~unix_sock_rw_mask); |     oldmask = umask(readonly ? ~unix_sock_ro_mask : ~unix_sock_rw_mask); | ||||||
|     if (server->privileged && setgid(unix_sock_gid)) { |  | ||||||
|         VIR_ERROR(_("Failed to set group ID to %d"), unix_sock_gid); |  | ||||||
|         goto cleanup; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (bind(sock->fd, &sock->addr.data.sa, sock->addr.len) < 0) { |     if (bind(sock->fd, &sock->addr.data.sa, sock->addr.len) < 0) { | ||||||
|         VIR_ERROR(_("Failed to bind socket to '%s': %s"), |         VIR_ERROR(_("Failed to bind socket to '%s': %s"), | ||||||
|                   path, virStrerror(errno, ebuf, sizeof ebuf)); |                   path, virStrerror(errno, ebuf, sizeof ebuf)); | ||||||
|         goto cleanup; |         goto cleanup; | ||||||
|     } |     } | ||||||
|     umask(oldmask); |     umask(oldmask); | ||||||
|     if (server->privileged && setgid(oldgrp)) { |  | ||||||
|         VIR_ERROR(_("Failed to restore group ID to %d"), oldgrp); |     /* chown() doesn't work for abstract sockets but we use them only | ||||||
|  |      * if libvirtd runs unprivileged | ||||||
|  |      */ | ||||||
|  |     if (server->privileged && chown(path, -1, unix_sock_gid)) { | ||||||
|  |         VIR_ERROR(_("Failed to change group ID of '%s' to %d: %s"), | ||||||
|  |                   path, unix_sock_gid, | ||||||
|  |                   virStrerror(errno, ebuf, sizeof ebuf)); | ||||||
|         goto cleanup; |         goto cleanup; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user