From 8eff0a9f9ece2c62ba09b53661b4bcf908560abd44223478224f35700bd7f242 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Tue, 26 Mar 2013 17:06:22 +0000 Subject: [PATCH] - Update hv_vss_daemon (bnc#811033) OBS-URL: https://build.opensuse.org/package/show/Virtualization/hyper-v?expand=0&rev=56 --- hyper-v.changes | 5 +++ hyper-v.spec | 3 +- hyper-v.tools.hv.hv_vss_daemon.c | 73 ++++++++++++++++++++------------ 3 files changed, 54 insertions(+), 27 deletions(-) diff --git a/hyper-v.changes b/hyper-v.changes index 900f544..2fb697e 100644 --- a/hyper-v.changes +++ b/hyper-v.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Tue Mar 26 18:03:47 CET 2013 - ohering@suse.de + +- Update hv_vss_daemon (bnc#811033) + ------------------------------------------------------------------- Fri Mar 22 17:23:36 CET 2013 - ohering@suse.de diff --git a/hyper-v.spec b/hyper-v.spec index f872518..fc7b7c3 100644 --- a/hyper-v.spec +++ b/hyper-v.spec @@ -29,7 +29,8 @@ Group: System/Kernel Supplements: modalias(dmi*:svn*MicrosoftCorporation*:pn*VirtualMachine*:rn*VirtualMachine*) Supplements: modalias(pci:v00001414d00005353sv*sd*bc*sc*i*) Url: http://www.kernel.org -Version: 4 +# Arbitrary version number +Version: 5 Release: 0 Source5: hyper-v.kvptest.ps1.txt Source9: hyper-v.include.linux.hyperv.h diff --git a/hyper-v.tools.hv.hv_vss_daemon.c b/hyper-v.tools.hv.hv_vss_daemon.c index cd4f5c0..5b36ea7 100644 --- a/hyper-v.tools.hv.hv_vss_daemon.c +++ b/hyper-v.tools.hv.hv_vss_daemon.c @@ -21,14 +21,18 @@ #include #include #include +#include #include +#include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -43,48 +47,59 @@ static struct sockaddr_nl addr; #endif +static int vss_do_freeze(char *dir, unsigned int cmd, char *fs_op) +{ + int ret, fd = open(dir, O_RDONLY); + + if (fd < 0) + return -1; + ret = ioctl(fd, cmd, 0); + syslog(LOG_INFO, "VSS: %s of %s: %s\n", fs_op, dir, strerror(errno)); + close(fd); + return !!ret; +} + static int vss_operate(int operation) { char *fs_op; - char cmd[512]; - char buf[512]; - FILE *file; - char *p; - char *x; - int error = -1; + char match[] = "/dev/"; + FILE *mounts; + struct mntent *ent; + unsigned int cmd; + int error = 0, root_seen = 0; switch (operation) { case VSS_OP_FREEZE: - fs_op = "-f "; + cmd = FIFREEZE; + fs_op = "freeze"; break; case VSS_OP_THAW: - fs_op = "-u "; + cmd = FITHAW; + fs_op = "thaw"; break; default: - goto out; + return -1; } - file = popen("mount | awk '/^\\/dev\\// { print $3}'", "r"); - if (file == NULL) - goto out; + mounts = setmntent("/proc/mounts", "r"); + if (mounts == NULL) + return -1; - while ((p = fgets(buf, sizeof(buf), file)) != NULL) { - x = strchr(p, '\n'); - *x = '\0'; - if (!strncmp(p, "/", sizeof("/"))) + while((ent = getmntent(mounts))) { + if (strncmp(ent->mnt_fsname, match, strlen(match))) continue; - - sprintf(cmd, "%s %s %s", "fsfreeze ", fs_op, p); - syslog(LOG_INFO, "VSS cmd is %s\n", cmd); - error = system(cmd); + if (strcmp(ent->mnt_dir, "/") == 0) { + root_seen = 1; + continue; + } + error |= vss_do_freeze(ent->mnt_dir, cmd, fs_op); } - pclose(file); + endmntent(mounts); - sprintf(cmd, "%s %s %s", "fsfreeze ", fs_op, "/"); - syslog(LOG_INFO, "VSS cmd is %s\n", cmd); - error = system(cmd); + if (root_seen) { + error |= vss_do_freeze("/", cmd, fs_op); + } -out: return error; } @@ -187,13 +202,19 @@ int main(void) len = recvfrom(fd, vss_recv_buffer, sizeof(vss_recv_buffer), 0, addr_p, &addr_l); - if (len < 0 || addr.nl_pid) { + if (len < 0) { syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s", addr.nl_pid, errno, strerror(errno)); close(fd); return -1; } + if (addr.nl_pid) { + syslog(LOG_WARNING, "Received packet from untrusted pid:%u", + addr.nl_pid); + continue; + } + incoming_msg = (struct nlmsghdr *)vss_recv_buffer; if (incoming_msg->nlmsg_type != NLMSG_DONE)