1 /*
2  * qemu_security.c: QEMU security management
3  *
4  * Copyright (C) 2016 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library.  If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
21 #include <config.h>
22 
23 #include "qemu_domain.h"
24 #include "qemu_namespace.h"
25 #include "qemu_security.h"
26 #include "virlog.h"
27 
28 #define VIR_FROM_THIS VIR_FROM_QEMU
29 
30 VIR_LOG_INIT("qemu.qemu_security");
31 
32 
33 int
qemuSecuritySetAllLabel(virQEMUDriver * driver,virDomainObj * vm,const char * incomingPath,bool migrated)34 qemuSecuritySetAllLabel(virQEMUDriver *driver,
35                         virDomainObj *vm,
36                         const char *incomingPath,
37                         bool migrated)
38 {
39     int ret = -1;
40     qemuDomainObjPrivate *priv = vm->privateData;
41     pid_t pid = -1;
42 
43     if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
44         pid = vm->pid;
45 
46     if (virSecurityManagerTransactionStart(driver->securityManager) < 0)
47         goto cleanup;
48 
49     if (virSecurityManagerSetAllLabel(driver->securityManager,
50                                       vm->def,
51                                       incomingPath,
52                                       priv->chardevStdioLogd,
53                                       migrated) < 0)
54         goto cleanup;
55 
56     if (virSecurityManagerTransactionCommit(driver->securityManager,
57                                             pid, priv->rememberOwner) < 0)
58         goto cleanup;
59 
60     ret = 0;
61  cleanup:
62     virSecurityManagerTransactionAbort(driver->securityManager);
63     return ret;
64 }
65 
66 
67 void
qemuSecurityRestoreAllLabel(virQEMUDriver * driver,virDomainObj * vm,bool migrated)68 qemuSecurityRestoreAllLabel(virQEMUDriver *driver,
69                             virDomainObj *vm,
70                             bool migrated)
71 {
72     qemuDomainObjPrivate *priv = vm->privateData;
73     bool transactionStarted = false;
74 
75     /* In contrast to qemuSecuritySetAllLabel, do not use vm->pid
76      * here. This function is called from qemuProcessStop() which
77      * is meant to do cleanup after qemu process died. The
78      * domain's namespace is gone as qemu was the only process
79      * running there. We would not succeed in entering the
80      * namespace then. */
81     if (virSecurityManagerTransactionStart(driver->securityManager) >= 0)
82         transactionStarted = true;
83 
84     virSecurityManagerRestoreAllLabel(driver->securityManager,
85                                       vm->def,
86                                       migrated,
87                                       priv->chardevStdioLogd);
88 
89     if (transactionStarted &&
90         virSecurityManagerTransactionCommit(driver->securityManager,
91                                             -1, priv->rememberOwner) < 0)
92         VIR_WARN("Unable to run security manager transaction");
93 
94     virSecurityManagerTransactionAbort(driver->securityManager);
95 }
96 
97 
98 int
qemuSecuritySetImageLabel(virQEMUDriver * driver,virDomainObj * vm,virStorageSource * src,bool backingChain,bool chainTop)99 qemuSecuritySetImageLabel(virQEMUDriver *driver,
100                           virDomainObj *vm,
101                           virStorageSource *src,
102                           bool backingChain,
103                           bool chainTop)
104 {
105     qemuDomainObjPrivate *priv = vm->privateData;
106     pid_t pid = -1;
107     int ret = -1;
108     virSecurityDomainImageLabelFlags labelFlags = 0;
109 
110     if (backingChain)
111         labelFlags |= VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN;
112 
113     if (chainTop)
114         labelFlags |= VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP;
115 
116     if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
117         pid = vm->pid;
118 
119     if (virSecurityManagerTransactionStart(driver->securityManager) < 0)
120         goto cleanup;
121 
122     if (virSecurityManagerSetImageLabel(driver->securityManager,
123                                         vm->def, src, labelFlags) < 0)
124         goto cleanup;
125 
126     if (virSecurityManagerTransactionCommit(driver->securityManager,
127                                             pid, priv->rememberOwner) < 0)
128         goto cleanup;
129 
130     ret = 0;
131  cleanup:
132     virSecurityManagerTransactionAbort(driver->securityManager);
133     return ret;
134 }
135 
136 
137 int
qemuSecurityRestoreImageLabel(virQEMUDriver * driver,virDomainObj * vm,virStorageSource * src,bool backingChain)138 qemuSecurityRestoreImageLabel(virQEMUDriver *driver,
139                               virDomainObj *vm,
140                               virStorageSource *src,
141                               bool backingChain)
142 {
143     qemuDomainObjPrivate *priv = vm->privateData;
144     pid_t pid = -1;
145     int ret = -1;
146     virSecurityDomainImageLabelFlags labelFlags = 0;
147 
148     if (backingChain)
149         labelFlags |= VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN;
150 
151     if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
152         pid = vm->pid;
153 
154     if (virSecurityManagerTransactionStart(driver->securityManager) < 0)
155         goto cleanup;
156 
157     if (virSecurityManagerRestoreImageLabel(driver->securityManager,
158                                             vm->def, src, labelFlags) < 0)
159         goto cleanup;
160 
161     if (virSecurityManagerTransactionCommit(driver->securityManager,
162                                             pid, priv->rememberOwner) < 0)
163         goto cleanup;
164 
165     ret = 0;
166  cleanup:
167     virSecurityManagerTransactionAbort(driver->securityManager);
168     return ret;
169 }
170 
171 
172 int
qemuSecurityMoveImageMetadata(virQEMUDriver * driver,virDomainObj * vm,virStorageSource * src,virStorageSource * dst)173 qemuSecurityMoveImageMetadata(virQEMUDriver *driver,
174                               virDomainObj *vm,
175                               virStorageSource *src,
176                               virStorageSource *dst)
177 {
178     qemuDomainObjPrivate *priv = vm->privateData;
179     pid_t pid = -1;
180 
181     if (!priv->rememberOwner)
182         return 0;
183 
184     if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
185         pid = vm->pid;
186 
187     return virSecurityManagerMoveImageMetadata(driver->securityManager, pid, src, dst);
188 }
189 
190 
191 int
qemuSecuritySetHostdevLabel(virQEMUDriver * driver,virDomainObj * vm,virDomainHostdevDef * hostdev)192 qemuSecuritySetHostdevLabel(virQEMUDriver *driver,
193                             virDomainObj *vm,
194                             virDomainHostdevDef *hostdev)
195 {
196     qemuDomainObjPrivate *priv = vm->privateData;
197     pid_t pid = -1;
198     int ret = -1;
199 
200     if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
201         pid = vm->pid;
202 
203     if (virSecurityManagerTransactionStart(driver->securityManager) < 0)
204         goto cleanup;
205 
206     if (virSecurityManagerSetHostdevLabel(driver->securityManager,
207                                           vm->def,
208                                           hostdev,
209                                           NULL) < 0)
210         goto cleanup;
211 
212     if (virSecurityManagerTransactionCommit(driver->securityManager,
213                                             pid, priv->rememberOwner) < 0)
214         goto cleanup;
215 
216     ret = 0;
217  cleanup:
218     virSecurityManagerTransactionAbort(driver->securityManager);
219     return ret;
220 }
221 
222 
223 int
qemuSecurityRestoreHostdevLabel(virQEMUDriver * driver,virDomainObj * vm,virDomainHostdevDef * hostdev)224 qemuSecurityRestoreHostdevLabel(virQEMUDriver *driver,
225                                 virDomainObj *vm,
226                                 virDomainHostdevDef *hostdev)
227 {
228     qemuDomainObjPrivate *priv = vm->privateData;
229     pid_t pid = -1;
230     int ret = -1;
231 
232     if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
233         pid = vm->pid;
234 
235     if (virSecurityManagerTransactionStart(driver->securityManager) < 0)
236         goto cleanup;
237 
238     if (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
239                                               vm->def,
240                                               hostdev,
241                                               NULL) < 0)
242         goto cleanup;
243 
244     if (virSecurityManagerTransactionCommit(driver->securityManager,
245                                             pid, priv->rememberOwner) < 0)
246         goto cleanup;
247 
248     ret = 0;
249  cleanup:
250     virSecurityManagerTransactionAbort(driver->securityManager);
251     return ret;
252 }
253 
254 
255 int
qemuSecuritySetMemoryLabel(virQEMUDriver * driver,virDomainObj * vm,virDomainMemoryDef * mem)256 qemuSecuritySetMemoryLabel(virQEMUDriver *driver,
257                            virDomainObj *vm,
258                            virDomainMemoryDef *mem)
259 {
260     qemuDomainObjPrivate *priv = vm->privateData;
261     pid_t pid = -1;
262     int ret = -1;
263 
264     if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
265         pid = vm->pid;
266 
267     if (virSecurityManagerTransactionStart(driver->securityManager) < 0)
268         goto cleanup;
269 
270     if (virSecurityManagerSetMemoryLabel(driver->securityManager,
271                                          vm->def,
272                                          mem) < 0)
273         goto cleanup;
274 
275     if (virSecurityManagerTransactionCommit(driver->securityManager,
276                                             pid, priv->rememberOwner) < 0)
277         goto cleanup;
278 
279     ret = 0;
280  cleanup:
281     virSecurityManagerTransactionAbort(driver->securityManager);
282     return ret;
283 }
284 
285 
286 int
qemuSecurityRestoreMemoryLabel(virQEMUDriver * driver,virDomainObj * vm,virDomainMemoryDef * mem)287 qemuSecurityRestoreMemoryLabel(virQEMUDriver *driver,
288                                virDomainObj *vm,
289                                virDomainMemoryDef *mem)
290 {
291     qemuDomainObjPrivate *priv = vm->privateData;
292     pid_t pid = -1;
293     int ret = -1;
294 
295     if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
296         pid = vm->pid;
297 
298     if (virSecurityManagerTransactionStart(driver->securityManager) < 0)
299         goto cleanup;
300 
301     if (virSecurityManagerRestoreMemoryLabel(driver->securityManager,
302                                              vm->def,
303                                              mem) < 0)
304         goto cleanup;
305 
306     if (virSecurityManagerTransactionCommit(driver->securityManager,
307                                             pid, priv->rememberOwner) < 0)
308         goto cleanup;
309 
310     ret = 0;
311  cleanup:
312     virSecurityManagerTransactionAbort(driver->securityManager);
313     return ret;
314 }
315 
316 
317 int
qemuSecuritySetInputLabel(virDomainObj * vm,virDomainInputDef * input)318 qemuSecuritySetInputLabel(virDomainObj *vm,
319                           virDomainInputDef *input)
320 {
321     qemuDomainObjPrivate *priv = vm->privateData;
322     virQEMUDriver *driver = priv->driver;
323     pid_t pid = -1;
324     int ret = -1;
325 
326     if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
327         pid = vm->pid;
328 
329     if (virSecurityManagerTransactionStart(driver->securityManager) < 0)
330         goto cleanup;
331 
332     if (virSecurityManagerSetInputLabel(driver->securityManager,
333                                         vm->def,
334                                         input) < 0)
335         goto cleanup;
336 
337     if (virSecurityManagerTransactionCommit(driver->securityManager,
338                                             pid, priv->rememberOwner) < 0)
339         goto cleanup;
340 
341     ret = 0;
342  cleanup:
343     virSecurityManagerTransactionAbort(driver->securityManager);
344     return ret;
345 }
346 
347 
348 int
qemuSecurityRestoreInputLabel(virDomainObj * vm,virDomainInputDef * input)349 qemuSecurityRestoreInputLabel(virDomainObj *vm,
350                               virDomainInputDef *input)
351 {
352     qemuDomainObjPrivate *priv = vm->privateData;
353     virQEMUDriver *driver = priv->driver;
354     pid_t pid = -1;
355     int ret = -1;
356 
357     if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
358         pid = vm->pid;
359 
360     if (virSecurityManagerTransactionStart(driver->securityManager) < 0)
361         goto cleanup;
362 
363     if (virSecurityManagerRestoreInputLabel(driver->securityManager,
364                                             vm->def,
365                                             input) < 0)
366         goto cleanup;
367 
368     if (virSecurityManagerTransactionCommit(driver->securityManager,
369                                             pid, priv->rememberOwner) < 0)
370         goto cleanup;
371 
372     ret = 0;
373  cleanup:
374     virSecurityManagerTransactionAbort(driver->securityManager);
375     return ret;
376 }
377 
378 
379 int
qemuSecuritySetChardevLabel(virQEMUDriver * driver,virDomainObj * vm,virDomainChrDef * chr)380 qemuSecuritySetChardevLabel(virQEMUDriver *driver,
381                             virDomainObj *vm,
382                             virDomainChrDef *chr)
383 {
384     int ret = -1;
385     qemuDomainObjPrivate *priv = vm->privateData;
386     pid_t pid = -1;
387 
388     if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
389         pid = vm->pid;
390 
391     if (virSecurityManagerTransactionStart(driver->securityManager) < 0)
392         goto cleanup;
393 
394     if (virSecurityManagerSetChardevLabel(driver->securityManager,
395                                           vm->def,
396                                           chr->source,
397                                           priv->chardevStdioLogd) < 0)
398         goto cleanup;
399 
400     if (virSecurityManagerTransactionCommit(driver->securityManager,
401                                             pid, priv->rememberOwner) < 0)
402         goto cleanup;
403 
404     ret = 0;
405  cleanup:
406     virSecurityManagerTransactionAbort(driver->securityManager);
407     return ret;
408 }
409 
410 
411 int
qemuSecurityRestoreChardevLabel(virQEMUDriver * driver,virDomainObj * vm,virDomainChrDef * chr)412 qemuSecurityRestoreChardevLabel(virQEMUDriver *driver,
413                                 virDomainObj *vm,
414                                 virDomainChrDef *chr)
415 {
416     int ret = -1;
417     qemuDomainObjPrivate *priv = vm->privateData;
418     pid_t pid = -1;
419 
420     if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
421         pid = vm->pid;
422 
423     if (virSecurityManagerTransactionStart(driver->securityManager) < 0)
424         goto cleanup;
425 
426     if (virSecurityManagerRestoreChardevLabel(driver->securityManager,
427                                               vm->def,
428                                               chr->source,
429                                               priv->chardevStdioLogd) < 0)
430         goto cleanup;
431 
432     if (virSecurityManagerTransactionCommit(driver->securityManager,
433                                             pid, priv->rememberOwner) < 0)
434         goto cleanup;
435 
436     ret = 0;
437  cleanup:
438     virSecurityManagerTransactionAbort(driver->securityManager);
439     return ret;
440 }
441 
442 int
qemuSecuritySetNetdevLabel(virQEMUDriver * driver,virDomainObj * vm,virDomainNetDef * net)443 qemuSecuritySetNetdevLabel(virQEMUDriver *driver,
444                            virDomainObj *vm,
445                            virDomainNetDef *net)
446 {
447     int ret = -1;
448     qemuDomainObjPrivate *priv = vm->privateData;
449     pid_t pid = -1;
450 
451     if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
452         pid = vm->pid;
453 
454     if (virSecurityManagerTransactionStart(driver->securityManager) < 0)
455         goto cleanup;
456 
457     if (virSecurityManagerSetNetdevLabel(driver->securityManager,
458                                          vm->def, net) < 0)
459         goto cleanup;
460 
461     if (virSecurityManagerTransactionCommit(driver->securityManager,
462                                             pid, priv->rememberOwner) < 0)
463         goto cleanup;
464 
465     ret = 0;
466  cleanup:
467     virSecurityManagerTransactionAbort(driver->securityManager);
468     return ret;
469 }
470 
471 
472 int
qemuSecurityRestoreNetdevLabel(virQEMUDriver * driver,virDomainObj * vm,virDomainNetDef * net)473 qemuSecurityRestoreNetdevLabel(virQEMUDriver *driver,
474                                virDomainObj *vm,
475                                virDomainNetDef *net)
476 {
477     int ret = -1;
478     qemuDomainObjPrivate *priv = vm->privateData;
479     pid_t pid = -1;
480 
481     if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
482         pid = vm->pid;
483 
484     if (virSecurityManagerTransactionStart(driver->securityManager) < 0)
485         goto cleanup;
486 
487     if (virSecurityManagerRestoreNetdevLabel(driver->securityManager,
488                                              vm->def, net) < 0)
489         goto cleanup;
490 
491     if (virSecurityManagerTransactionCommit(driver->securityManager,
492                                             pid, priv->rememberOwner) < 0)
493         goto cleanup;
494 
495     ret = 0;
496  cleanup:
497     virSecurityManagerTransactionAbort(driver->securityManager);
498     return ret;
499 }
500 
501 
502 /*
503  * qemuSecurityStartVhostUserGPU:
504  *
505  * @driver: the QEMU driver
506  * @vm: the domain object
507  * @cmd: the command to run
508  * @existstatus: pointer to int returning exit status of process
509  * @cmdret: pointer to int returning result of virCommandRun
510  *
511  * Start the vhost-user-gpu process with appropriate labels.
512  * This function returns -1 on security setup error, 0 if all the
513  * setup was done properly. In case the virCommand failed to run
514  * 0 is returned but cmdret is set appropriately with the process
515  * exitstatus also set.
516  */
517 int
qemuSecurityStartVhostUserGPU(virQEMUDriver * driver,virDomainObj * vm,virCommand * cmd,int * exitstatus,int * cmdret)518 qemuSecurityStartVhostUserGPU(virQEMUDriver *driver,
519                               virDomainObj *vm,
520                               virCommand *cmd,
521                               int *exitstatus,
522                               int *cmdret)
523 {
524     if (virSecurityManagerSetChildProcessLabel(driver->securityManager,
525                                                vm->def, cmd) < 0)
526         return -1;
527 
528     if (virSecurityManagerPreFork(driver->securityManager) < 0)
529         return -1;
530 
531     *cmdret = virCommandRun(cmd, exitstatus);
532 
533     virSecurityManagerPostFork(driver->securityManager);
534 
535     if (*cmdret < 0)
536         return -1;
537 
538     return 0;
539 }
540 
541 
542 /*
543  * qemuSecurityStartTPMEmulator:
544  *
545  * @driver: the QEMU driver
546  * @vm: the domain object
547  * @cmd: the command to run
548  * @uid: the uid to run the emulator
549  * @gid: the gid to run the emulator
550  * @existstatus: pointer to int returning exit status of process
551  * @cmdret: pointer to int returning result of virCommandRun
552  *
553  * Start the TPM emulator with appropriate labels. Apply security
554  * labels to files first.
555  * This function returns -1 on security setup error, 0 if all the
556  * setup was done properly. In case the virCommand failed to run
557  * 0 is returned but cmdret is set appropriately with the process
558  * exitstatus also set.
559  */
560 int
qemuSecurityStartTPMEmulator(virQEMUDriver * driver,virDomainObj * vm,virCommand * cmd,uid_t uid,gid_t gid,int * exitstatus,int * cmdret)561 qemuSecurityStartTPMEmulator(virQEMUDriver *driver,
562                              virDomainObj *vm,
563                              virCommand *cmd,
564                              uid_t uid,
565                              gid_t gid,
566                              int *exitstatus,
567                              int *cmdret)
568 {
569     qemuDomainObjPrivate *priv = vm->privateData;
570     int ret = -1;
571     bool transactionStarted = false;
572 
573     if (virSecurityManagerTransactionStart(driver->securityManager) < 0)
574         return -1;
575     transactionStarted = true;
576 
577     if (virSecurityManagerSetTPMLabels(driver->securityManager,
578                                        vm->def) < 0) {
579         virSecurityManagerTransactionAbort(driver->securityManager);
580         return -1;
581     }
582 
583     if (virSecurityManagerTransactionCommit(driver->securityManager,
584                                             -1, priv->rememberOwner) < 0)
585         goto cleanup_abort;
586     transactionStarted = false;
587 
588     if (qemuSecurityCommandRun(driver, vm, cmd, uid, gid, exitstatus, cmdret) < 0)
589         goto cleanup;
590 
591     ret = 0;
592 
593     if (*cmdret < 0)
594         goto cleanup;
595 
596     return 0;
597 
598  cleanup:
599     if (!transactionStarted &&
600         virSecurityManagerTransactionStart(driver->securityManager) >= 0)
601         transactionStarted = true;
602 
603     virSecurityManagerRestoreTPMLabels(driver->securityManager, vm->def);
604 
605     if (transactionStarted &&
606         virSecurityManagerTransactionCommit(driver->securityManager,
607                                             -1, priv->rememberOwner) < 0)
608         VIR_WARN("Unable to run security manager transaction");
609 
610  cleanup_abort:
611     virSecurityManagerTransactionAbort(driver->securityManager);
612     return ret;
613 }
614 
615 
616 void
qemuSecurityCleanupTPMEmulator(virQEMUDriver * driver,virDomainObj * vm)617 qemuSecurityCleanupTPMEmulator(virQEMUDriver *driver,
618                                virDomainObj *vm)
619 {
620     qemuDomainObjPrivate *priv = vm->privateData;
621     bool transactionStarted = false;
622 
623     if (virSecurityManagerTransactionStart(driver->securityManager) >= 0)
624         transactionStarted = true;
625 
626     virSecurityManagerRestoreTPMLabels(driver->securityManager, vm->def);
627 
628     if (transactionStarted &&
629         virSecurityManagerTransactionCommit(driver->securityManager,
630                                             -1, priv->rememberOwner) < 0)
631         VIR_WARN("Unable to run security manager transaction");
632 
633     virSecurityManagerTransactionAbort(driver->securityManager);
634 }
635 
636 
637 int
qemuSecurityDomainSetPathLabel(virQEMUDriver * driver,virDomainObj * vm,const char * path,bool allowSubtree)638 qemuSecurityDomainSetPathLabel(virQEMUDriver *driver,
639                                virDomainObj *vm,
640                                const char *path,
641                                bool allowSubtree)
642 {
643     qemuDomainObjPrivate *priv = vm->privateData;
644     pid_t pid = -1;
645     int ret = -1;
646 
647     if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
648         pid = vm->pid;
649 
650     if (virSecurityManagerTransactionStart(driver->securityManager) < 0)
651         goto cleanup;
652 
653     if (virSecurityManagerDomainSetPathLabel(driver->securityManager,
654                                              vm->def,
655                                              path,
656                                              allowSubtree) < 0)
657         goto cleanup;
658 
659     if (virSecurityManagerTransactionCommit(driver->securityManager,
660                                             pid, priv->rememberOwner) < 0)
661         goto cleanup;
662 
663     ret = 0;
664  cleanup:
665     virSecurityManagerTransactionAbort(driver->securityManager);
666     return ret;
667 }
668 
669 
670 int
qemuSecurityDomainRestorePathLabel(virQEMUDriver * driver,virDomainObj * vm,const char * path)671 qemuSecurityDomainRestorePathLabel(virQEMUDriver *driver,
672                                    virDomainObj *vm,
673                                    const char *path)
674 {
675     qemuDomainObjPrivate *priv = vm->privateData;
676     pid_t pid = -1;
677     int ret = -1;
678 
679     if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
680         pid = vm->pid;
681 
682     if (virSecurityManagerTransactionStart(driver->securityManager) < 0)
683         goto cleanup;
684 
685     if (virSecurityManagerDomainRestorePathLabel(driver->securityManager,
686                                                  vm->def,
687                                                  path) < 0)
688         goto cleanup;
689 
690     if (virSecurityManagerTransactionCommit(driver->securityManager,
691                                             pid, priv->rememberOwner) < 0)
692         goto cleanup;
693 
694     ret = 0;
695  cleanup:
696     virSecurityManagerTransactionAbort(driver->securityManager);
697     return ret;
698 }
699 
700 
701 /**
702  * qemuSecurityCommandRun:
703  * @driver: the QEMU driver
704  * @vm: the domain object
705  * @cmd: the command to run
706  * @uid: the uid to force
707  * @gid: the gid to force
708  * @existstatus: pointer to int returning exit status of process
709  * @cmdret: pointer to int returning result of virCommandRun
710  *
711  * Run @cmd with seclabels set on it. If @uid and/or @gid are not
712  * -1 then their value is enforced.
713  *
714  * Returns: 0 on success,
715  *         -1 otherwise.
716  */
717 int
qemuSecurityCommandRun(virQEMUDriver * driver,virDomainObj * vm,virCommand * cmd,uid_t uid,gid_t gid,int * exitstatus,int * cmdret)718 qemuSecurityCommandRun(virQEMUDriver *driver,
719                        virDomainObj *vm,
720                        virCommand *cmd,
721                        uid_t uid,
722                        gid_t gid,
723                        int *exitstatus,
724                        int *cmdret)
725 {
726     if (virSecurityManagerSetChildProcessLabel(driver->securityManager,
727                                                vm->def, cmd) < 0)
728         return -1;
729 
730     if (uid != (uid_t) -1)
731         virCommandSetUID(cmd, uid);
732     if (gid != (gid_t) -1)
733         virCommandSetGID(cmd, gid);
734 
735     if (virSecurityManagerPreFork(driver->securityManager) < 0)
736         return -1;
737 
738     *cmdret = virCommandRun(cmd, exitstatus);
739 
740     virSecurityManagerPostFork(driver->securityManager);
741 
742     return 0;
743 }
744