ia64/xen-unstable

view xen/xsm/flask/hooks.c @ 18394:dade7f0bdc8d

hvm: Use main memory for video memory.

When creating an HVM domain, if e.g. another domain is created before
qemu allocates video memory, the extra 8MB memory ballooning is not
available any more, because it got consumed by the other domain.

This fixes it by taking video memory from the main memory:

- make hvmloader use e820_malloc to reserve some of the main memory
and notify ioemu of its address through the Xen platform PCI card.
- add XENMAPSPACE_mfn to the xen_add_to_physmap memory op, to allow
ioemu to move the MFNs between the original position and the PCI
mapping, when LFB acceleration is disabled/enabled
- add a remove_from_physmap memory op, to allow ioemu to unmap it
completely for the case of old guests with acceleration disabled.
- add xc_domain_memory_translate_gpfn_list to libxc to allow ioemu to
get the MFNs of the video memory.
- have xend save the PCI memory space instead of ioemu: if a memory
page is there, the guest can access it like usual memory, so xend
can safely be responsible to save it. The extra benefit is that
live migration will apply the logdirty optimization there too.
- handle old saved images, populating the video memory from ioemu if
really needed.

Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Aug 27 14:53:39 2008 +0100 (2008-08-27)
parents 217c8b6ebfab
children 44f039c4aee4
line source
1 /*
2 * This file contains the Flask hook function implementations for Xen.
3 *
4 * Author: George Coker, <gscoker@alpha.ncsc.mil>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2,
8 * as published by the Free Software Foundation.
9 */
11 #include <xen/init.h>
12 #include <xen/lib.h>
13 #include <xen/sched.h>
14 #include <xen/xmalloc.h>
15 #include <xsm/xsm.h>
16 #include <xen/spinlock.h>
17 #include <xen/cpumask.h>
18 #include <xen/errno.h>
19 #include <xen/guest_access.h>
20 #include <public/xen.h>
21 #include <public/physdev.h>
22 #include <public/platform.h>
24 #include <public/xsm/flask_op.h>
26 #include <avc.h>
27 #include <avc_ss.h>
28 #include <objsec.h>
29 #include <conditional.h>
31 struct xsm_operations *original_ops = NULL;
33 static int domain_has_perm(struct domain *dom1, struct domain *dom2,
34 u16 class, u32 perms)
35 {
36 struct domain_security_struct *dsec1, *dsec2;
38 dsec1 = dom1->ssid;
39 dsec2 = dom2->ssid;
41 return avc_has_perm(dsec1->sid, dsec2->sid, class, perms, NULL);
42 }
44 static int domain_has_evtchn(struct domain *d, struct evtchn *chn, u32 perms)
45 {
46 struct domain_security_struct *dsec;
47 struct evtchn_security_struct *esec;
49 dsec = d->ssid;
50 esec = chn->ssid;
52 return avc_has_perm(dsec->sid, esec->sid, SECCLASS_EVENT, perms, NULL);
53 }
55 static int domain_has_xen(struct domain *d, u32 perms)
56 {
57 struct domain_security_struct *dsec;
58 dsec = d->ssid;
60 return avc_has_perm(dsec->sid, SECINITSID_XEN, SECCLASS_XEN, perms, NULL);
61 }
63 static int flask_domain_alloc_security(struct domain *d)
64 {
65 struct domain_security_struct *dsec;
67 dsec = xmalloc(struct domain_security_struct);
69 if ( !dsec )
70 return -ENOMEM;
72 memset(dsec, 0, sizeof(struct domain_security_struct));
74 dsec->d = d;
76 if ( d->domain_id == IDLE_DOMAIN_ID )
77 {
78 dsec->sid = SECINITSID_XEN;
79 dsec->create_sid = SECINITSID_DOM0;
80 }
81 else
82 {
83 dsec->sid = SECINITSID_UNLABELED;
84 dsec->create_sid = SECSID_NULL;
85 }
87 d->ssid = dsec;
89 return 0;
90 }
92 static void flask_domain_free_security(struct domain *d)
93 {
94 struct domain_security_struct *dsec = d->ssid;
96 if ( !dsec )
97 return;
99 d->ssid = NULL;
100 xfree(dsec);
101 }
103 static int flask_evtchn_unbound(struct domain *d1, struct evtchn *chn,
104 domid_t id2)
105 {
106 u32 newsid;
107 int rc;
108 domid_t id;
109 struct domain *d2;
110 struct domain_security_struct *dsec, *dsec1, *dsec2;
111 struct evtchn_security_struct *esec;
113 dsec = current->domain->ssid;
114 dsec1 = d1->ssid;
115 esec = chn->ssid;
117 if ( id2 == DOMID_SELF )
118 id = current->domain->domain_id;
119 else
120 id = id2;
122 d2 = get_domain_by_id(id);
123 if ( d2 == NULL )
124 return -EPERM;
126 dsec2 = d2->ssid;
127 rc = security_transition_sid(dsec1->sid, dsec2->sid, SECCLASS_EVENT,
128 &newsid);
129 if ( rc )
130 goto out;
132 rc = avc_has_perm(dsec->sid, newsid, SECCLASS_EVENT,
133 EVENT__CREATE|EVENT__ALLOC, NULL);
134 if ( rc )
135 goto out;
137 rc = avc_has_perm(newsid, dsec2->sid, SECCLASS_EVENT, EVENT__BIND, NULL);
138 if ( rc )
139 goto out;
140 else
141 esec->sid = newsid;
143 out:
144 put_domain(d2);
145 return rc;
146 }
148 static int flask_evtchn_interdomain(struct domain *d1, struct evtchn *chn1,
149 struct domain *d2, struct evtchn *chn2)
150 {
151 u32 newsid1;
152 u32 newsid2;
153 int rc;
154 struct domain_security_struct *dsec1, *dsec2;
155 struct evtchn_security_struct *esec1, *esec2;
157 dsec1 = d1->ssid;
158 dsec2 = d2->ssid;
160 esec1 = chn1->ssid;
161 esec2 = chn2->ssid;
163 rc = security_transition_sid(dsec1->sid, dsec2->sid,
164 SECCLASS_EVENT, &newsid1);
165 if ( rc )
166 {
167 printk("%s: security_transition_sid failed, rc=%d (domain=%d)\n",
168 __FUNCTION__, -rc, d2->domain_id);
169 return rc;
170 }
172 rc = avc_has_perm(dsec1->sid, newsid1, SECCLASS_EVENT, EVENT__CREATE, NULL);
173 if ( rc )
174 return rc;
176 rc = security_transition_sid(dsec2->sid, dsec1->sid,
177 SECCLASS_EVENT, &newsid2);
178 if ( rc )
179 {
180 printk("%s: security_transition_sid failed, rc=%d (domain=%d)\n",
181 __FUNCTION__, -rc, d1->domain_id);
182 return rc;
183 }
185 rc = avc_has_perm(dsec2->sid, newsid2, SECCLASS_EVENT, EVENT__CREATE, NULL);
186 if ( rc )
187 return rc;
189 rc = avc_has_perm(newsid1, dsec2->sid, SECCLASS_EVENT, EVENT__BIND, NULL);
190 if ( rc )
191 return rc;
193 rc = avc_has_perm(newsid2, dsec1->sid, SECCLASS_EVENT, EVENT__BIND, NULL);
194 if ( rc )
195 return rc;
197 esec1->sid = newsid1;
198 esec2->sid = newsid2;
200 return rc;
201 }
203 static void flask_evtchn_close_post(struct evtchn *chn)
204 {
205 struct evtchn_security_struct *esec;
206 esec = chn->ssid;
208 esec->sid = SECINITSID_UNLABELED;
209 }
211 static int flask_evtchn_send(struct domain *d, struct evtchn *chn)
212 {
213 return domain_has_evtchn(d, chn, EVENT__SEND);
214 }
216 static int flask_evtchn_status(struct domain *d, struct evtchn *chn)
217 {
218 return domain_has_evtchn(d, chn, EVENT__STATUS);
219 }
221 static int flask_evtchn_reset(struct domain *d1, struct domain *d2)
222 {
223 return domain_has_perm(d1, d2, SECCLASS_EVENT, EVENT__RESET);
224 }
226 static int flask_alloc_security_evtchn(struct evtchn *chn)
227 {
228 struct evtchn_security_struct *esec;
230 esec = xmalloc(struct evtchn_security_struct);
232 if ( !esec )
233 return -ENOMEM;
235 memset(esec, 0, sizeof(struct evtchn_security_struct));
237 esec->chn = chn;
238 esec->sid = SECINITSID_UNLABELED;
240 chn->ssid = esec;
242 return 0;
243 }
245 static void flask_free_security_evtchn(struct evtchn *chn)
246 {
247 struct evtchn_security_struct *esec;
249 if ( !chn )
250 return;
252 esec = chn->ssid;
254 if ( !esec )
255 return;
257 chn->ssid = NULL;
258 xfree(esec);
259 }
261 static int flask_grant_mapref(struct domain *d1, struct domain *d2,
262 uint32_t flags)
263 {
264 u32 perms = GRANT__MAP_READ;
266 if ( flags & GTF_writing )
267 perms |= GRANT__MAP_WRITE;
269 return domain_has_perm(d1, d2, SECCLASS_GRANT, perms);
270 }
272 static int flask_grant_unmapref(struct domain *d1, struct domain *d2)
273 {
274 return domain_has_perm(d1, d2, SECCLASS_GRANT, GRANT__UNMAP);
275 }
277 static int flask_grant_setup(struct domain *d1, struct domain *d2)
278 {
279 return domain_has_perm(d1, d2, SECCLASS_GRANT, GRANT__SETUP);
280 }
282 static int flask_grant_transfer(struct domain *d1, struct domain *d2)
283 {
284 return domain_has_perm(d1, d2, SECCLASS_GRANT, GRANT__TRANSFER);
285 }
287 static int flask_grant_copy(struct domain *d1, struct domain *d2)
288 {
289 return domain_has_perm(d1, d2, SECCLASS_GRANT, GRANT__COPY);
290 }
292 static int flask_grant_query_size(struct domain *d1, struct domain *d2)
293 {
294 return domain_has_perm(d1, d2, SECCLASS_GRANT, GRANT__QUERY);
295 }
297 static int get_page_sid(struct page_info *page, u32 *sid)
298 {
299 int rc = 0;
300 struct domain *d;
301 struct domain_security_struct *dsec;
302 unsigned long mfn;
304 d = page_get_owner(page);
306 if ( d == NULL )
307 {
308 mfn = page_to_mfn(page);
309 rc = security_iomem_sid(mfn, sid);
310 return rc;
311 }
313 switch ( d->domain_id )
314 {
315 case DOMID_IO:
316 /*A tracked IO page?*/
317 *sid = SECINITSID_DOMIO;
318 break;
320 case DOMID_XEN:
321 /*A page from Xen's private heap?*/
322 *sid = SECINITSID_DOMXEN;
323 break;
325 default:
326 /*Pages are implicitly labeled by domain ownership!*/
327 dsec = d->ssid;
328 *sid = dsec->sid;
329 break;
330 }
332 return rc;
333 }
335 static int get_mfn_sid(unsigned long mfn, u32 *sid)
336 {
337 int rc = 0;
338 struct page_info *page;
340 if ( mfn_valid(mfn) )
341 {
342 /*mfn is valid if this is a page that Xen is tracking!*/
343 page = mfn_to_page(mfn);
344 rc = get_page_sid(page, sid);
345 }
346 else
347 {
348 /*Possibly an untracked IO page?*/
349 rc = security_iomem_sid(mfn, sid);
350 }
352 return rc;
353 }
355 static int flask_translate_gpfn_list(struct domain *d, unsigned long mfn)
356 {
357 int rc = 0;
358 u32 sid;
359 struct domain_security_struct *dsec;
360 dsec = d->ssid;
362 rc = get_mfn_sid(mfn, &sid);
363 if ( rc )
364 return rc;
366 return avc_has_perm(dsec->sid, sid, SECCLASS_MMU, MMU__TRANSLATEGP, NULL);
367 }
369 static int flask_memory_adjust_reservation(struct domain *d1, struct domain *d2)
370 {
371 return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__ADJUST);
372 }
374 static int flask_memory_stat_reservation(struct domain *d1, struct domain *d2)
375 {
376 return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__STAT);
377 }
379 static int flask_memory_pin_page(struct domain *d, struct page_info *page)
380 {
381 int rc = 0;
382 u32 sid;
383 struct domain_security_struct *dsec;
384 dsec = d->ssid;
386 rc = get_page_sid(page, &sid);
387 if ( rc )
388 return rc;
390 return avc_has_perm(dsec->sid, sid, SECCLASS_MMU, MMU__PINPAGE, NULL);
391 }
393 /* Used to defer flushing of memory structures. */
394 struct percpu_mm_info {
395 #define DOP_FLUSH_TLB (1<<0) /* Flush the local TLB. */
396 #define DOP_FLUSH_ALL_TLBS (1<<1) /* Flush TLBs of all VCPUs of current dom. */
397 #define DOP_RELOAD_LDT (1<<2) /* Reload the LDT shadow mapping. */
398 unsigned int deferred_ops;
399 /* If non-NULL, specifies a foreign subject domain for some operations. */
400 struct domain *foreign;
401 };
402 static DEFINE_PER_CPU(struct percpu_mm_info, percpu_mm_info);
404 /*
405 * Returns the current foreign domain; defaults to the currently-executing
406 * domain if a foreign override hasn't been specified.
407 */
408 #define FOREIGNDOM (this_cpu(percpu_mm_info).foreign ?: current->domain)
410 static int flask_console_io(struct domain *d, int cmd)
411 {
412 u32 perm;
414 switch ( cmd )
415 {
416 case CONSOLEIO_read:
417 perm = XEN__READCONSOLE;
418 break;
419 case CONSOLEIO_write:
420 perm = XEN__WRITECONSOLE;
421 break;
422 default:
423 return -EPERM;
424 }
426 return domain_has_xen(d, perm);
427 }
429 static int flask_profile(struct domain *d, int op)
430 {
431 u32 perm;
433 switch ( op )
434 {
435 case XENOPROF_init:
436 case XENOPROF_enable_virq:
437 case XENOPROF_disable_virq:
438 case XENOPROF_get_buffer:
439 perm = XEN__NONPRIVPROFILE;
440 break;
441 case XENOPROF_reset_active_list:
442 case XENOPROF_reset_passive_list:
443 case XENOPROF_set_active:
444 case XENOPROF_set_passive:
445 case XENOPROF_reserve_counters:
446 case XENOPROF_counter:
447 case XENOPROF_setup_events:
448 case XENOPROF_start:
449 case XENOPROF_stop:
450 case XENOPROF_release_counters:
451 case XENOPROF_shutdown:
452 perm = XEN__PRIVPROFILE;
453 break;
454 default:
455 return -EPERM;
456 }
458 return domain_has_xen(d, perm);
459 }
461 static int flask_kexec(void)
462 {
463 return domain_has_xen(current->domain, XEN__KEXEC);
464 }
466 static int flask_schedop_shutdown(struct domain *d1, struct domain *d2)
467 {
468 return domain_has_perm(d1, d2, SECCLASS_DOMAIN, DOMAIN__SHUTDOWN);
469 }
471 static void flask_security_domaininfo(struct domain *d,
472 struct xen_domctl_getdomaininfo *info)
473 {
474 struct domain_security_struct *dsec;
476 dsec = d->ssid;
477 info->ssidref = dsec->sid;
478 }
480 static int flask_setvcpucontext(struct domain *d)
481 {
482 return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
483 DOMAIN__SETVCPUCONTEXT);
484 }
486 static int flask_pausedomain(struct domain *d)
487 {
488 return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__PAUSE);
489 }
491 static int flask_unpausedomain(struct domain *d)
492 {
493 return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__UNPAUSE);
494 }
496 static int flask_resumedomain(struct domain *d)
497 {
498 return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__RESUME);
499 }
501 static int flask_domain_create(struct domain *d, u32 ssidref)
502 {
503 int rc;
504 struct domain_security_struct *dsec1;
505 struct domain_security_struct *dsec2;
507 dsec1 = current->domain->ssid;
509 if ( dsec1->create_sid == SECSID_NULL )
510 dsec1->create_sid = ssidref;
512 rc = avc_has_perm(dsec1->sid, dsec1->create_sid, SECCLASS_DOMAIN,
513 DOMAIN__CREATE, NULL);
514 if ( rc )
515 {
516 dsec1->create_sid = SECSID_NULL;
517 return rc;
518 }
520 dsec2 = d->ssid;
521 dsec2->sid = dsec1->create_sid;
523 dsec1->create_sid = SECSID_NULL;
524 dsec2->create_sid = SECSID_NULL;
526 return rc;
527 }
529 static int flask_max_vcpus(struct domain *d)
530 {
531 return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
532 DOMAIN__MAX_VCPUS);
533 }
535 static int flask_destroydomain(struct domain *d)
536 {
537 return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
538 DOMAIN__DESTROY);
539 }
541 static int flask_vcpuaffinity(int cmd, struct domain *d)
542 {
543 u32 perm;
545 switch ( cmd )
546 {
547 case XEN_DOMCTL_setvcpuaffinity:
548 perm = DOMAIN__SETVCPUAFFINITY;
549 break;
550 case XEN_DOMCTL_getvcpuaffinity:
551 perm = DOMAIN__GETVCPUAFFINITY;
552 break;
553 default:
554 return -EPERM;
555 }
557 return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm );
558 }
560 static int flask_scheduler(struct domain *d)
561 {
562 int rc = 0;
564 rc = domain_has_xen(current->domain, XEN__SCHEDULER);
565 if ( rc )
566 return rc;
568 return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
569 DOMAIN__SCHEDULER);
570 }
572 static int flask_getdomaininfo(struct domain *d)
573 {
574 return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
575 DOMAIN__GETDOMAININFO);
576 }
578 static int flask_getvcpucontext(struct domain *d)
579 {
580 return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
581 DOMAIN__GETVCPUCONTEXT);
582 }
584 static int flask_getvcpuinfo(struct domain *d)
585 {
586 return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
587 DOMAIN__GETVCPUINFO);
588 }
590 static int flask_domain_settime(struct domain *d)
591 {
592 return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__SETTIME);
593 }
595 static int flask_tbufcontrol(void)
596 {
597 return domain_has_xen(current->domain, SECCLASS_XEN);
598 }
600 static int flask_readconsole(uint32_t clear)
601 {
602 u32 perms = XEN__READCONSOLE;
604 if ( clear )
605 perms |= XEN__CLEARCONSOLE;
607 return domain_has_xen(current->domain, perms);
608 }
610 static int flask_sched_id(void)
611 {
612 return domain_has_xen(current->domain, XEN__SCHEDULER);
613 }
615 static int flask_setdomainmaxmem(struct domain *d)
616 {
617 return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
618 DOMAIN__SETDOMAINMAXMEM);
619 }
621 static int flask_setdomainhandle(struct domain *d)
622 {
623 return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
624 DOMAIN__SETDOMAINHANDLE);
625 }
627 static int flask_setdebugging(struct domain *d)
628 {
629 return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
630 DOMAIN__SETDEBUGGING);
631 }
633 static inline u32 resource_to_perm(uint8_t access)
634 {
635 if ( access )
636 return RESOURCE__ADD;
637 else
638 return RESOURCE__REMOVE;
639 }
641 static int flask_irq_permission(struct domain *d, uint8_t pirq, uint8_t access)
642 {
643 u32 perm;
644 u32 rsid;
645 int rc = -EPERM;
647 struct domain_security_struct *ssec, *tsec;
649 rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE,
650 resource_to_perm(access));
652 if ( rc )
653 return rc;
655 if ( access )
656 perm = RESOURCE__ADD_IRQ;
657 else
658 perm = RESOURCE__REMOVE_IRQ;
660 ssec = current->domain->ssid;
661 tsec = d->ssid;
663 rc = security_pirq_sid(pirq, &rsid);
664 if ( rc )
665 return rc;
667 rc = avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, perm, NULL);
669 if ( rc )
670 return rc;
672 return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE,
673 RESOURCE__USE, NULL);
674 }
676 static int flask_iomem_permission(struct domain *d, unsigned long mfn,
677 uint8_t access)
678 {
679 u32 perm;
680 u32 rsid;
681 int rc = -EPERM;
683 struct domain_security_struct *ssec, *tsec;
685 rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE,
686 resource_to_perm(access));
688 if ( rc )
689 return rc;
691 if ( access )
692 perm = RESOURCE__ADD_IOMEM;
693 else
694 perm = RESOURCE__REMOVE_IOMEM;
696 ssec = current->domain->ssid;
697 tsec = d->ssid;
699 rc = security_iomem_sid(mfn, &rsid);
700 if ( rc )
701 return rc;
703 rc = avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, perm, NULL);
705 if ( rc )
706 return rc;
708 return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE,
709 RESOURCE__USE, NULL);
710 }
712 static int flask_perfcontrol(void)
713 {
714 return domain_has_xen(current->domain, XEN__PERFCONTROL);
715 }
717 #ifdef CONFIG_X86
718 static int flask_shadow_control(struct domain *d, uint32_t op)
719 {
720 u32 perm;
722 switch ( op )
723 {
724 case XEN_DOMCTL_SHADOW_OP_OFF:
725 perm = SHADOW__DISABLE;
726 break;
727 case XEN_DOMCTL_SHADOW_OP_ENABLE:
728 case XEN_DOMCTL_SHADOW_OP_ENABLE_TEST:
729 case XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE:
730 case XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION:
731 case XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION:
732 perm = SHADOW__ENABLE;
733 break;
734 case XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY:
735 case XEN_DOMCTL_SHADOW_OP_PEEK:
736 case XEN_DOMCTL_SHADOW_OP_CLEAN:
737 perm = SHADOW__LOGDIRTY;
738 break;
739 default:
740 return -EPERM;
741 }
743 return domain_has_perm(current->domain, d, SECCLASS_SHADOW, perm);
744 }
746 static int flask_ioport_permission(struct domain *d, uint32_t ioport,
747 uint8_t access)
748 {
749 u32 perm;
750 u32 rsid;
751 int rc = -EPERM;
753 struct domain_security_struct *ssec, *tsec;
755 rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE,
756 resource_to_perm(access));
758 if ( rc )
759 return rc;
761 if ( access )
762 perm = RESOURCE__ADD_IOPORT;
763 else
764 perm = RESOURCE__REMOVE_IOPORT;
766 ssec = current->domain->ssid;
767 tsec = d->ssid;
769 rc = security_ioport_sid(ioport, &rsid);
770 if ( rc )
771 return rc;
773 rc = avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, perm, NULL);
774 if ( rc )
775 return rc;
777 return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE,
778 RESOURCE__USE, NULL);
779 }
781 static int flask_getpageframeinfo(struct page_info *page)
782 {
783 int rc = 0;
784 u32 tsid;
785 struct domain_security_struct *dsec;
787 dsec = current->domain->ssid;
789 rc = get_page_sid(page, &tsid);
790 if ( rc )
791 return rc;
793 return avc_has_perm(dsec->sid, tsid, SECCLASS_MMU, MMU__PAGEINFO, NULL);
794 }
796 static int flask_getmemlist(struct domain *d)
797 {
798 return domain_has_perm(current->domain, d, SECCLASS_MMU, MMU__PAGELIST);
799 }
801 static int flask_hypercall_init(struct domain *d)
802 {
803 return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,
804 DOMAIN__HYPERCALL);
805 }
807 static int flask_hvmcontext(struct domain *d, uint32_t cmd)
808 {
809 u32 perm;
811 switch ( cmd )
812 {
813 case XEN_DOMCTL_sethvmcontext:
814 perm = HVM__SETHVMC;
815 break;
816 case XEN_DOMCTL_gethvmcontext:
817 perm = HVM__GETHVMC;
818 break;
819 default:
820 return -EPERM;
821 }
823 return domain_has_perm(current->domain, d, SECCLASS_HVM, perm);
824 }
826 static int flask_address_size(struct domain *d, uint32_t cmd)
827 {
828 u32 perm;
830 switch ( cmd )
831 {
832 case XEN_DOMCTL_set_address_size:
833 perm = DOMAIN__SETADDRSIZE;
834 break;
835 case XEN_DOMCTL_get_address_size:
836 perm = DOMAIN__GETADDRSIZE;
837 break;
838 default:
839 return -EPERM;
840 }
842 return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm);
843 }
845 static int flask_hvm_param(struct domain *d, unsigned long op)
846 {
847 u32 perm;
849 switch ( op )
850 {
851 case HVMOP_set_param:
852 perm = HVM__SETPARAM;
853 break;
854 case HVMOP_get_param:
855 perm = HVM__GETPARAM;
856 break;
857 default:
858 return -EPERM;
859 }
861 return domain_has_perm(current->domain, d, SECCLASS_HVM, perm);
862 }
864 static int flask_hvm_set_pci_intx_level(struct domain *d)
865 {
866 return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__PCILEVEL);
867 }
869 static int flask_hvm_set_isa_irq_level(struct domain *d)
870 {
871 return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__IRQLEVEL);
872 }
874 static int flask_hvm_set_pci_link_route(struct domain *d)
875 {
876 return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__PCIROUTE);
877 }
879 static int flask_apic(struct domain *d, int cmd)
880 {
881 u32 perm;
883 switch ( cmd )
884 {
885 case PHYSDEVOP_APIC_READ:
886 perm = XEN__READAPIC;
887 break;
888 case PHYSDEVOP_APIC_WRITE:
889 perm = XEN__WRITEAPIC;
890 break;
891 default:
892 return -EPERM;
893 }
895 return domain_has_xen(d, perm);
896 }
898 static int flask_assign_vector(struct domain *d, uint32_t pirq)
899 {
900 u32 psid;
901 struct domain_security_struct *dsec;
902 dsec = d->ssid;
904 if ( security_pirq_sid(pirq, &psid) )
905 return -EPERM;
907 return avc_has_perm(dsec->sid, psid, SECCLASS_EVENT, EVENT__VECTOR, NULL);
908 }
910 static int flask_xen_settime(void)
911 {
912 return domain_has_xen(current->domain, XEN__SETTIME);
913 }
915 static int flask_memtype(uint32_t access)
916 {
917 u32 perm;
919 switch ( access )
920 {
921 case XENPF_add_memtype:
922 perm = XEN__MTRR_ADD;
923 break;
924 case XENPF_del_memtype:
925 perm = XEN__MTRR_DEL;
926 break;
927 case XENPF_read_memtype:
928 perm = XEN__MTRR_READ;
929 break;
930 default:
931 return -EPERM;
932 }
934 return domain_has_xen(current->domain, perm);
935 }
937 static int flask_microcode(void)
938 {
939 return domain_has_xen(current->domain, XEN__MICROCODE);
940 }
942 static int flask_physinfo(void)
943 {
944 return domain_has_xen(current->domain, XEN__PHYSINFO);
945 }
947 static int flask_platform_quirk(uint32_t quirk)
948 {
949 struct domain_security_struct *dsec;
950 dsec = current->domain->ssid;
952 return avc_has_perm(dsec->sid, SECINITSID_XEN, SECCLASS_XEN,
953 XEN__QUIRK, NULL);
954 }
956 static int flask_machine_memory_map(void)
957 {
958 struct domain_security_struct *dsec;
959 dsec = current->domain->ssid;
961 return avc_has_perm(dsec->sid, SECINITSID_XEN, SECCLASS_MMU,
962 MMU__MEMORYMAP, NULL);
963 }
965 static int flask_domain_memory_map(struct domain *d)
966 {
967 return domain_has_perm(current->domain, d, SECCLASS_MMU, MMU__MEMORYMAP);
968 }
970 static int flask_mmu_normal_update(struct domain *d, intpte_t fpte)
971 {
972 int rc = 0;
973 u32 map_perms = MMU__MAP_READ;
974 unsigned long fmfn;
975 struct domain_security_struct *dsec;
976 u32 fsid;
978 dsec = d->ssid;
980 if ( l1e_get_flags(l1e_from_intpte(fpte)) & _PAGE_RW )
981 map_perms |= MMU__MAP_WRITE;
983 fmfn = gmfn_to_mfn(FOREIGNDOM, l1e_get_pfn(l1e_from_intpte(fpte)));
985 rc = get_mfn_sid(fmfn, &fsid);
986 if ( rc )
987 return rc;
989 return avc_has_perm(dsec->sid, fsid, SECCLASS_MMU, map_perms, NULL);
990 }
992 static int flask_mmu_machphys_update(struct domain *d, unsigned long mfn)
993 {
994 int rc = 0;
995 u32 psid;
996 struct domain_security_struct *dsec;
997 dsec = d->ssid;
999 rc = get_mfn_sid(mfn, &psid);
1000 if ( rc )
1001 return rc;
1003 return avc_has_perm(dsec->sid, psid, SECCLASS_MMU, MMU__UPDATEMP, NULL);
1006 static int flask_update_va_mapping(struct domain *d, l1_pgentry_t pte)
1008 int rc = 0;
1009 u32 psid;
1010 u32 map_perms = MMU__MAP_READ;
1011 unsigned long mfn;
1012 struct domain_security_struct *dsec;
1014 dsec = d->ssid;
1016 mfn = gmfn_to_mfn(FOREIGNDOM, l1e_get_pfn(pte));
1017 rc = get_mfn_sid(mfn, &psid);
1018 if ( rc )
1019 return rc;
1021 if ( l1e_get_flags(pte) & _PAGE_RW )
1022 map_perms |= MMU__MAP_WRITE;
1024 return avc_has_perm(dsec->sid, psid, SECCLASS_MMU, map_perms, NULL);
1027 static int flask_add_to_physmap(struct domain *d1, struct domain *d2)
1029 return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__PHYSMAP);
1032 static int flask_remove_from_physmap(struct domain *d1, struct domain *d2)
1034 return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__PHYSMAP);
1036 #endif
1038 long do_flask_op(XEN_GUEST_HANDLE(xsm_op_t) u_flask_op);
1040 static struct xsm_operations flask_ops = {
1041 .security_domaininfo = flask_security_domaininfo,
1042 .setvcpucontext = flask_setvcpucontext,
1043 .pausedomain = flask_pausedomain,
1044 .unpausedomain = flask_unpausedomain,
1045 .resumedomain = flask_resumedomain,
1046 .domain_create = flask_domain_create,
1047 .max_vcpus = flask_max_vcpus,
1048 .destroydomain = flask_destroydomain,
1049 .vcpuaffinity = flask_vcpuaffinity,
1050 .scheduler = flask_scheduler,
1051 .getdomaininfo = flask_getdomaininfo,
1052 .getvcpucontext = flask_getvcpucontext,
1053 .getvcpuinfo = flask_getvcpuinfo,
1054 .domain_settime = flask_domain_settime,
1055 .tbufcontrol = flask_tbufcontrol,
1056 .readconsole = flask_readconsole,
1057 .sched_id = flask_sched_id,
1058 .setdomainmaxmem = flask_setdomainmaxmem,
1059 .setdomainhandle = flask_setdomainhandle,
1060 .setdebugging = flask_setdebugging,
1061 .irq_permission = flask_irq_permission,
1062 .iomem_permission = flask_iomem_permission,
1063 .perfcontrol = flask_perfcontrol,
1065 .evtchn_unbound = flask_evtchn_unbound,
1066 .evtchn_interdomain = flask_evtchn_interdomain,
1067 .evtchn_close_post = flask_evtchn_close_post,
1068 .evtchn_send = flask_evtchn_send,
1069 .evtchn_status = flask_evtchn_status,
1070 .evtchn_reset = flask_evtchn_reset,
1072 .grant_mapref = flask_grant_mapref,
1073 .grant_unmapref = flask_grant_unmapref,
1074 .grant_setup = flask_grant_setup,
1075 .grant_transfer = flask_grant_transfer,
1076 .grant_copy = flask_grant_copy,
1077 .grant_query_size = flask_grant_query_size,
1079 .alloc_security_domain = flask_domain_alloc_security,
1080 .free_security_domain = flask_domain_free_security,
1081 .alloc_security_evtchn = flask_alloc_security_evtchn,
1082 .free_security_evtchn = flask_free_security_evtchn,
1084 .translate_gpfn_list = flask_translate_gpfn_list,
1085 .memory_adjust_reservation = flask_memory_adjust_reservation,
1086 .memory_stat_reservation = flask_memory_stat_reservation,
1087 .memory_pin_page = flask_memory_pin_page,
1089 .console_io = flask_console_io,
1091 .profile = flask_profile,
1093 .kexec = flask_kexec,
1094 .schedop_shutdown = flask_schedop_shutdown,
1096 .__do_xsm_op = do_flask_op,
1098 #ifdef CONFIG_X86
1099 .shadow_control = flask_shadow_control,
1100 .ioport_permission = flask_ioport_permission,
1101 .getpageframeinfo = flask_getpageframeinfo,
1102 .getmemlist = flask_getmemlist,
1103 .hypercall_init = flask_hypercall_init,
1104 .hvmcontext = flask_hvmcontext,
1105 .address_size = flask_address_size,
1106 .hvm_param = flask_hvm_param,
1107 .hvm_set_pci_intx_level = flask_hvm_set_pci_intx_level,
1108 .hvm_set_isa_irq_level = flask_hvm_set_isa_irq_level,
1109 .hvm_set_pci_link_route = flask_hvm_set_pci_link_route,
1110 .apic = flask_apic,
1111 .assign_vector = flask_assign_vector,
1112 .xen_settime = flask_xen_settime,
1113 .memtype = flask_memtype,
1114 .microcode = flask_microcode,
1115 .physinfo = flask_physinfo,
1116 .platform_quirk = flask_platform_quirk,
1117 .machine_memory_map = flask_machine_memory_map,
1118 .domain_memory_map = flask_domain_memory_map,
1119 .mmu_normal_update = flask_mmu_normal_update,
1120 .mmu_machphys_update = flask_mmu_machphys_update,
1121 .update_va_mapping = flask_update_va_mapping,
1122 .add_to_physmap = flask_add_to_physmap,
1123 .remove_from_physmap = flask_remove_from_physmap,
1124 #endif
1125 };
1127 static __init int flask_init(void)
1129 int ret = 0;
1131 if ( !flask_enabled ) {
1132 printk("Flask: Disabled at boot.\n");
1133 return 0;
1136 printk("Flask: Initializing.\n");
1138 avc_init();
1140 original_ops = xsm_ops;
1141 if ( register_xsm(&flask_ops) )
1142 panic("Flask: Unable to register with XSM.\n");
1144 ret = security_load_policy(policy_buffer, policy_size);
1146 if ( flask_enforcing )
1147 printk("Flask: Starting in enforcing mode.\n");
1148 else
1149 printk("Flask: Starting in permissive mode.\n");
1151 return ret;
1154 xsm_initcall(flask_init);