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:
parent
dda24845fe
commit
5e5acbc8d6
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user