[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge
# HG changeset patch # User Ian Campbell <ijc@xxxxxxxxxxxxxx> # Date 1357907019 0 # Node ID f54b7b1f65eaa222e2d251ea741da6dcb7adbebe # Parent 0b9dfd067b4259e2cb3285f279f369dd7bd2e032 # Parent fe115341b816ed303df06708dded2b58bf0d5f51 merge --- diff -r 0b9dfd067b42 -r f54b7b1f65ea docs/misc/xsm-flask.txt --- a/docs/misc/xsm-flask.txt Fri Jan 11 12:22:30 2013 +0000 +++ b/docs/misc/xsm-flask.txt Fri Jan 11 12:23:39 2013 +0000 @@ -68,9 +68,43 @@ HVM domains with stubdomain device model - dm_dom_t is the device model for a domain with type domHVM_t One disadvantage of using type enforcement to enforce isolation is that a new -type is needed for each group of domains. In addition, it is not possible to -allow isolated_domU_t cannot to create loopback event channels without allowing -two domains of type isolated_domU_t to communicate with one another. +type is needed for each group of domains. The user field can be used to address +this for the most common case of groups that can communicate internally but not +externally; see "Users and roles" below. + +Type transitions +---------------- + +Xen defines a number of operations such as memory mapping that are necessary for +a domain to perform on itself, but are also undesirable to allow a domain to +perform on every other domain of the same label. While it is possible to address +this by only creating one domain per type, this solution significantly limits +the flexibility of the type system. Another method to address this issue is to +duplicate the permission names for every operation that can be performed on the +current domain or on other domains; however, this significantly increases the +necessary number of permissions and complicates the XSM hooks. Instead, this is +addressed by allowing a distinct type to be used for a domain's access to +itself. The same applies for a device model domain's access to its designated +target, allowing the IS_PRIV_FOR checks used in Xen's DAC model to be +implemented in FLASK. + +Upon domain creation (or relabel), a type transition is computed using the +domain's label as the source and target. The result of this computation is used +as the target when the domain accesses itself. In the example policy, this +computed type is the result of appending _self to a domain's type: domU_t_self +for domU_t. If no type transition rule exists, the domain will continue to use +its own label for both the source and target. An AVC message will look like: + + scontext=system_u:system_r:domU_t tcontext=system_u:system_r:domU_t_self + +A similar type transition is done when a device model domain is associated with +its target using the set_target operation. The transition is computed with the +target domain as the source and the device model domain as the target: this +ordering was chosen in order to preserve the original label for the target when +no type transition rule exists. In the example policy, these computed types are +the result of appending _target to the domain. + +Type transitions are also used to compute the labels of event channels. Users and roles --------------- @@ -84,7 +118,8 @@ the customer_1 user. Access control rules involving users and roles are defined in the policy constraints file (tools/flask/policy/policy/constraints). The example policy provides constraints that prevent different users from communicating using -grants or event channels, while still allowing communication with dom0. +grants or event channels, while still allowing communication with the system_u +user where dom0 resides. Resource Policy --------------- diff -r 0b9dfd067b42 -r f54b7b1f65ea tools/flask/policy/policy/flask/access_vectors --- a/tools/flask/policy/policy/flask/access_vectors Fri Jan 11 12:22:30 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,178 +0,0 @@ -# -# Define the access vectors. -# -# class class_name { permission_name ... } - -class xen -{ - scheduler - settime - tbufcontrol - readconsole - clearconsole - perfcontrol - mtrr_add - mtrr_del - mtrr_read - microcode - physinfo - quirk - writeconsole - readapic - writeapic - privprofile - nonprivprofile - kexec - firmware - sleep - frequency - getidle - debug - getcpuinfo - heap - pm_op - mca_op - lockprof - cpupool_op - sched_op -} - -class domain -{ - setvcpucontext - pause - unpause - resume - create - transition - max_vcpus - destroy - setvcpuaffinity - getvcpuaffinity - scheduler - getdomaininfo - getvcpuinfo - getvcpucontext - setdomainmaxmem - setdomainhandle - setdebugging - hypercall - settime - set_target - shutdown - setaddrsize - getaddrsize - trigger - getextvcpucontext - setextvcpucontext - getvcpuextstate - setvcpuextstate - getpodtarget - setpodtarget - set_misc_info - set_virq_handler -} - -class domain2 -{ - relabelfrom - relabelto - relabelself -} - -class hvm -{ - sethvmc - gethvmc - setparam - getparam - pcilevel - irqlevel - pciroute - bind_irq - cacheattr - trackdirtyvram - hvmctl - mem_event - mem_sharing -} - -class event -{ - bind - send - status - notify - create - reset -} - -class grant -{ - map_read - map_write - unmap - transfer - setup - copy - query -} - -class mmu -{ - map_read - map_write - pageinfo - pagelist - adjust - stat - translategp - updatemp - physmap - pinpage - mfnlist - memorymap - remote_remap -} - -class shadow -{ - disable - enable - logdirty -} - -class resource -{ - add - remove - use - add_irq - remove_irq - add_ioport - remove_ioport - add_iomem - remove_iomem - stat_device - add_device - remove_device - plug - unplug - setup -} - -class security -{ - compute_av - compute_create - compute_member - check_context - load_policy - compute_relabel - compute_user - setenforce - setbool - setsecparam - add_ocontext - del_ocontext -} diff -r 0b9dfd067b42 -r f54b7b1f65ea tools/flask/policy/policy/flask/initial_sids --- a/tools/flask/policy/policy/flask/initial_sids Fri Jan 11 12:22:30 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -# FLASK - -# -# Define initial security identifiers -# -sid xen -sid dom0 -sid domio -sid domxen -sid unlabeled -sid security -sid ioport -sid iomem -sid irq -sid device -# FLASK diff -r 0b9dfd067b42 -r f54b7b1f65ea tools/flask/policy/policy/flask/mkaccess_vector.sh --- a/tools/flask/policy/policy/flask/mkaccess_vector.sh Fri Jan 11 12:22:30 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,138 +0,0 @@ -#!/bin/sh - -# - -# FLASK - -set -e - -awk=$1 -shift - -# output files -av_permissions="include/av_permissions.h" -av_perm_to_string="include/av_perm_to_string.h" - -cat $* | $awk " -BEGIN { - outfile = \"$av_permissions\" - avpermfile = \"$av_perm_to_string\" - "' - nextstate = "COMMON_OR_AV"; - printf("/* This file is automatically generated. Do not edit. */\n") > outfile; - printf("/* This file is automatically generated. Do not edit. */\n") > avpermfile; -; - } -/^[ \t]*#/ { - next; - } -$1 == "class" { - if (nextstate != "COMMON_OR_AV" && - nextstate != "CLASS_OR_CLASS-OPENBRACKET") - { - printf("Parse error: Unexpected class definition on line %d\n", NR); - next; - } - - tclass = $2; - - if (tclass in av_defined) - { - printf("Duplicate access vector definition for %s on line %d\n", tclass, NR); - next; - } - av_defined[tclass] = 1; - - permission = 1; - - nextstate = "INHERITS_OR_CLASS-OPENBRACKET"; - next; - } -$1 == "{" { - if (nextstate != "INHERITS_OR_CLASS-OPENBRACKET" && - nextstate != "CLASS_OR_CLASS-OPENBRACKET" && - nextstate != "COMMON-OPENBRACKET") - { - printf("Parse error: Unexpected { on line %d\n", NR); - next; - } - - if (nextstate == "INHERITS_OR_CLASS-OPENBRACKET") - nextstate = "CLASS-CLOSEBRACKET"; - - if (nextstate == "CLASS_OR_CLASS-OPENBRACKET") - nextstate = "CLASS-CLOSEBRACKET"; - - if (nextstate == "COMMON-OPENBRACKET") - nextstate = "COMMON-CLOSEBRACKET"; - } -/[a-z][a-z_]*/ { - if (nextstate != "COMMON-CLOSEBRACKET" && - nextstate != "CLASS-CLOSEBRACKET") - { - printf("Parse error: Unexpected symbol %s on line %d\n", $1, NR); - next; - } - - if (nextstate == "COMMON-CLOSEBRACKET") - { - if ((common_name,$1) in common_perms) - { - printf("Duplicate permission %s for common %s on line %d.\n", $1, common_name, NR); - next; - } - - common_perms[common_name,$1] = permission; - - printf("#define COMMON_%s__%s", toupper(common_name), toupper($1)) > outfile; - - printf(" S_(\"%s\")\n", $1) > cpermfile; - } - else - { - if ((tclass,$1) in av_perms) - { - printf("Duplicate permission %s for %s on line %d.\n", $1, tclass, NR); - next; - } - - av_perms[tclass,$1] = permission; - - printf("#define %s__%s", toupper(tclass), toupper($1)) > outfile; - - printf(" S_(SECCLASS_%s, %s__%s, \"%s\")\n", toupper(tclass), toupper(tclass), toupper($1), $1) > avpermfile; - } - - spaces = 40 - (length($1) + length(tclass)); - if (spaces < 1) - spaces = 1; - - for (i = 0; i < spaces; i++) - printf(" ") > outfile; - printf("0x%08xUL\n", permission) > outfile; - permission = permission * 2; - } -$1 == "}" { - if (nextstate != "CLASS-CLOSEBRACKET" && - nextstate != "COMMON-CLOSEBRACKET") - { - printf("Parse error: Unexpected } on line %d\n", NR); - next; - } - - if (nextstate == "COMMON-CLOSEBRACKET") - { - common_base[common_name] = permission; - printf("TE_(common_%s_perm_to_string)\n\n", common_name) > cpermfile; - } - - printf("\n") > outfile; - - nextstate = "COMMON_OR_AV"; - } -END { - if (nextstate != "COMMON_OR_AV" && nextstate != "CLASS_OR_CLASS-OPENBRACKET") - printf("Parse error: Unexpected end of file\n"); - - }' - -# FLASK diff -r 0b9dfd067b42 -r f54b7b1f65ea tools/flask/policy/policy/flask/mkflask.sh --- a/tools/flask/policy/policy/flask/mkflask.sh Fri Jan 11 12:22:30 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ -#!/bin/sh - -# - -# FLASK - -set -e - -awk=$1 -shift 1 - -# output file -output_file="include/flask.h" -debug_file="include/class_to_string.h" -debug_file2="include/initial_sid_to_string.h" - -cat $* | $awk " -BEGIN { - outfile = \"$output_file\" - debugfile = \"$debug_file\" - debugfile2 = \"$debug_file2\" - "' - nextstate = "CLASS"; - - printf("/* This file is automatically generated. Do not edit. */\n") > outfile; - - printf("#ifndef _SELINUX_FLASK_H_\n") > outfile; - printf("#define _SELINUX_FLASK_H_\n") > outfile; - printf("\n/*\n * Security object class definitions\n */\n") > outfile; - printf("/* This file is automatically generated. Do not edit. */\n") > debugfile; - printf("/*\n * Security object class definitions\n */\n") > debugfile; - printf(" S_(\"null\")\n") > debugfile; - printf("/* This file is automatically generated. Do not edit. */\n") > debugfile2; - printf("static char *initial_sid_to_string[] =\n{\n") > debugfile2; - printf(" \"null\",\n") > debugfile2; - } -/^[ \t]*#/ { - next; - } -$1 == "class" { - if (nextstate != "CLASS") - { - printf("Parse error: Unexpected class definition on line %d\n", NR); - next; - } - - if ($2 in class_found) - { - printf("Duplicate class definition for %s on line %d.\n", $2, NR); - next; - } - class_found[$2] = 1; - - class_value++; - - printf("#define SECCLASS_%s", toupper($2)) > outfile; - for (i = 0; i < 40 - length($2); i++) - printf(" ") > outfile; - printf("%d\n", class_value) > outfile; - - printf(" S_(\"%s\")\n", $2) > debugfile; - } -$1 == "sid" { - if (nextstate == "CLASS") - { - nextstate = "SID"; - printf("\n/*\n * Security identifier indices for initial entities\n */\n") > outfile; - } - - if ($2 in sid_found) - { - printf("Duplicate SID definition for %s on line %d.\n", $2, NR); - next; - } - sid_found[$2] = 1; - sid_value++; - - printf("#define SECINITSID_%s", toupper($2)) > outfile; - for (i = 0; i < 37 - length($2); i++) - printf(" ") > outfile; - printf("%d\n", sid_value) > outfile; - printf(" \"%s\",\n", $2) > debugfile2; - } -END { - if (nextstate != "SID") - printf("Parse error: Unexpected end of file\n"); - - printf("\n#define SECINITSID_NUM") > outfile; - for (i = 0; i < 34; i++) - printf(" ") > outfile; - printf("%d\n", sid_value) > outfile; - printf("\n#endif\n") > outfile; - printf("};\n\n") > debugfile2; - }' - -# FLASK diff -r 0b9dfd067b42 -r f54b7b1f65ea tools/flask/policy/policy/flask/security_classes --- a/tools/flask/policy/policy/flask/security_classes Fri Jan 11 12:22:30 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -# FLASK - -# -# Define the security object classes -# - -# Classes marked as userspace are classes -# for userspace object managers - -class xen -class domain -class domain2 -class hvm -class mmu -class resource -class shadow -class event -class grant -class security - -# FLASK diff -r 0b9dfd067b42 -r f54b7b1f65ea tools/flask/policy/policy/modules/xen/xen.if --- a/tools/flask/policy/policy/modules/xen/xen.if Fri Jan 11 12:22:30 2013 +0000 +++ b/tools/flask/policy/policy/modules/xen/xen.if Fri Jan 11 12:23:39 2013 +0000 @@ -5,15 +5,35 @@ # Domain creation and setup # ################################################################################ +define(`declare_domain_common', ` + allow $1 $2:grant { query setup }; + allow $1 $2:mmu { adjust physmap map_read map_write stat pinpage updatemp mmuext_op }; + allow $1 $2:hvm { getparam setparam }; +') + # declare_domain(type, attrs...) -# Declare a type as a domain type, and allow basic domain setup +# Declare a domain type, along with associated _self and _channel types +# Allow the domain to perform basic operations on itself define(`declare_domain', ` type $1, domain_type`'ifelse(`$#', `1', `', `,shift($@)'); + type $1_self, domain_type, domain_self_type; + type_transition $1 $1:domain $1_self; type $1_channel, event_type; type_transition $1 domain_type:event $1_channel; - allow $1 $1:grant { query setup }; - allow $1 $1:mmu { adjust physmap map_read map_write stat pinpage }; - allow $1 $1:hvm { getparam setparam }; + declare_domain_common($1, $1_self) +') + +# declare_singleton_domain(type, attrs...) +# Declare a domain type and associated _channel types. +# Note: Because the domain can perform basic operations on itself and any +# other domain of the same type, this constructor should be used for types +# containing at most one domain. This is not enforced by policy. +define(`declare_singleton_domain', ` + type $1, domain_type`'ifelse(`$#', `1', `', `,shift($@)'); + define(`$1_self', `$1') + type $1_channel, event_type; + type_transition $1 domain_type:event $1_channel; + declare_domain_common($1, $1) ') # declare_build_label(type) @@ -27,11 +47,12 @@ define(`declare_build_label', ` define(`create_domain_common', ` allow $1 $2:domain { create max_vcpus setdomainmaxmem setaddrsize getdomaininfo hypercall setvcpucontext setextvcpucontext - scheduler getvcpuinfo getvcpuextstate getaddrsize + getscheduler getvcpuinfo getvcpuextstate getaddrsize getvcpuaffinity setvcpuaffinity }; + allow $1 $2:domain2 { set_cpuid settsc setscheduler }; allow $1 $2:security check_context; allow $1 $2:shadow enable; - allow $1 $2:mmu {map_read map_write adjust memorymap physmap pinpage}; + allow $1 $2:mmu { map_read map_write adjust memorymap physmap pinpage mmuext_op }; allow $1 $2:grant setup; allow $1 $2:hvm { cacheattr getparam hvmctl irqlevel pciroute sethvmc setparam pcilevel trackdirtyvram }; ') @@ -50,6 +71,7 @@ define(`create_domain_build_label', ` allow $1 $2_channel:event create; allow $1 $2_building:domain2 relabelfrom; allow $1 $2:domain2 relabelto; + allow $2_building $2:domain transition; ') # manage_domain(priv, target) @@ -57,7 +79,7 @@ define(`create_domain_build_label', ` define(`manage_domain', ` allow $1 $2:domain { getdomaininfo getvcpuinfo getvcpuaffinity getaddrsize pause unpause trigger shutdown destroy - setvcpuaffinity setdomainmaxmem }; + setvcpuaffinity setdomainmaxmem getscheduler }; ') # migrate_domain_out(priv, target) @@ -67,6 +89,7 @@ define(`migrate_domain_out', ` allow $1 $2:hvm { gethvmc getparam irqlevel }; allow $1 $2:mmu { stat pageinfo map_read }; allow $1 $2:domain { getaddrsize getvcpucontext getextvcpucontext getvcpuextstate pause destroy }; + allow $1 $2:domain2 gettsc; ') ################################################################################ @@ -99,20 +122,36 @@ define(`domain_comms', ` ') # domain_self_comms(domain) -# Allow a domain types to communicate with others of its type using grants -# and event channels (this includes event channels to DOMID_SELF) +# Allow a non-singleton domain type to communicate with itself using grants +# and event channels define(`domain_self_comms', ` - create_channel($1, $1, $1_channel) - allow $1 $1:grant { map_read map_write copy unmap }; + create_channel($1, $1_self, $1_channel) + allow $1 $1_self:grant { map_read map_write copy unmap }; ') # device_model(dm_dom, hvm_dom) # Define how a device model domain interacts with its target define(`device_model', ` - domain_comms($1, $2) - allow $1 $2:domain { set_target shutdown }; - allow $1 $2:mmu { map_read map_write adjust physmap }; - allow $1 $2:hvm { getparam setparam trackdirtyvram hvmctl irqlevel pciroute }; + type $2_target, domain_type, domain_target_type; + type_transition $2 $1:domain $2_target; + allow $1 $2:domain set_target; + + type_transition $2_target domain_type:event $2_channel; + create_channel($1, $2_target, $1_channel) + create_channel($2, $1, $2_channel) + allow $1 $2_channel:event create; + + allow $1 $2_target:domain shutdown; + allow $1 $2_target:mmu { map_read map_write adjust physmap }; + allow $1 $2_target:hvm { getparam setparam trackdirtyvram hvmctl irqlevel pciroute cacheattr send_irq }; +') + +# make_device_model(priv, dm_dom, hvm_dom) +# Allow creation of a device model and HVM domain pair +define(`make_device_model', ` + device_model($2, $3) + allow $1 $2:domain2 make_priv_for; + allow $1 $3:domain2 set_as_target; ') ################################################################################ # @@ -123,8 +162,9 @@ define(`device_model', ` # use_device(domain, device) # Allow a device to be used by a domain define(`use_device', ` + allow $1 $1_self:mmu exchange; allow $1 $2:resource use; - allow $1 $2:mmu { map_read map_write }; + allow $1 domio_t:mmu { map_read map_write }; ') # admin_device(domain, device) diff -r 0b9dfd067b42 -r f54b7b1f65ea tools/flask/policy/policy/modules/xen/xen.te --- a/tools/flask/policy/policy/modules/xen/xen.te Fri Jan 11 12:22:30 2013 +0000 +++ b/tools/flask/policy/policy/modules/xen/xen.te Fri Jan 11 12:23:39 2013 +0000 @@ -8,6 +8,8 @@ ################################################################################ attribute xen_type; attribute domain_type; +attribute domain_self_type; +attribute domain_target_type; attribute resource_type; attribute event_type; attribute mls_priv; @@ -25,12 +27,12 @@ attribute mls_priv; type xen_t, xen_type, mls_priv; # Domain 0 -declare_domain(dom0_t, mls_priv); +declare_singleton_domain(dom0_t, mls_priv); -# Untracked I/O memory (pseudo-domain) +# I/O memory (DOMID_IO pseudo-domain) type domio_t, xen_type; -# Xen heap (pseudo-domain) +# Xen heap (DOMID_XEN pseudo-domain) type domxen_t, xen_type; # Unlabeled objects @@ -53,8 +55,8 @@ type device_t, resource_type; # ################################################################################ allow dom0_t xen_t:xen { kexec readapic writeapic mtrr_read mtrr_add mtrr_del - scheduler physinfo heap quirk readconsole writeconsole settime getcpuinfo - microcode cpupool_op sched_op pm_op }; + physinfo heap quirk readconsole writeconsole settime getcpuinfo + microcode cpupool_op pm_op tmem_control getscheduler setscheduler }; allow dom0_t xen_t:mmu { memorymap }; allow dom0_t security_t:security { check_context compute_av compute_create compute_member load_policy compute_relabel compute_user setenforce @@ -67,12 +69,14 @@ admin_device(dom0_t, device_t) admin_device(dom0_t, irq_t) admin_device(dom0_t, ioport_t) admin_device(dom0_t, iomem_t) -allow dom0_t domio_t:mmu { map_read map_write }; -domain_self_comms(dom0_t) +domain_comms(dom0_t, dom0_t) auditallow dom0_t security_t:security { load_policy setenforce setbool }; +# Allow all domains to use (unprivileged parts of) the tmem hypercall +allow domain_type xen_t:xen tmem_op; + ############################################################################### # # Domain creation @@ -84,11 +88,14 @@ domain_self_comms(domU_t) create_domain(dom0_t, domU_t) manage_domain(dom0_t, domU_t) domain_comms(dom0_t, domU_t) +domain_comms(domU_t, domU_t) +domain_self_comms(domU_t) declare_domain(isolated_domU_t) create_domain(dom0_t, isolated_domU_t) manage_domain(dom0_t, isolated_domU_t) domain_comms(dom0_t, isolated_domU_t) +domain_self_comms(isolated_domU_t) # Declare a boolean that denies creation of prot_domU_t domains gen_bool(prot_doms_locked, false) @@ -98,6 +105,8 @@ if (!prot_doms_locked) { } domain_comms(dom0_t, prot_domU_t) domain_comms(domU_t, prot_domU_t) +domain_comms(prot_domU_t, prot_domU_t) +domain_self_comms(prot_domU_t) # domHVM_t is meant to be paired with a qemu-dm stub domain of type dm_dom_t declare_domain(domHVM_t) @@ -110,7 +119,7 @@ declare_domain(dm_dom_t) create_domain(dom0_t, dm_dom_t) manage_domain(dom0_t, dm_dom_t) domain_comms(dom0_t, dm_dom_t) -device_model(dm_dom_t, domHVM_t) +make_device_model(dom0_t, dm_dom_t, domHVM_t) # nomigrate_t must be built via the nomigrate_t_building label; once built, # dom0 cannot read its memory. diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/arch/x86/acpi/power.c --- a/xen/arch/x86/acpi/power.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/arch/x86/acpi/power.c Fri Jan 11 12:23:39 2013 +0000 @@ -239,7 +239,7 @@ static long enter_state_helper(void *dat */ int acpi_enter_sleep(struct xenpf_enter_acpi_sleep *sleep) { - if ( !IS_PRIV(current->domain) || !acpi_sinfo.pm1a_cnt_blk.address ) + if ( !acpi_sinfo.pm1a_cnt_blk.address ) return -EPERM; /* Sanity check */ diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/arch/x86/cpu/mcheck/mce.c --- a/xen/arch/x86/cpu/mcheck/mce.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/arch/x86/cpu/mcheck/mce.c Fri Jan 11 12:23:39 2013 +0000 @@ -1293,10 +1293,7 @@ long do_mca(XEN_GUEST_HANDLE_PARAM(xen_m struct xen_mc_msrinject *mc_msrinject; struct xen_mc_mceinject *mc_mceinject; - if (!IS_PRIV(v->domain) ) - return x86_mcerr(NULL, -EPERM); - - ret = xsm_do_mca(); + ret = xsm_do_mca(XSM_PRIV); if ( ret ) return x86_mcerr(NULL, ret); diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/arch/x86/domctl.c --- a/xen/arch/x86/domctl.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/arch/x86/domctl.c Fri Jan 11 12:23:39 2013 +0000 @@ -77,7 +77,7 @@ long arch_do_domctl( if ( np == 0 ) ret = 0; - else if ( xsm_ioport_permission(d, fp, fp + np - 1, allow) ) + else if ( xsm_ioport_permission(XSM_HOOK, d, fp, fp + np - 1, allow) ) ret = -EPERM; else if ( allow ) ret = ioports_permit_access(d, fp, fp + np - 1); @@ -97,10 +97,6 @@ long arch_do_domctl( page = mfn_to_page(mfn); - ret = xsm_getpageframeinfo(d); - if ( ret ) - break; - if ( likely(get_page(page, d)) ) { ret = 0; @@ -141,10 +137,6 @@ long arch_do_domctl( struct page_info *page; xen_pfn_t *arr; - ret = xsm_getpageframeinfo(d); - if ( ret ) - break; - if ( unlikely(num > 1024) || unlikely(num != domctl->u.getpageframeinfo3.num) ) { @@ -239,10 +231,6 @@ long arch_do_domctl( int num = domctl->u.getpageframeinfo2.num; uint32_t *arr32; - ret = xsm_getpageframeinfo(d); - if ( ret ) - break; - if ( unlikely(num > 1024) ) { ret = -E2BIG; @@ -334,10 +322,6 @@ long arch_do_domctl( uint64_t mfn; struct page_info *page; - ret = xsm_getmemlist(d); - if ( ret ) - break; - if ( unlikely(d->is_dying) ) { ret = -EINVAL; break; @@ -373,10 +357,6 @@ long arch_do_domctl( struct page_info *page; void *hypercall_page; - ret = xsm_hypercall_init(d); - if ( ret ) - break; - page = get_page_from_gfn(d, gmfn, NULL, P2M_ALLOC); ret = -EACCES; @@ -401,10 +381,6 @@ long arch_do_domctl( { struct hvm_domain_context c = { .size = domctl->u.hvmcontext.size }; - ret = xsm_hvmcontext(d, domctl->cmd); - if ( ret ) - goto sethvmcontext_out; - ret = -EINVAL; if ( !is_hvm_domain(d) ) goto sethvmcontext_out; @@ -431,10 +407,6 @@ long arch_do_domctl( { struct hvm_domain_context c = { 0 }; - ret = xsm_hvmcontext(d, domctl->cmd); - if ( ret ) - goto gethvmcontext_out; - ret = -EINVAL; if ( !is_hvm_domain(d) ) goto gethvmcontext_out; @@ -477,10 +449,6 @@ long arch_do_domctl( case XEN_DOMCTL_gethvmcontext_partial: { - ret = xsm_hvmcontext(d, domctl->cmd); - if ( ret ) - break; - ret = -EINVAL; if ( !is_hvm_domain(d) ) break; @@ -496,10 +464,6 @@ long arch_do_domctl( case XEN_DOMCTL_set_address_size: { - ret = xsm_address_size(d, domctl->cmd); - if ( ret ) - break; - switch ( domctl->u.address_size.size ) { case 32: @@ -517,10 +481,6 @@ long arch_do_domctl( case XEN_DOMCTL_get_address_size: { - ret = xsm_address_size(d, domctl->cmd); - if ( ret ) - break; - domctl->u.address_size.size = is_pv_32on64_domain(d) ? 32 : BITS_PER_LONG; @@ -531,10 +491,6 @@ long arch_do_domctl( case XEN_DOMCTL_set_machine_address_size: { - ret = xsm_machine_address_size(d, domctl->cmd); - if ( ret ) - break; - ret = -EBUSY; if ( d->tot_pages > 0 ) break; @@ -547,10 +503,6 @@ long arch_do_domctl( case XEN_DOMCTL_get_machine_address_size: { - ret = xsm_machine_address_size(d, domctl->cmd); - if ( ret ) - break; - domctl->u.address_size.size = d->arch.physaddr_bitsize; ret = 0; @@ -562,10 +514,6 @@ long arch_do_domctl( { struct vcpu *v; - ret = xsm_sendtrigger(d); - if ( ret ) - break; - ret = -EINVAL; if ( domctl->u.sendtrigger.vcpu >= MAX_VIRT_CPUS ) break; @@ -623,7 +571,7 @@ long arch_do_domctl( if ( !is_hvm_domain(d) ) break; - ret = xsm_bind_pt_irq(d, bind); + ret = xsm_bind_pt_irq(XSM_HOOK, d, bind); if ( ret ) break; @@ -656,7 +604,7 @@ long arch_do_domctl( !irq_access_permitted(current->domain, bind->machine_irq) ) break; - ret = xsm_unbind_pt_irq(d, bind); + ret = xsm_unbind_pt_irq(XSM_HOOK, d, bind); if ( ret ) break; @@ -691,7 +639,7 @@ long arch_do_domctl( !iomem_access_permitted(current->domain, mfn, mfn + nr_mfns - 1) ) break; - ret = xsm_iomem_mapping(d, mfn, mfn + nr_mfns - 1, add); + ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn + nr_mfns - 1, add); if ( ret ) break; @@ -769,7 +717,7 @@ long arch_do_domctl( !ioports_access_permitted(current->domain, fmp, fmp + np - 1) ) break; - ret = xsm_ioport_mapping(d, fmp, fmp + np - 1, add); + ret = xsm_ioport_mapping(XSM_HOOK, d, fmp, fmp + np - 1, add); if ( ret ) break; @@ -832,10 +780,6 @@ long arch_do_domctl( case XEN_DOMCTL_pin_mem_cacheattr: { - ret = xsm_pin_mem_cacheattr(d); - if ( ret ) - break; - ret = hvm_set_mem_pinned_cacheattr( d, domctl->u.pin_mem_cacheattr.start, domctl->u.pin_mem_cacheattr.end, @@ -851,10 +795,6 @@ long arch_do_domctl( evc = &domctl->u.ext_vcpucontext; - ret = xsm_ext_vcpucontext(d, domctl->cmd); - if ( ret ) - break; - ret = -ESRCH; if ( (evc->vcpu >= d->max_vcpus) || ((v = d->vcpu[evc->vcpu]) == NULL) ) @@ -1118,10 +1058,6 @@ long arch_do_domctl( evc = &domctl->u.vcpuextstate; - ret = xsm_vcpuextstate(d, domctl->cmd); - if ( ret ) - goto vcpuextstate_out; - ret = -ESRCH; if ( (evc->vcpu >= d->max_vcpus) || ((v = d->vcpu[evc->vcpu]) == NULL) ) @@ -1223,19 +1159,15 @@ long arch_do_domctl( case XEN_DOMCTL_mem_event_op: { - ret = xsm_mem_event(d); - if ( !ret ) - ret = mem_event_domctl(d, &domctl->u.mem_event_op, - guest_handle_cast(u_domctl, void)); + ret = mem_event_domctl(d, &domctl->u.mem_event_op, + guest_handle_cast(u_domctl, void)); copyback = 1; } break; case XEN_DOMCTL_mem_sharing_op: { - ret = xsm_mem_sharing(d); - if ( !ret ) - ret = mem_sharing_domctl(d, &domctl->u.mem_sharing_op); + ret = mem_sharing_domctl(d, &domctl->u.mem_sharing_op); } break; @@ -1265,11 +1197,9 @@ long arch_do_domctl( if ( current->domain == d ) break; - ret = xsm_mem_event(d); - if ( !ret ) { - p2m = p2m_get_hostp2m(d); - p2m->access_required = domctl->u.access_required.access_required; - } + ret = 0; + p2m = p2m_get_hostp2m(d); + p2m->access_required = domctl->u.access_required.access_required; } break; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/arch/x86/hvm/hvm.c Fri Jan 11 12:23:39 2013 +0000 @@ -3388,7 +3388,7 @@ static int hvmop_set_pci_intx_level( if ( (op.domain > 0) || (op.bus > 0) || (op.device > 31) || (op.intx > 3) ) return -EINVAL; - rc = rcu_lock_remote_target_domain_by_id(op.domid, &d); + rc = rcu_lock_remote_domain_by_id(op.domid, &d); if ( rc != 0 ) return rc; @@ -3396,7 +3396,7 @@ static int hvmop_set_pci_intx_level( if ( !is_hvm_domain(d) ) goto out; - rc = xsm_hvm_set_pci_intx_level(d); + rc = xsm_hvm_set_pci_intx_level(XSM_DM_PRIV, d); if ( rc ) goto out; @@ -3555,7 +3555,7 @@ static int hvmop_set_isa_irq_level( if ( op.isa_irq > 15 ) return -EINVAL; - rc = rcu_lock_remote_target_domain_by_id(op.domid, &d); + rc = rcu_lock_remote_domain_by_id(op.domid, &d); if ( rc != 0 ) return rc; @@ -3563,7 +3563,7 @@ static int hvmop_set_isa_irq_level( if ( !is_hvm_domain(d) ) goto out; - rc = xsm_hvm_set_isa_irq_level(d); + rc = xsm_hvm_set_isa_irq_level(XSM_DM_PRIV, d); if ( rc ) goto out; @@ -3599,7 +3599,7 @@ static int hvmop_set_pci_link_route( if ( (op.link > 3) || (op.isa_irq > 15) ) return -EINVAL; - rc = rcu_lock_remote_target_domain_by_id(op.domid, &d); + rc = rcu_lock_remote_domain_by_id(op.domid, &d); if ( rc != 0 ) return rc; @@ -3607,7 +3607,7 @@ static int hvmop_set_pci_link_route( if ( !is_hvm_domain(d) ) goto out; - rc = xsm_hvm_set_pci_link_route(d); + rc = xsm_hvm_set_pci_link_route(XSM_DM_PRIV, d); if ( rc ) goto out; @@ -3629,7 +3629,7 @@ static int hvmop_inject_msi( if ( copy_from_guest(&op, uop, 1) ) return -EFAULT; - rc = rcu_lock_remote_target_domain_by_id(op.domid, &d); + rc = rcu_lock_remote_domain_by_id(op.domid, &d); if ( rc != 0 ) return rc; @@ -3637,7 +3637,7 @@ static int hvmop_inject_msi( if ( !is_hvm_domain(d) ) goto out; - rc = xsm_hvm_inject_msi(d); + rc = xsm_hvm_inject_msi(XSM_DM_PRIV, d); if ( rc ) goto out; @@ -3726,15 +3726,15 @@ long do_hvm_op(unsigned long op, XEN_GUE if ( a.index >= HVM_NR_PARAMS ) return -EINVAL; - rc = rcu_lock_target_domain_by_id(a.domid, &d); - if ( rc != 0 ) - return rc; + d = rcu_lock_domain_by_any_id(a.domid); + if ( d == NULL ) + return -ESRCH; rc = -EINVAL; if ( !is_hvm_domain(d) ) goto param_fail; - rc = xsm_hvm_param(d, op); + rc = xsm_hvm_param(XSM_TARGET, d, op); if ( rc ) goto param_fail; @@ -3972,7 +3972,7 @@ long do_hvm_op(unsigned long op, XEN_GUE if ( copy_from_guest(&a, arg, 1) ) return -EFAULT; - rc = rcu_lock_remote_target_domain_by_id(a.domid, &d); + rc = rcu_lock_remote_domain_by_id(a.domid, &d); if ( rc != 0 ) return rc; @@ -3983,7 +3983,7 @@ long do_hvm_op(unsigned long op, XEN_GUE if ( a.nr > GB(1) >> PAGE_SHIFT ) goto param_fail2; - rc = xsm_hvm_param(d, op); + rc = xsm_hvm_param(XSM_TARGET, d, op); if ( rc ) goto param_fail2; @@ -4013,7 +4013,7 @@ long do_hvm_op(unsigned long op, XEN_GUE if ( copy_from_guest(&a, arg, 1) ) return -EFAULT; - rc = rcu_lock_remote_target_domain_by_id(a.domid, &d); + rc = rcu_lock_remote_domain_by_id(a.domid, &d); if ( rc != 0 ) return rc; @@ -4021,7 +4021,7 @@ long do_hvm_op(unsigned long op, XEN_GUE if ( !is_hvm_domain(d) ) goto param_fail3; - rc = xsm_hvm_param(d, op); + rc = xsm_hvm_param(XSM_TARGET, d, op); if ( rc ) goto param_fail3; @@ -4078,11 +4078,11 @@ long do_hvm_op(unsigned long op, XEN_GUE if ( copy_from_guest(&a, arg, 1) ) return -EFAULT; - rc = rcu_lock_target_domain_by_id(a.domid, &d); - if ( rc != 0 ) - return rc; - - rc = xsm_hvm_param(d, op); + d = rcu_lock_domain_by_any_id(a.domid); + if ( d == NULL ) + return -ESRCH; + + rc = xsm_hvm_param(XSM_TARGET, d, op); if ( rc ) goto param_fail_getmemtype; @@ -4128,7 +4128,7 @@ long do_hvm_op(unsigned long op, XEN_GUE if ( copy_from_guest(&a, arg, 1) ) return -EFAULT; - rc = rcu_lock_remote_target_domain_by_id(a.domid, &d); + rc = rcu_lock_remote_domain_by_id(a.domid, &d); if ( rc != 0 ) return rc; @@ -4136,7 +4136,7 @@ long do_hvm_op(unsigned long op, XEN_GUE if ( !is_hvm_domain(d) ) goto param_fail4; - rc = xsm_hvm_param(d, op); + rc = xsm_hvm_param(XSM_TARGET, d, op); if ( rc ) goto param_fail4; @@ -4221,7 +4221,7 @@ long do_hvm_op(unsigned long op, XEN_GUE if ( copy_from_guest(&a, arg, 1) ) return -EFAULT; - rc = rcu_lock_remote_target_domain_by_id(a.domid, &d); + rc = rcu_lock_remote_domain_by_id(a.domid, &d); if ( rc != 0 ) return rc; @@ -4229,7 +4229,7 @@ long do_hvm_op(unsigned long op, XEN_GUE if ( !is_hvm_domain(d) ) goto param_fail5; - rc = xsm_hvm_param(d, op); + rc = xsm_hvm_param(XSM_TARGET, d, op); if ( rc ) goto param_fail5; @@ -4256,7 +4256,7 @@ long do_hvm_op(unsigned long op, XEN_GUE if ( copy_from_guest(&a, arg, 1) ) return -EFAULT; - rc = rcu_lock_remote_target_domain_by_id(a.domid, &d); + rc = rcu_lock_remote_domain_by_id(a.domid, &d); if ( rc != 0 ) return rc; @@ -4264,7 +4264,7 @@ long do_hvm_op(unsigned long op, XEN_GUE if ( !is_hvm_domain(d) ) goto param_fail6; - rc = xsm_hvm_param(d, op); + rc = xsm_hvm_param(XSM_TARGET, d, op); if ( rc ) goto param_fail6; @@ -4292,15 +4292,15 @@ long do_hvm_op(unsigned long op, XEN_GUE if ( copy_from_guest(&a, arg, 1) ) return -EFAULT; - rc = rcu_lock_target_domain_by_id(a.domid, &d); - if ( rc != 0 ) - return rc; + d = rcu_lock_domain_by_any_id(a.domid); + if ( d == NULL ) + return -ESRCH; rc = -EINVAL; if ( !is_hvm_domain(d) || !paging_mode_shadow(d) ) goto param_fail7; - rc = xsm_hvm_param(d, op); + rc = xsm_hvm_param(XSM_TARGET, d, op); if ( rc ) goto param_fail7; @@ -4346,7 +4346,7 @@ long do_hvm_op(unsigned long op, XEN_GUE if ( copy_from_guest(&tr, arg, 1 ) ) return -EFAULT; - rc = rcu_lock_remote_target_domain_by_id(tr.domid, &d); + rc = rcu_lock_remote_domain_by_id(tr.domid, &d); if ( rc != 0 ) return rc; @@ -4354,7 +4354,7 @@ long do_hvm_op(unsigned long op, XEN_GUE if ( !is_hvm_domain(d) ) goto param_fail8; - rc = xsm_hvm_param(d, op); + rc = xsm_hvm_param(XSM_TARGET, d, op); if ( rc ) goto param_fail8; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/arch/x86/irq.c --- a/xen/arch/x86/irq.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/arch/x86/irq.c Fri Jan 11 12:23:39 2013 +0000 @@ -1853,8 +1853,7 @@ int map_domain_pirq( ASSERT(spin_is_locked(&d->event_lock)); if ( !IS_PRIV(current->domain) && - !(IS_PRIV_FOR(current->domain, d) && - irq_access_permitted(current->domain, pirq))) + !irq_access_permitted(current->domain, pirq)) return -EPERM; if ( pirq < 0 || pirq >= d->nr_pirqs || irq < 0 || irq >= nr_irqs ) @@ -1875,7 +1874,7 @@ int map_domain_pirq( return 0; } - ret = xsm_map_domain_pirq(d, irq, data); + ret = xsm_map_domain_pirq(XSM_HOOK, d, irq, data); if ( ret ) { dprintk(XENLOG_G_ERR, "dom%d: could not permit access to irq %d mapping to pirq %d\n", diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/arch/x86/mm.c Fri Jan 11 12:23:39 2013 +0000 @@ -2605,11 +2605,6 @@ static struct domain *get_pg_owner(domid pg_owner = rcu_lock_domain(dom_io); break; case DOMID_XEN: - if ( !IS_PRIV(curr) ) - { - MEM_LOG("Cannot set foreign dom"); - break; - } pg_owner = rcu_lock_domain(dom_xen); break; default: @@ -2618,12 +2613,6 @@ static struct domain *get_pg_owner(domid MEM_LOG("Unknown domain '%u'", domid); break; } - if ( !IS_PRIV_FOR(curr, pg_owner) ) - { - MEM_LOG("Cannot set foreign dom"); - rcu_unlock_domain(pg_owner); - pg_owner = NULL; - } break; } @@ -2711,6 +2700,13 @@ long do_mmuext_op( goto out; } + rc = xsm_mmuext_op(XSM_TARGET, d, pg_owner); + if ( rc ) + { + rcu_unlock_domain(pg_owner); + goto out; + } + for ( i = 0; i < count; i++ ) { if ( hypercall_preempt_check() ) @@ -2776,7 +2772,7 @@ long do_mmuext_op( break; } - if ( (rc = xsm_memory_pin_page(d, pg_owner, page)) != 0 ) + if ( (rc = xsm_memory_pin_page(XSM_HOOK, d, pg_owner, page)) != 0 ) { put_page_and_type(page); okay = 0; @@ -3153,6 +3149,8 @@ long do_mmu_update( struct vcpu *v = current; struct domain *d = v->domain, *pt_owner = d, *pg_owner; struct domain_mmap_cache mapcache; + uint32_t xsm_needed = 0; + uint32_t xsm_checked = 0; if ( unlikely(count & MMU_UPDATE_PREEMPTED) ) { @@ -3184,11 +3182,6 @@ long do_mmu_update( rc = -EINVAL; goto out; } - if ( !IS_PRIV_FOR(d, pt_owner) ) - { - rc = -ESRCH; - goto out; - } } if ( (pg_owner = get_pg_owner((uint16_t)foreigndom)) == NULL ) @@ -3228,9 +3221,20 @@ long do_mmu_update( { p2m_type_t p2mt; - rc = xsm_mmu_normal_update(d, pt_owner, pg_owner, req.val); - if ( rc ) - break; + xsm_needed |= XSM_MMU_NORMAL_UPDATE; + if ( get_pte_flags(req.val) & _PAGE_PRESENT ) + { + xsm_needed |= XSM_MMU_UPDATE_READ; + if ( get_pte_flags(req.val) & _PAGE_RW ) + xsm_needed |= XSM_MMU_UPDATE_WRITE; + } + if ( xsm_needed != xsm_checked ) + { + rc = xsm_mmu_update(XSM_TARGET, d, pt_owner, pg_owner, xsm_needed); + if ( rc ) + break; + xsm_checked = xsm_needed; + } rc = -EINVAL; req.ptr -= cmd; @@ -3342,9 +3346,14 @@ long do_mmu_update( mfn = req.ptr >> PAGE_SHIFT; gpfn = req.val; - rc = xsm_mmu_machphys_update(d, pg_owner, mfn); - if ( rc ) - break; + xsm_needed |= XSM_MMU_MACHPHYS_UPDATE; + if ( xsm_needed != xsm_checked ) + { + rc = xsm_mmu_update(XSM_TARGET, d, NULL, pg_owner, xsm_needed); + if ( rc ) + break; + xsm_checked = xsm_needed; + } if ( unlikely(!get_page_from_pagenr(mfn, pg_owner)) ) { @@ -3908,7 +3917,7 @@ static int __do_update_va_mapping( perfc_incr(calls_to_update_va); - rc = xsm_update_va_mapping(d, pg_owner, val); + rc = xsm_update_va_mapping(XSM_TARGET, d, pg_owner, val); if ( rc ) return rc; @@ -4375,11 +4384,11 @@ long arch_memory_op(int op, XEN_GUEST_HA if ( copy_from_guest(&xatp, arg, 1) ) return -EFAULT; - rc = rcu_lock_target_domain_by_id(xatp.domid, &d); - if ( rc != 0 ) - return rc; - - if ( xsm_add_to_physmap(current->domain, d) ) + d = rcu_lock_domain_by_any_id(xatp.domid); + if ( d == NULL ) + return -ESRCH; + + if ( xsm_add_to_physmap(XSM_TARGET, current->domain, d) ) { rcu_unlock_domain(d); return -EPERM; @@ -4414,11 +4423,11 @@ long arch_memory_op(int op, XEN_GUEST_HA if ( fmap.map.nr_entries > E820MAX ) return -EINVAL; - rc = rcu_lock_target_domain_by_id(fmap.domid, &d); - if ( rc != 0 ) - return rc; - - rc = xsm_domain_memory_map(d); + d = rcu_lock_domain_by_any_id(fmap.domid); + if ( d == NULL ) + return -ESRCH; + + rc = xsm_domain_memory_map(XSM_TARGET, d); if ( rc ) { rcu_unlock_domain(d); @@ -4493,10 +4502,7 @@ long arch_memory_op(int op, XEN_GUEST_HA XEN_GUEST_HANDLE_PARAM(e820entry_t) buffer_param; unsigned int i; - if ( !IS_PRIV(current->domain) ) - return -EINVAL; - - rc = xsm_machine_memory_map(); + rc = xsm_machine_memory_map(XSM_PRIV); if ( rc ) return rc; @@ -4572,21 +4578,17 @@ long arch_memory_op(int op, XEN_GUEST_HA struct domain *d; struct p2m_domain *p2m; - /* Support DOMID_SELF? */ - if ( !IS_PRIV(current->domain) ) - return -EPERM; - if ( copy_from_guest(&target, arg, 1) ) return -EFAULT; - rc = rcu_lock_target_domain_by_id(target.domid, &d); - if ( rc != 0 ) - return rc; + d = rcu_lock_domain_by_any_id(target.domid); + if ( d == NULL ) + return -ESRCH; if ( op == XENMEM_set_pod_target ) - rc = xsm_set_pod_target(d); + rc = xsm_set_pod_target(XSM_PRIV, d); else - rc = xsm_get_pod_target(d); + rc = xsm_get_pod_target(XSM_PRIV, d); if ( rc != 0 ) goto pod_target_out_unlock; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/arch/x86/mm/mem_event.c --- a/xen/arch/x86/mm/mem_event.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/arch/x86/mm/mem_event.c Fri Jan 11 12:23:39 2013 +0000 @@ -29,6 +29,7 @@ #include <asm/mem_paging.h> #include <asm/mem_access.h> #include <asm/mem_sharing.h> +#include <xsm/xsm.h> /* for public/io/ring.h macros */ #define xen_mb() mb() @@ -439,35 +440,19 @@ static void mem_sharing_notification(str mem_sharing_sharing_resume(v->domain); } -struct domain *get_mem_event_op_target(uint32_t domain, int *rc) -{ - struct domain *d; - - /* Get the target domain */ - *rc = rcu_lock_remote_target_domain_by_id(domain, &d); - if ( *rc != 0 ) - return NULL; - - /* Not dying? */ - if ( d->is_dying ) - { - rcu_unlock_domain(d); - *rc = -EINVAL; - return NULL; - } - - return d; -} - int do_mem_event_op(int op, uint32_t domain, void *arg) { int ret; struct domain *d; - d = get_mem_event_op_target(domain, &ret); - if ( !d ) + ret = rcu_lock_live_remote_domain_by_id(domain, &d); + if ( ret ) return ret; + ret = xsm_mem_event_op(XSM_TARGET, d, op); + if ( ret ) + goto out; + switch (op) { case XENMEM_paging_op: @@ -483,6 +468,7 @@ int do_mem_event_op(int op, uint32_t dom ret = -ENOSYS; } + out: rcu_unlock_domain(d); return ret; } @@ -516,6 +502,10 @@ int mem_event_domctl(struct domain *d, x { int rc; + rc = xsm_mem_event_control(XSM_PRIV, d, mec->mode, mec->op); + if ( rc ) + return rc; + if ( unlikely(d == current->domain) ) { gdprintk(XENLOG_INFO, "Tried to do a memory event op on itself.\n"); @@ -537,13 +527,6 @@ int mem_event_domctl(struct domain *d, x return -EINVAL; } - /* TODO: XSM hook */ -#if 0 - rc = xsm_mem_event_control(d, mec->op); - if ( rc ) - return rc; -#endif - rc = -ENOSYS; switch ( mec->mode ) diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/arch/x86/mm/mem_sharing.c --- a/xen/arch/x86/mm/mem_sharing.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/arch/x86/mm/mem_sharing.c Fri Jan 11 12:23:39 2013 +0000 @@ -34,6 +34,7 @@ #include <asm/atomic.h> #include <xen/rcupdate.h> #include <asm/event.h> +#include <xsm/xsm.h> #include "mm-locks.h" @@ -1345,10 +1346,18 @@ int mem_sharing_memop(struct domain *d, if ( !mem_sharing_enabled(d) ) return -EINVAL; - cd = get_mem_event_op_target(mec->u.share.client_domain, &rc); - if ( !cd ) + rc = rcu_lock_live_remote_domain_by_id(mec->u.share.client_domain, + &cd); + if ( rc ) return rc; + rc = xsm_mem_sharing_op(XSM_TARGET, d, cd, mec->op); + if ( rc ) + { + rcu_unlock_domain(cd); + return rc; + } + if ( !mem_sharing_enabled(cd) ) { rcu_unlock_domain(cd); @@ -1401,10 +1410,18 @@ int mem_sharing_memop(struct domain *d, if ( !mem_sharing_enabled(d) ) return -EINVAL; - cd = get_mem_event_op_target(mec->u.share.client_domain, &rc); - if ( !cd ) + rc = rcu_lock_live_remote_domain_by_id(mec->u.share.client_domain, + &cd); + if ( rc ) return rc; + rc = xsm_mem_sharing_op(XSM_TARGET, d, cd, mec->op); + if ( rc ) + { + rcu_unlock_domain(cd); + return rc; + } + if ( !mem_sharing_enabled(cd) ) { rcu_unlock_domain(cd); diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/arch/x86/mm/paging.c --- a/xen/arch/x86/mm/paging.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/arch/x86/mm/paging.c Fri Jan 11 12:23:39 2013 +0000 @@ -559,7 +559,7 @@ int paging_domctl(struct domain *d, xen_ return -EINVAL; } - rc = xsm_shadow_control(d, sc->op); + rc = xsm_shadow_control(XSM_HOOK, d, sc->op); if ( rc ) return rc; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/arch/x86/msi.c --- a/xen/arch/x86/msi.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/arch/x86/msi.c Fri Jan 11 12:23:39 2013 +0000 @@ -1016,7 +1016,7 @@ int pci_restore_msi_state(struct pci_dev if (!pdev) return -EINVAL; - ret = xsm_resource_setup_pci((pdev->seg << 16) | (pdev->bus << 8) | pdev->devfn); + ret = xsm_resource_setup_pci(XSM_PRIV, (pdev->seg << 16) | (pdev->bus << 8) | pdev->devfn); if ( ret ) return ret; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/arch/x86/physdev.c --- a/xen/arch/x86/physdev.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/arch/x86/physdev.c Fri Jan 11 12:23:39 2013 +0000 @@ -109,12 +109,6 @@ int physdev_map_pirq(domid_t domid, int if ( ret ) return ret; - if ( !IS_PRIV_FOR(current->domain, d) ) - { - ret = -EPERM; - goto free_domain; - } - /* Verify or get irq. */ switch ( type ) { @@ -238,11 +232,7 @@ int physdev_unmap_pirq(domid_t domid, in goto free_domain; } - ret = -EPERM; - if ( !IS_PRIV_FOR(current->domain, d) ) - goto free_domain; - - ret = xsm_unmap_domain_pirq(d, domain_pirq_to_irq(d, pirq)); + ret = xsm_unmap_domain_pirq(XSM_TARGET, d, domain_pirq_to_irq(d, pirq)); if ( ret ) goto free_domain; @@ -433,10 +423,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H ret = -EFAULT; if ( copy_from_guest(&apic, arg, 1) != 0 ) break; - ret = -EPERM; - if ( !IS_PRIV(v->domain) ) - break; - ret = xsm_apic(v->domain, cmd); + ret = xsm_apic(XSM_PRIV, v->domain, cmd); if ( ret ) break; ret = ioapic_guest_read(apic.apic_physbase, apic.reg, &apic.value); @@ -450,10 +437,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H ret = -EFAULT; if ( copy_from_guest(&apic, arg, 1) != 0 ) break; - ret = -EPERM; - if ( !IS_PRIV(v->domain) ) - break; - ret = xsm_apic(v->domain, cmd); + ret = xsm_apic(XSM_PRIV, v->domain, cmd); if ( ret ) break; ret = ioapic_guest_write(apic.apic_physbase, apic.reg, apic.value); @@ -467,8 +451,10 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H if ( copy_from_guest(&irq_op, arg, 1) != 0 ) break; - ret = -EPERM; - if ( !IS_PRIV(v->domain) ) + /* Use the APIC check since this dummy hypercall should still only + * be called by the domain with access to program the ioapic */ + ret = xsm_apic(XSM_PRIV, v->domain, cmd); + if ( ret ) break; /* Vector is only used by hypervisor, and dom0 shouldn't @@ -517,9 +503,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H case PHYSDEVOP_manage_pci_add: { struct physdev_manage_pci manage_pci; - ret = -EPERM; - if ( !IS_PRIV(v->domain) ) - break; ret = -EFAULT; if ( copy_from_guest(&manage_pci, arg, 1) != 0 ) break; @@ -530,9 +513,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H case PHYSDEVOP_manage_pci_remove: { struct physdev_manage_pci manage_pci; - ret = -EPERM; - if ( !IS_PRIV(v->domain) ) - break; ret = -EFAULT; if ( copy_from_guest(&manage_pci, arg, 1) != 0 ) break; @@ -545,10 +525,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H struct physdev_manage_pci_ext manage_pci_ext; struct pci_dev_info pdev_info; - ret = -EPERM; - if ( !IS_PRIV(current->domain) ) - break; - ret = -EFAULT; if ( copy_from_guest(&manage_pci_ext, arg, 1) != 0 ) break; @@ -571,10 +547,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H struct physdev_pci_device_add add; struct pci_dev_info pdev_info; - ret = -EPERM; - if ( !IS_PRIV(current->domain) ) - break; - ret = -EFAULT; if ( copy_from_guest(&add, arg, 1) != 0 ) break; @@ -595,10 +567,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H case PHYSDEVOP_pci_device_remove: { struct physdev_pci_device dev; - ret = -EPERM; - if ( !IS_PRIV(v->domain) ) - break; - ret = -EFAULT; if ( copy_from_guest(&dev, arg, 1) != 0 ) break; @@ -610,11 +578,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H case PHYSDEVOP_pci_mmcfg_reserved: { struct physdev_pci_mmcfg_reserved info; - ret = -EPERM; - if ( !IS_PRIV(current->domain) ) - break; - - ret = xsm_resource_setup_misc(); + ret = xsm_resource_setup_misc(XSM_PRIV); if ( ret ) break; @@ -631,10 +595,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H struct physdev_restore_msi restore_msi; struct pci_dev *pdev; - ret = -EPERM; - if ( !IS_PRIV(v->domain) ) - break; - ret = -EFAULT; if ( copy_from_guest(&restore_msi, arg, 1) != 0 ) break; @@ -650,10 +610,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H struct physdev_pci_device dev; struct pci_dev *pdev; - ret = -EPERM; - if ( !IS_PRIV(v->domain) ) - break; - ret = -EFAULT; if ( copy_from_guest(&dev, arg, 1) != 0 ) break; @@ -668,10 +624,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H case PHYSDEVOP_setup_gsi: { struct physdev_setup_gsi setup_gsi; - ret = -EPERM; - if ( !IS_PRIV(v->domain) ) - break; - ret = -EFAULT; if ( copy_from_guest(&setup_gsi, arg, 1) != 0 ) break; @@ -680,7 +632,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H if ( setup_gsi.gsi < 0 || setup_gsi.gsi >= nr_irqs_gsi ) break; - ret = xsm_resource_setup_gsi(setup_gsi.gsi); + ret = xsm_resource_setup_gsi(XSM_PRIV, setup_gsi.gsi); if ( ret ) break; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/arch/x86/platform_hypercall.c --- a/xen/arch/x86/platform_hypercall.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/arch/x86/platform_hypercall.c Fri Jan 11 12:23:39 2013 +0000 @@ -66,15 +66,16 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA ret_t ret = 0; struct xen_platform_op curop, *op = &curop; - if ( !IS_PRIV(current->domain) ) - return -EPERM; - if ( copy_from_guest(op, u_xenpf_op, 1) ) return -EFAULT; if ( op->interface_version != XENPF_INTERFACE_VERSION ) return -EACCES; + ret = xsm_platform_op(XSM_PRIV, op->cmd); + if ( ret ) + return ret; + /* * Trylock here avoids deadlock with an existing platform critical section * which might (for some current or future reason) want to synchronise @@ -89,10 +90,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA { case XENPF_settime: { - ret = xsm_xen_settime(); - if ( ret ) - break; - do_settime(op->u.settime.secs, op->u.settime.nsecs, op->u.settime.system_time); @@ -102,10 +99,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA case XENPF_add_memtype: { - ret = xsm_memtype(op->cmd); - if ( ret ) - break; - ret = mtrr_add_page( op->u.add_memtype.mfn, op->u.add_memtype.nr_mfns, @@ -125,10 +118,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA case XENPF_del_memtype: { - ret = xsm_memtype(op->cmd); - if ( ret ) - break; - if (op->u.del_memtype.handle == 0 /* mtrr/main.c otherwise does a lookup */ && (int)op->u.del_memtype.reg >= 0) @@ -147,10 +136,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA unsigned long mfn, nr_mfns; mtrr_type type; - ret = xsm_memtype(op->cmd); - if ( ret ) - break; - ret = -EINVAL; if ( op->u.read_memtype.reg < num_var_ranges ) { @@ -168,10 +153,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA { XEN_GUEST_HANDLE(const_void) data; - ret = xsm_microcode(); - if ( ret ) - break; - guest_from_compat_handle(data, op->u.microcode.data); /* @@ -199,10 +180,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA { int quirk_id = op->u.platform_quirk.quirk_id; - ret = xsm_platform_quirk(quirk_id); - if ( ret ) - break; - switch ( quirk_id ) { case QUIRK_NOIRQBALANCING: @@ -224,10 +201,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA break; case XENPF_firmware_info: - ret = xsm_firmware_info(); - if ( ret ) - break; - switch ( op->u.firmware_info.type ) { case XEN_FW_DISK_INFO: { @@ -336,10 +309,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA break; case XENPF_efi_runtime_call: - ret = xsm_efi_call(); - if ( ret ) - break; - ret = efi_runtime_call(&op->u.efi_runtime_call); if ( ret == 0 && __copy_field_to_guest(u_xenpf_op, op, u.efi_runtime_call) ) @@ -347,18 +316,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA break; case XENPF_enter_acpi_sleep: - ret = xsm_acpi_sleep(); - if ( ret ) - break; - ret = acpi_enter_sleep(&op->u.enter_acpi_sleep); break; case XENPF_change_freq: - ret = xsm_change_freq(); - if ( ret ) - break; - ret = -ENOSYS; if ( cpufreq_controller != FREQCTL_dom0_kernel ) break; @@ -380,10 +341,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA XEN_GUEST_HANDLE(uint8) cpumap_bitmap; XEN_GUEST_HANDLE(uint64) idletimes; - ret = xsm_getidletime(); - if ( ret ) - break; - ret = -ENOSYS; if ( cpufreq_controller != FREQCTL_dom0_kernel ) break; @@ -420,10 +377,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA break; case XENPF_set_processor_pminfo: - ret = xsm_setpminfo(); - if ( ret ) - break; - switch ( op->u.set_pminfo.type ) { case XEN_PM_PX: @@ -476,10 +429,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA g_info = &op->u.pcpu_info; - ret = xsm_getcpuinfo(); - if ( ret ) - break; - if ( !get_cpu_maps() ) { ret = -EBUSY; @@ -549,7 +498,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA { int cpu = op->u.cpu_ol.cpuid; - ret = xsm_resource_plug_core(); + ret = xsm_resource_plug_core(XSM_HOOK); if ( ret ) break; @@ -565,10 +514,6 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA break; } - ret = xsm_resource_plug_core(); - if ( ret ) - break; - ret = continue_hypercall_on_cpu( 0, cpu_up_helper, (void *)(unsigned long)cpu); break; @@ -578,7 +523,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA { int cpu = op->u.cpu_ol.cpuid; - ret = xsm_resource_unplug_core(); + ret = xsm_resource_unplug_core(XSM_HOOK); if ( ret ) break; @@ -607,7 +552,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA break; case XENPF_cpu_hotadd: - ret = xsm_resource_plug_core(); + ret = xsm_resource_plug_core(XSM_HOOK); if ( ret ) break; @@ -617,7 +562,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA break; case XENPF_mem_hotadd: - ret = xsm_resource_plug_core(); + ret = xsm_resource_plug_core(XSM_HOOK); if ( ret ) break; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/arch/x86/sysctl.c --- a/xen/arch/x86/sysctl.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/arch/x86/sysctl.c Fri Jan 11 12:23:39 2013 +0000 @@ -69,11 +69,6 @@ long arch_do_sysctl( { xen_sysctl_physinfo_t *pi = &sysctl->u.physinfo; - ret = xsm_physinfo(); - if ( ret ) - break; - - memset(pi, 0, sizeof(*pi)); pi->threads_per_core = cpumask_weight(per_cpu(cpu_sibling_mask, 0)); @@ -103,10 +98,6 @@ long arch_do_sysctl( uint32_t i, max_cpu_index, last_online_cpu; xen_sysctl_topologyinfo_t *ti = &sysctl->u.topologyinfo; - ret = xsm_physinfo(); - if ( ret ) - break; - last_online_cpu = cpumask_last(&cpu_online_map); max_cpu_index = min_t(uint32_t, ti->max_cpu_index, last_online_cpu); ti->max_cpu_index = last_online_cpu; @@ -144,10 +135,6 @@ long arch_do_sysctl( uint32_t i, j, max_node_index, last_online_node; xen_sysctl_numainfo_t *ni = &sysctl->u.numainfo; - ret = xsm_physinfo(); - if ( ret ) - break; - last_online_node = last_node(node_online_map); max_node_index = min_t(uint32_t, ni->max_node_index, last_online_node); ni->max_node_index = last_online_node; @@ -199,14 +186,14 @@ long arch_do_sysctl( switch ( sysctl->u.cpu_hotplug.op ) { case XEN_SYSCTL_CPU_HOTPLUG_ONLINE: - ret = xsm_resource_plug_core(); + ret = xsm_resource_plug_core(XSM_HOOK); if ( ret ) break; ret = continue_hypercall_on_cpu( 0, cpu_up_helper, (void *)(unsigned long)cpu); break; case XEN_SYSCTL_CPU_HOTPLUG_OFFLINE: - ret = xsm_resource_unplug_core(); + ret = xsm_resource_unplug_core(XSM_HOOK); if ( ret ) break; ret = continue_hypercall_on_cpu( diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/arch/x86/traps.c Fri Jan 11 12:23:39 2013 +0000 @@ -1643,7 +1643,7 @@ static int pci_cfg_ok(struct domain *d, start |= (d->arch.pci_cf8 >> 16) & 0xF00; } end = start + size - 1; - if (xsm_pci_config_permission(d, machine_bdf, start, end, write)) + if (xsm_pci_config_permission(XSM_HOOK, d, machine_bdf, start, end, write)) return 0; return 1; } diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/common/domain.c --- a/xen/common/domain.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/common/domain.c Fri Jan 11 12:23:39 2013 +0000 @@ -252,7 +252,7 @@ struct domain *domain_create( if ( !is_idle_domain(d) ) { - if ( (err = xsm_domain_create(d, ssidref)) != 0 ) + if ( (err = xsm_domain_create(XSM_HOOK, d, ssidref)) != 0 ) goto fail; d->is_paused_by_controller = 1; @@ -475,6 +475,21 @@ int rcu_lock_remote_domain_by_id(domid_t return 0; } +int rcu_lock_live_remote_domain_by_id(domid_t dom, struct domain **d) +{ + int rv; + rv = rcu_lock_remote_domain_by_id(dom, d); + if ( rv ) + return rv; + if ( (*d)->is_dying ) + { + rcu_unlock_domain(*d); + return -EINVAL; + } + + return 0; +} + int domain_kill(struct domain *d) { int rc = 0; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/common/domctl.c --- a/xen/common/domctl.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/common/domctl.c Fri Jan 11 12:23:39 2013 +0000 @@ -265,27 +265,9 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe return -ESRCH; } - switch ( op->cmd ) - { - case XEN_DOMCTL_ioport_mapping: - case XEN_DOMCTL_memory_mapping: - case XEN_DOMCTL_bind_pt_irq: - case XEN_DOMCTL_unbind_pt_irq: { - bool_t is_priv = IS_PRIV_FOR(current->domain, d); - if ( !is_priv ) - { - ret = -EPERM; - goto domctl_out_unlock_domonly; - } - break; - } - case XEN_DOMCTL_getdomaininfo: - break; - default: - if ( !IS_PRIV(current->domain) ) - return -EPERM; - break; - } + ret = xsm_domctl(XSM_OTHER, d, op->cmd); + if ( ret ) + goto domctl_out_unlock_domonly; if ( !domctl_lock_acquire() ) { @@ -308,10 +290,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe if ( d == NULL ) break; - ret = xsm_setvcpucontext(d); - if ( ret ) - goto svc_out; - ret = -EINVAL; if ( (d == current->domain) || /* no domain_pause() */ (vcpu >= d->max_vcpus) || ((v = d->vcpu[vcpu]) == NULL) ) @@ -358,10 +336,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe case XEN_DOMCTL_pausedomain: { - ret = xsm_pausedomain(d); - if ( ret ) - break; - ret = -EINVAL; if ( d != current->domain ) { @@ -373,10 +347,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe case XEN_DOMCTL_unpausedomain: { - ret = xsm_unpausedomain(d); - if ( ret ) - break; - domain_unpause_by_systemcontroller(d); ret = 0; } @@ -384,10 +354,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe case XEN_DOMCTL_resumedomain: { - ret = xsm_resumedomain(d); - if ( ret ) - break; - domain_resume(d); ret = 0; } @@ -470,10 +436,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe (is_hvm_domain(d) && (max > MAX_HVM_VCPUS)) ) break; - ret = xsm_max_vcpus(d); - if ( ret ) - break; - /* Until Xenoprof can dynamically grow its vcpu-s array... */ if ( d->xenoprof ) { @@ -556,7 +518,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe case XEN_DOMCTL_destroydomain: { - ret = xsm_destroydomain(d) ? : domain_kill(d); + ret = domain_kill(d); } break; @@ -565,10 +527,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe { struct vcpu *v; - ret = xsm_vcpuaffinity(op->cmd, d); - if ( ret ) - break; - ret = -EINVAL; if ( op->u.vcpuaffinity.vcpu >= d->max_vcpus ) break; @@ -599,10 +557,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe case XEN_DOMCTL_scheduler_op: { - ret = xsm_scheduler(d); - if ( ret ) - break; - ret = sched_adjust(d, &op->u.scheduler_op); copyback = 1; } @@ -625,7 +579,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe break; } - ret = xsm_getdomaininfo(d); + ret = xsm_getdomaininfo(XSM_HOOK, d); if ( ret ) goto getdomaininfo_out; @@ -645,10 +599,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe vcpu_guest_context_u c = { .nat = NULL }; struct vcpu *v; - ret = xsm_getvcpucontext(d); - if ( ret ) - goto getvcpucontext_out; - ret = -EINVAL; if ( op->u.vcpucontext.vcpu >= d->max_vcpus ) goto getvcpucontext_out; @@ -702,10 +652,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe struct vcpu *v; struct vcpu_runstate_info runstate; - ret = xsm_getvcpuinfo(d); - if ( ret ) - break; - ret = -EINVAL; if ( op->u.getvcpuinfo.vcpu >= d->max_vcpus ) break; @@ -730,10 +676,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe { unsigned long new_max; - ret = xsm_setdomainmaxmem(d); - if ( ret ) - break; - ret = -EINVAL; new_max = op->u.max_mem.max_memkb >> (PAGE_SHIFT-10); @@ -751,10 +693,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe case XEN_DOMCTL_setdomainhandle: { - ret = xsm_setdomainhandle(d); - if ( ret ) - break; - memcpy(d->handle, op->u.setdomainhandle.handle, sizeof(xen_domain_handle_t)); ret = 0; @@ -767,10 +705,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe if ( d == current->domain ) /* no domain_pause() */ break; - ret = xsm_setdebugging(d); - if ( ret ) - break; - domain_pause(d); d->debugger_attached = !!op->u.setdebugging.enable; domain_unpause(d); /* causes guest to latch new status */ @@ -785,7 +719,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe if ( pirq >= d->nr_pirqs ) ret = -EINVAL; - else if ( xsm_irq_permission(d, pirq, allow) ) + else if ( xsm_irq_permission(XSM_HOOK, d, pirq, allow) ) ret = -EPERM; else if ( allow ) ret = irq_permit_access(d, pirq); @@ -804,7 +738,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe if ( (mfn + nr_mfns - 1) < mfn ) /* wrap? */ break; - if ( xsm_iomem_permission(d, mfn, mfn + nr_mfns - 1, allow) ) + if ( xsm_iomem_permission(XSM_HOOK, d, mfn, mfn + nr_mfns - 1, allow) ) ret = -EPERM; else if ( allow ) ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1); @@ -815,10 +749,6 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe case XEN_DOMCTL_settimeoffset: { - ret = xsm_domain_settime(d); - if ( ret ) - break; - domain_set_time_offset(d, op->u.settimeoffset.time_offset_seconds); ret = 0; } @@ -840,7 +770,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe break; } - ret = xsm_set_target(d, e); + ret = xsm_set_target(XSM_HOOK, d, e); if ( ret ) { put_domain(e); break; @@ -855,27 +785,20 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xe case XEN_DOMCTL_subscribe: { - ret = xsm_domctl(d, op->cmd); - if ( !ret ) - d->suspend_evtchn = op->u.subscribe.port; + d->suspend_evtchn = op->u.subscribe.port; } break; case XEN_DOMCTL_disable_migrate: { - ret = xsm_domctl(d, op->cmd); - if ( !ret ) - d->disable_migrate = op->u.disable_migrate.disable; + d->disable_migrate = op->u.disable_migrate.disable; } break; case XEN_DOMCTL_set_virq_handler: { uint32_t virq = op->u.set_virq_handler.virq; - - ret = xsm_set_virq_handler(d, virq); - if ( !ret ) - ret = set_global_virq_handler(d, virq); + ret = set_global_virq_handler(d, virq); } break; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/common/event_channel.c --- a/xen/common/event_channel.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/common/event_channel.c Fri Jan 11 12:23:39 2013 +0000 @@ -165,9 +165,9 @@ static long evtchn_alloc_unbound(evtchn_ domid_t dom = alloc->dom; long rc; - rc = rcu_lock_target_domain_by_id(dom, &d); - if ( rc ) - return rc; + d = rcu_lock_domain_by_any_id(dom); + if ( d == NULL ) + return -ESRCH; spin_lock(&d->event_lock); @@ -175,7 +175,7 @@ static long evtchn_alloc_unbound(evtchn_ ERROR_EXIT_DOM(port, d); chn = evtchn_from_port(d, port); - rc = xsm_evtchn_unbound(d, chn, alloc->remote_dom); + rc = xsm_evtchn_unbound(XSM_TARGET, d, chn, alloc->remote_dom); if ( rc ) goto out; @@ -231,7 +231,7 @@ static long evtchn_bind_interdomain(evtc (rchn->u.unbound.remote_domid != ld->domain_id) ) ERROR_EXIT_DOM(-EINVAL, rd); - rc = xsm_evtchn_interdomain(ld, lchn, rd, rchn); + rc = xsm_evtchn_interdomain(XSM_HOOK, ld, lchn, rd, rchn); if ( rc ) goto out; @@ -580,7 +580,7 @@ int evtchn_send(struct domain *d, unsign return -EINVAL; } - ret = xsm_evtchn_send(ld, lchn); + ret = xsm_evtchn_send(XSM_HOOK, ld, lchn); if ( ret ) goto out; @@ -798,9 +798,9 @@ static long evtchn_status(evtchn_status_ struct evtchn *chn; long rc = 0; - rc = rcu_lock_target_domain_by_id(dom, &d); - if ( rc ) - return rc; + d = rcu_lock_domain_by_any_id(dom); + if ( d == NULL ) + return -ESRCH; spin_lock(&d->event_lock); @@ -812,7 +812,7 @@ static long evtchn_status(evtchn_status_ chn = evtchn_from_port(d, port); - rc = xsm_evtchn_status(d, chn); + rc = xsm_evtchn_status(XSM_TARGET, d, chn); if ( rc ) goto out; @@ -950,11 +950,11 @@ static long evtchn_reset(evtchn_reset_t struct domain *d; int i, rc; - rc = rcu_lock_target_domain_by_id(dom, &d); - if ( rc ) - return rc; + d = rcu_lock_domain_by_any_id(dom); + if ( d == NULL ) + return -ESRCH; - rc = xsm_evtchn_reset(current->domain, d); + rc = xsm_evtchn_reset(XSM_TARGET, current->domain, d); if ( rc ) goto out; @@ -1101,7 +1101,7 @@ int alloc_unbound_xen_event_channel( goto out; chn = evtchn_from_port(d, port); - rc = xsm_evtchn_unbound(d, chn, remote_domid); + rc = xsm_evtchn_unbound(XSM_TARGET, d, chn, remote_domid); chn->state = ECS_UNBOUND; chn->xen_consumer = get_xen_consumer(notification_fn); diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/common/grant_table.c --- a/xen/common/grant_table.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/common/grant_table.c Fri Jan 11 12:23:39 2013 +0000 @@ -230,30 +230,6 @@ double_gt_unlock(struct grant_table *lgt spin_unlock(&rgt->lock); } -static struct domain *gt_lock_target_domain_by_id(domid_t dom) -{ - struct domain *d; - int rc = GNTST_general_error; - - switch ( rcu_lock_target_domain_by_id(dom, &d) ) - { - case 0: - return d; - - case -ESRCH: - gdprintk(XENLOG_INFO, "Bad domid %d.\n", dom); - rc = GNTST_bad_domain; - break; - - case -EPERM: - rc = GNTST_permission_denied; - break; - } - - ASSERT(rc < 0 && -rc <= MAX_ERRNO); - return ERR_PTR(rc); -} - static inline int __get_maptrack_handle( struct grant_table *t) @@ -576,7 +552,7 @@ __gnttab_map_grant_ref( return; } - rc = xsm_grant_mapref(ld, rd, op->flags); + rc = xsm_grant_mapref(XSM_HOOK, ld, rd, op->flags); if ( rc ) { rcu_unlock_domain(rd); @@ -896,7 +872,7 @@ __gnttab_unmap_common( return; } - rc = xsm_grant_unmapref(ld, rd); + rc = xsm_grant_unmapref(XSM_HOOK, ld, rd); if ( rc ) { rcu_unlock_domain(rd); @@ -1352,14 +1328,15 @@ gnttab_setup_table( if ( !guest_handle_okay(op.frame_list, op.nr_frames) ) return -EFAULT; - d = gt_lock_target_domain_by_id(op.dom); - if ( IS_ERR(d) ) + d = rcu_lock_domain_by_any_id(op.dom); + if ( d == NULL ) { - op.status = PTR_ERR(d); - goto out1; + gdprintk(XENLOG_INFO, "Bad domid %d.\n", op.dom); + op.status = GNTST_bad_domain; + goto out2; } - if ( xsm_grant_setup(current->domain, d) ) + if ( xsm_grant_setup(XSM_TARGET, current->domain, d) ) { op.status = GNTST_permission_denied; goto out2; @@ -1421,14 +1398,15 @@ gnttab_query_size( return -EFAULT; } - d = gt_lock_target_domain_by_id(op.dom); - if ( IS_ERR(d) ) + d = rcu_lock_domain_by_any_id(op.dom); + if ( d == NULL ) { - op.status = PTR_ERR(d); + gdprintk(XENLOG_INFO, "Bad domid %d.\n", op.dom); + op.status = GNTST_bad_domain; goto query_out; } - rc = xsm_grant_query_size(current->domain, d); + rc = xsm_grant_query_size(XSM_TARGET, current->domain, d); if ( rc ) { op.status = GNTST_permission_denied; @@ -1604,7 +1582,7 @@ gnttab_transfer( goto copyback; } - if ( xsm_grant_transfer(d, e) ) + if ( xsm_grant_transfer(XSM_HOOK, d, e) ) { put_gfn(d, gop.mfn); gop.status = GNTST_permission_denied; @@ -2044,7 +2022,7 @@ __gnttab_copy( PIN_FAIL(error_out, GNTST_bad_domain, "couldn't find %d\n", op->dest.domid); - rc = xsm_grant_copy(sd, dd); + rc = xsm_grant_copy(XSM_HOOK, sd, dd); if ( rc ) { rc = GNTST_permission_denied; @@ -2296,13 +2274,13 @@ gnttab_get_status_frames(XEN_GUEST_HANDL return -EFAULT; } - d = gt_lock_target_domain_by_id(op.dom); - if ( IS_ERR(d) ) + d = rcu_lock_domain_by_any_id(op.dom); + if ( d == NULL ) { - op.status = PTR_ERR(d); + op.status = GNTST_bad_domain; goto out1; } - rc = xsm_grant_setup(current->domain, d); + rc = xsm_grant_setup(XSM_TARGET, current->domain, d); if ( rc ) { op.status = GNTST_permission_denied; goto out1; @@ -2349,14 +2327,15 @@ gnttab_get_version(XEN_GUEST_HANDLE_PARA if ( copy_from_guest(&op, uop, 1) ) return -EFAULT; - rc = rcu_lock_target_domain_by_id(op.dom, &d); - if ( rc < 0 ) - return rc; - - if ( xsm_grant_query_size(current->domain, d) ) + d = rcu_lock_domain_by_any_id(op.dom); + if ( d == NULL ) + return -ESRCH; + + rc = xsm_grant_query_size(XSM_TARGET, current->domain, d); + if ( rc ) { rcu_unlock_domain(d); - return -EPERM; + return rc; } op.version = d->grant_table->gt_version; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/common/kexec.c --- a/xen/common/kexec.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/common/kexec.c Fri Jan 11 12:23:39 2013 +0000 @@ -852,10 +852,7 @@ static int do_kexec_op_internal(unsigned unsigned long flags; int ret = -EINVAL; - if ( !IS_PRIV(current->domain) ) - return -EPERM; - - ret = xsm_kexec(); + ret = xsm_kexec(XSM_PRIV); if ( ret ) return ret; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/common/memory.c --- a/xen/common/memory.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/common/memory.c Fri Jan 11 12:23:39 2013 +0000 @@ -341,9 +341,19 @@ static long memory_exchange(XEN_GUEST_HA out_chunk_order = exch.in.extent_order - exch.out.extent_order; } - rc = rcu_lock_target_domain_by_id(exch.in.domid, &d); + d = rcu_lock_domain_by_any_id(exch.in.domid); + if ( d == NULL ) + { + rc = -ESRCH; + goto fail_early; + } + + rc = xsm_memory_exchange(XSM_TARGET, d); if ( rc ) + { + rcu_unlock_domain(d); goto fail_early; + } memflags |= MEMF_bits(domain_clamp_alloc_bitsize( d, @@ -585,11 +595,12 @@ long do_memory_op(unsigned long cmd, XEN && (reservation.mem_flags & XENMEMF_populate_on_demand) ) args.memflags |= MEMF_populate_on_demand; - if ( unlikely(rcu_lock_target_domain_by_id(reservation.domid, &d)) ) + d = rcu_lock_domain_by_any_id(reservation.domid); + if ( d == NULL ) return start_extent; args.domain = d; - rc = xsm_memory_adjust_reservation(current->domain, d); + rc = xsm_memory_adjust_reservation(XSM_TARGET, current->domain, d); if ( rc ) { rcu_unlock_domain(d); @@ -634,11 +645,11 @@ long do_memory_op(unsigned long cmd, XEN if ( copy_from_guest(&domid, arg, 1) ) return -EFAULT; - rc = rcu_lock_target_domain_by_id(domid, &d); - if ( rc ) - return rc; + d = rcu_lock_domain_by_any_id(domid); + if ( d == NULL ) + return -ESRCH; - rc = xsm_memory_stat_reservation(current->domain, d); + rc = xsm_memory_stat_reservation(XSM_TARGET, current->domain, d); if ( rc ) { rcu_unlock_domain(d); @@ -672,11 +683,11 @@ long do_memory_op(unsigned long cmd, XEN if ( copy_from_guest(&xrfp, arg, 1) ) return -EFAULT; - rc = rcu_lock_target_domain_by_id(xrfp.domid, &d); - if ( rc != 0 ) - return rc; + d = rcu_lock_domain_by_any_id(xrfp.domid); + if ( d == NULL ) + return -ESRCH; - if ( xsm_remove_from_physmap(current->domain, d) ) + if ( xsm_remove_from_physmap(XSM_TARGET, current->domain, d) ) { rcu_unlock_domain(d); return -EPERM; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/common/schedule.c --- a/xen/common/schedule.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/common/schedule.c Fri Jan 11 12:23:39 2013 +0000 @@ -921,13 +921,7 @@ ret_t do_sched_op(int cmd, XEN_GUEST_HAN if ( d == NULL ) break; - if ( !IS_PRIV_FOR(current->domain, d) ) - { - rcu_unlock_domain(d); - return -EPERM; - } - - ret = xsm_schedop_shutdown(current->domain, d); + ret = xsm_schedop_shutdown(XSM_DM_PRIV, current->domain, d); if ( ret ) { rcu_unlock_domain(d); @@ -1012,7 +1006,11 @@ int sched_id(void) long sched_adjust(struct domain *d, struct xen_domctl_scheduler_op *op) { long ret; - + + ret = xsm_domctl_scheduler_op(XSM_HOOK, d, op->cmd); + if ( ret ) + return ret; + if ( (op->sched_id != DOM2OP(d)->sched_id) || ((op->cmd != XEN_DOMCTL_SCHEDOP_putinfo) && (op->cmd != XEN_DOMCTL_SCHEDOP_getinfo)) ) @@ -1031,6 +1029,10 @@ long sched_adjust_global(struct xen_sysc struct cpupool *pool; int rc; + rc = xsm_sysctl_scheduler_op(XSM_HOOK, op->cmd); + if ( rc ) + return rc; + if ( (op->cmd != XEN_DOMCTL_SCHEDOP_putinfo) && (op->cmd != XEN_DOMCTL_SCHEDOP_getinfo) ) return -EINVAL; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/common/sysctl.c --- a/xen/common/sysctl.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/common/sysctl.c Fri Jan 11 12:23:39 2013 +0000 @@ -34,15 +34,16 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xe struct xen_sysctl curop, *op = &curop; static DEFINE_SPINLOCK(sysctl_lock); - if ( !IS_PRIV(current->domain) ) - return -EPERM; - if ( copy_from_guest(op, u_sysctl, 1) ) return -EFAULT; if ( op->interface_version != XEN_SYSCTL_INTERFACE_VERSION ) return -EACCES; + ret = xsm_sysctl(XSM_PRIV, op->cmd); + if ( ret ) + return ret; + /* * Trylock here avoids deadlock with an existing sysctl critical section * which might (for some current or future reason) want to synchronise @@ -56,7 +57,7 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xe switch ( op->cmd ) { case XEN_SYSCTL_readconsole: - ret = xsm_readconsole(op->u.readconsole.clear); + ret = xsm_readconsole(XSM_HOOK, op->u.readconsole.clear); if ( ret ) break; @@ -64,18 +65,10 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xe break; case XEN_SYSCTL_tbuf_op: - ret = xsm_tbufcontrol(); - if ( ret ) - break; - ret = tb_control(&op->u.tbuf_op); break; case XEN_SYSCTL_sched_id: - ret = xsm_sched_id(); - if ( ret ) - break; - op->u.sched_id.sched_id = sched_id(); break; @@ -94,7 +87,7 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xe if ( num_domains == op->u.getdomaininfolist.max_domains ) break; - ret = xsm_getdomaininfo(d); + ret = xsm_getdomaininfo(XSM_HOOK, d); if ( ret ) continue; @@ -121,20 +114,12 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xe #ifdef PERF_COUNTERS case XEN_SYSCTL_perfc_op: - ret = xsm_perfcontrol(); - if ( ret ) - break; - ret = perfc_control(&op->u.perfc_op); break; #endif #ifdef LOCK_PROFILE case XEN_SYSCTL_lockprof_op: - ret = xsm_lockprof(); - if ( ret ) - break; - ret = spinlock_profile_control(&op->u.lockprof_op); break; #endif @@ -143,10 +128,6 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xe char c; uint32_t i; - ret = xsm_debug_keys(); - if ( ret ) - break; - ret = -EFAULT; for ( i = 0; i < op->u.debug_keys.nr_keys; i++ ) { @@ -166,10 +147,6 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xe nr_cpus = min(op->u.getcpuinfo.max_cpus, nr_cpu_ids); - ret = xsm_getcpuinfo(); - if ( ret ) - break; - ret = -EFAULT; for ( i = 0; i < nr_cpus; i++ ) { @@ -185,10 +162,6 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xe break; case XEN_SYSCTL_availheap: - ret = xsm_availheap(); - if ( ret ) - break; - op->u.availheap.avail_bytes = avail_domheap_pages_region( op->u.availheap.node, op->u.availheap.min_bitwidth, @@ -198,18 +171,10 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xe #ifdef HAS_ACPI case XEN_SYSCTL_get_pmstat: - ret = xsm_get_pmstat(); - if ( ret ) - break; - ret = do_get_pm_info(&op->u.get_pmstat); break; case XEN_SYSCTL_pm_op: - ret = xsm_pm_op(); - if ( ret ) - break; - ret = do_pm_op(&op->u.pm_op); if ( ret == -EAGAIN ) copyback = 1; @@ -221,7 +186,7 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xe uint32_t *status, *ptr; unsigned long pfn; - ret = xsm_page_offline(op->u.page_offline.cmd); + ret = xsm_page_offline(XSM_HOOK, op->u.page_offline.cmd); if ( ret ) break; @@ -277,18 +242,10 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xe break; case XEN_SYSCTL_cpupool_op: - ret = xsm_cpupool_op(); - if ( ret ) - break; - ret = cpupool_do_sysctl(&op->u.cpupool_op); break; case XEN_SYSCTL_scheduler_op: - ret = xsm_sched_op(); - if ( ret ) - break; - ret = sched_adjust_global(&op->u.scheduler_op); break; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/common/tmem.c --- a/xen/common/tmem.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/common/tmem.c Fri Jan 11 12:23:39 2013 +0000 @@ -2644,6 +2644,9 @@ EXPORT long do_tmem_op(tmem_cli_op_t uop if ( !tmem_initialized ) return -ENODEV; + if ( !tmh_current_permitted() ) + return -EPERM; + total_tmem_ops++; if ( tmh_lock_all ) diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/common/xenoprof.c --- a/xen/common/xenoprof.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/common/xenoprof.c Fri Jan 11 12:23:39 2013 +0000 @@ -677,7 +677,7 @@ ret_t do_xenoprof_op(int op, XEN_GUEST_H return -EPERM; } - ret = xsm_profile(current->domain, op); + ret = xsm_profile(XSM_HOOK, current->domain, op); if ( ret ) return ret; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/drivers/char/console.c --- a/xen/drivers/char/console.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/drivers/char/console.c Fri Jan 11 12:23:39 2013 +0000 @@ -406,13 +406,7 @@ long do_console_io(int cmd, int count, X long rc; unsigned int idx, len; -#ifndef VERBOSE - /* Only domain 0 may access the emergency console. */ - if ( current->domain->domain_id != 0 ) - return -EPERM; -#endif - - rc = xsm_console_io(current->domain, cmd); + rc = xsm_console_io(XSM_OTHER, current->domain, cmd); if ( rc ) return rc; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/drivers/passthrough/iommu.c --- a/xen/drivers/passthrough/iommu.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/drivers/passthrough/iommu.c Fri Jan 11 12:23:39 2013 +0000 @@ -514,7 +514,7 @@ static int iommu_get_device_group( ((pdev->bus == bus) && (pdev->devfn == devfn)) ) continue; - if ( xsm_get_device_group((seg << 16) | (pdev->bus << 8) | pdev->devfn) ) + if ( xsm_get_device_group(XSM_HOOK, (seg << 16) | (pdev->bus << 8) | pdev->devfn) ) continue; sdev_id = ops->get_device_group_id(seg, pdev->bus, pdev->devfn); @@ -617,7 +617,7 @@ int iommu_do_domctl( u32 max_sdevs; XEN_GUEST_HANDLE_64(uint32) sdevs; - ret = xsm_get_device_group(domctl->u.get_device_group.machine_sbdf); + ret = xsm_get_device_group(XSM_HOOK, domctl->u.get_device_group.machine_sbdf); if ( ret ) break; @@ -645,7 +645,7 @@ int iommu_do_domctl( break; case XEN_DOMCTL_test_assign_device: - ret = xsm_test_assign_device(domctl->u.assign_device.machine_sbdf); + ret = xsm_test_assign_device(XSM_HOOK, domctl->u.assign_device.machine_sbdf); if ( ret ) break; @@ -669,7 +669,7 @@ int iommu_do_domctl( break; } - ret = xsm_assign_device(d, domctl->u.assign_device.machine_sbdf); + ret = xsm_assign_device(XSM_HOOK, d, domctl->u.assign_device.machine_sbdf); if ( ret ) break; @@ -688,7 +688,7 @@ int iommu_do_domctl( break; case XEN_DOMCTL_deassign_device: - ret = xsm_deassign_device(d, domctl->u.assign_device.machine_sbdf); + ret = xsm_deassign_device(XSM_HOOK, d, domctl->u.assign_device.machine_sbdf); if ( ret ) break; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/drivers/passthrough/pci.c --- a/xen/drivers/passthrough/pci.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/drivers/passthrough/pci.c Fri Jan 11 12:23:39 2013 +0000 @@ -477,7 +477,7 @@ int pci_add_device(u16 seg, u8 bus, u8 d pdev_type = "device"; } - ret = xsm_resource_plug_pci((seg << 16) | (bus << 8) | devfn); + ret = xsm_resource_plug_pci(XSM_PRIV, (seg << 16) | (bus << 8) | devfn); if ( ret ) return ret; @@ -604,7 +604,7 @@ int pci_remove_device(u16 seg, u8 bus, u struct pci_dev *pdev; int ret; - ret = xsm_resource_unplug_pci((seg << 16) | (bus << 8) | devfn); + ret = xsm_resource_unplug_pci(XSM_PRIV, (seg << 16) | (bus << 8) | devfn); if ( ret ) return ret; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/include/asm-x86/mem_event.h --- a/xen/include/asm-x86/mem_event.h Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/include/asm-x86/mem_event.h Fri Jan 11 12:23:39 2013 +0000 @@ -62,7 +62,6 @@ void mem_event_put_request(struct domain int mem_event_get_response(struct domain *d, struct mem_event_domain *med, mem_event_response_t *rsp); -struct domain *get_mem_event_op_target(uint32_t domain, int *rc); int do_mem_event_op(int op, uint32_t domain, void *arg); int mem_event_domctl(struct domain *d, xen_domctl_mem_event_op_t *mec, XEN_GUEST_HANDLE_PARAM(void) u_domctl); diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/include/xen/sched.h --- a/xen/include/xen/sched.h Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/include/xen/sched.h Fri Jan 11 12:23:39 2013 +0000 @@ -484,6 +484,12 @@ int rcu_lock_remote_target_domain_by_id( */ int rcu_lock_remote_domain_by_id(domid_t dom, struct domain **d); +/* + * As rcu_lock_remote_domain_by_id() but will fail EINVAL if the domain is + * dying. + */ +int rcu_lock_live_remote_domain_by_id(domid_t dom, struct domain **d); + /* Finish a RCU critical region started by rcu_lock_domain_by_id(). */ static inline void rcu_unlock_domain(struct domain *d) { diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/include/xen/tmem_xen.h --- a/xen/include/xen/tmem_xen.h Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/include/xen/tmem_xen.h Fri Jan 11 12:23:39 2013 +0000 @@ -16,6 +16,7 @@ #include <xen/guest_access.h> /* copy_from_guest */ #include <xen/hash.h> /* hash_long */ #include <xen/domain_page.h> /* __map_domain_page */ +#include <xsm/xsm.h> /* xsm_tmem_control */ #include <public/tmem.h> #ifdef CONFIG_COMPAT #include <compat/tmem.h> @@ -326,9 +327,14 @@ static inline bool_t tmh_set_client_from return rc; } +static inline bool_t tmh_current_permitted(void) +{ + return !xsm_tmem_op(XSM_HOOK); +} + static inline bool_t tmh_current_is_privileged(void) { - return IS_PRIV(current->domain); + return !xsm_tmem_control(XSM_PRIV); } static inline uint8_t tmh_get_first_byte(pfp_t *pfp) diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/include/xsm/dummy.h --- a/xen/include/xsm/dummy.h Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/include/xsm/dummy.h Fri Jan 11 12:23:39 2013 +0000 @@ -6,167 +6,144 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation. + * + * + * Each XSM hook implementing an access check should have its first parameter + * preceded by XSM_DEFAULT_ARG (or use XSM_DEFAULT_VOID if it has no + * arguments). The first non-declaration statement shold be XSM_ASSERT_ACTION + * with the expected type of the hook, which will either define or check the + * value of action. */ #include <xen/sched.h> #include <xsm/xsm.h> +/* Cannot use BUILD_BUG_ON here because the expressions we check are not + * considered constant at compile time. Instead, rely on constant propagation to + * inline out the calls to this invalid function, which will cause linker errors + * if references remain at link time. + */ +#define LINKER_BUG_ON(x) do { if (x) __xsm_action_mismatch_detected(); } while (0) +/* DO NOT implement this function; it is supposed to trigger link errors */ +void __xsm_action_mismatch_detected(void); + +#ifdef XSM_ENABLE + +/* In XSM_ENABLE builds, this header file is included from xsm/dummy.c, and + * contains static (not inline) functions compiled to the dummy XSM module. + * There is no xsm_default_t argument available, so the value from the assertion + * is used to initialize the variable. + */ +#define XSM_INLINE /* */ +#define XSM_DEFAULT_ARG /* */ +#define XSM_DEFAULT_VOID void +#define XSM_ASSERT_ACTION(def) xsm_default_t action = def; (void)action + +#else /* XSM_ENABLE */ + +/* In !XSM_ENABLE builds, this header file is included from xsm/xsm.h, and + * contains inline functions for each XSM hook. These functions also perform + * compile-time checks on the xsm_default_t argument to ensure that the behavior + * of the dummy XSM module is the same as the behavior with XSM disabled. + */ +#define XSM_INLINE inline +#define XSM_DEFAULT_ARG xsm_default_t action, +#define XSM_DEFAULT_VOID xsm_default_t action +#define XSM_ASSERT_ACTION(def) LINKER_BUG_ON(def != action) + +#endif /* XSM_ENABLE */ + +static inline int xsm_default_action(xsm_default_t action, struct domain *src, + struct domain *target) +{ + switch ( action ) { + case XSM_HOOK: + return 0; + case XSM_DM_PRIV: + if ( !IS_PRIV_FOR(src, target) ) + return -EPERM; + return 0; + case XSM_TARGET: + if ( src != target && !IS_PRIV_FOR(src, target) ) + return -EPERM; + return 0; + case XSM_PRIV: + if ( !IS_PRIV(src) ) + return -EPERM; + return 0; + default: + LINKER_BUG_ON(1); + return -EPERM; + } +} + static XSM_INLINE void xsm_security_domaininfo(struct domain *d, struct xen_domctl_getdomaininfo *info) { return; } -static XSM_INLINE int xsm_setvcpucontext(struct domain *d) +static XSM_INLINE int xsm_domain_create(XSM_DEFAULT_ARG struct domain *d, u32 ssidref) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_pausedomain(struct domain *d) +static XSM_INLINE int xsm_getdomaininfo(XSM_DEFAULT_ARG struct domain *d) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_unpausedomain(struct domain *d) +static XSM_INLINE int xsm_domctl_scheduler_op(XSM_DEFAULT_ARG struct domain *d, int cmd) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_resumedomain(struct domain *d) +static XSM_INLINE int xsm_sysctl_scheduler_op(XSM_DEFAULT_ARG int cmd) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_domain_create(struct domain *d, u32 ssidref) +static XSM_INLINE int xsm_set_target(XSM_DEFAULT_ARG struct domain *d, struct domain *e) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_max_vcpus(struct domain *d) +static XSM_INLINE int xsm_domctl(XSM_DEFAULT_ARG struct domain *d, int cmd) { - return 0; + XSM_ASSERT_ACTION(XSM_OTHER); + switch ( cmd ) + { + case XEN_DOMCTL_ioport_mapping: + case XEN_DOMCTL_memory_mapping: + case XEN_DOMCTL_bind_pt_irq: + case XEN_DOMCTL_unbind_pt_irq: + return xsm_default_action(XSM_DM_PRIV, current->domain, d); + default: + return xsm_default_action(XSM_PRIV, current->domain, d); + } } -static XSM_INLINE int xsm_destroydomain(struct domain *d) +static XSM_INLINE int xsm_sysctl(XSM_DEFAULT_ARG int cmd) { - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_vcpuaffinity(int cmd, struct domain *d) +static XSM_INLINE int xsm_readconsole(XSM_DEFAULT_ARG uint32_t clear) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_scheduler(struct domain *d) +static XSM_INLINE int xsm_do_mca(XSM_DEFAULT_VOID) { - return 0; -} - -static XSM_INLINE int xsm_getdomaininfo(struct domain *d) -{ - if ( !IS_PRIV(current->domain) ) - return -EPERM; - return 0; -} - -static XSM_INLINE int xsm_getvcpucontext(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_getvcpuinfo(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_domain_settime(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_set_target(struct domain *d, struct domain *e) -{ - return 0; -} - -static XSM_INLINE int xsm_domctl(struct domain *d, int cmd) -{ - return 0; -} - -static XSM_INLINE int xsm_set_virq_handler(struct domain *d, uint32_t virq) -{ - return 0; -} - -static XSM_INLINE int xsm_tbufcontrol(void) -{ - return 0; -} - -static XSM_INLINE int xsm_readconsole(uint32_t clear) -{ - return 0; -} - -static XSM_INLINE int xsm_sched_id(void) -{ - return 0; -} - -static XSM_INLINE int xsm_setdomainmaxmem(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_setdomainhandle(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_setdebugging(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_perfcontrol(void) -{ - return 0; -} - -static XSM_INLINE int xsm_debug_keys(void) -{ - return 0; -} - -static XSM_INLINE int xsm_getcpuinfo(void) -{ - return 0; -} - -static XSM_INLINE int xsm_get_pmstat(void) -{ - return 0; -} - -static XSM_INLINE int xsm_setpminfo(void) -{ - return 0; -} - -static XSM_INLINE int xsm_pm_op(void) -{ - return 0; -} - -static XSM_INLINE int xsm_do_mca(void) -{ - return 0; -} - -static XSM_INLINE int xsm_availheap(void) -{ - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } static XSM_INLINE int xsm_alloc_security_domain(struct domain *d) @@ -179,84 +156,109 @@ static XSM_INLINE void xsm_free_security return; } -static XSM_INLINE int xsm_grant_mapref(struct domain *d1, struct domain *d2, +static XSM_INLINE int xsm_grant_mapref(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2, uint32_t flags) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_grant_unmapref(struct domain *d1, struct domain *d2) +static XSM_INLINE int xsm_grant_unmapref(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_grant_setup(struct domain *d1, struct domain *d2) +static XSM_INLINE int xsm_grant_setup(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_grant_transfer(struct domain *d1, struct domain *d2) +static XSM_INLINE int xsm_grant_transfer(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_grant_copy(struct domain *d1, struct domain *d2) +static XSM_INLINE int xsm_grant_copy(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_grant_query_size(struct domain *d1, struct domain *d2) +static XSM_INLINE int xsm_grant_query_size(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_memory_adjust_reservation(struct domain *d1, +static XSM_INLINE int xsm_memory_exchange(XSM_DEFAULT_ARG struct domain *d) +{ + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, current->domain, d); +} + +static XSM_INLINE int xsm_memory_adjust_reservation(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_memory_stat_reservation(struct domain *d1, struct domain *d2) +static XSM_INLINE int xsm_memory_stat_reservation(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_console_io(struct domain *d, int cmd) +static XSM_INLINE int xsm_console_io(XSM_DEFAULT_ARG struct domain *d, int cmd) { - return 0; + XSM_ASSERT_ACTION(XSM_OTHER); +#ifdef VERBOSE + return xsm_default_action(XSM_HOOK, current->domain, NULL); +#else + return xsm_default_action(XSM_PRIV, current->domain, NULL); +#endif } -static XSM_INLINE int xsm_profile(struct domain *d, int op) +static XSM_INLINE int xsm_profile(XSM_DEFAULT_ARG struct domain *d, int op) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_kexec(void) +static XSM_INLINE int xsm_kexec(XSM_DEFAULT_VOID) { - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_schedop_shutdown(struct domain *d1, struct domain *d2) +static XSM_INLINE int xsm_schedop_shutdown(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - return 0; + XSM_ASSERT_ACTION(XSM_DM_PRIV); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_memory_pin_page(struct domain *d1, struct domain *d2, +static XSM_INLINE int xsm_memory_pin_page(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2, struct page_info *page) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_evtchn_unbound(struct domain *d, struct evtchn *chn, +static XSM_INLINE int xsm_evtchn_unbound(XSM_DEFAULT_ARG struct domain *d, struct evtchn *chn, domid_t id2) { - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_evtchn_interdomain(struct domain *d1, struct evtchn +static XSM_INLINE int xsm_evtchn_interdomain(XSM_DEFAULT_ARG struct domain *d1, struct evtchn *chan1, struct domain *d2, struct evtchn *chan2) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, d1, d2); } static XSM_INLINE void xsm_evtchn_close_post(struct evtchn *chn) @@ -264,19 +266,22 @@ static XSM_INLINE void xsm_evtchn_close_ return; } -static XSM_INLINE int xsm_evtchn_send(struct domain *d, struct evtchn *chn) +static XSM_INLINE int xsm_evtchn_send(XSM_DEFAULT_ARG struct domain *d, struct evtchn *chn) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_evtchn_status(struct domain *d, struct evtchn *chn) +static XSM_INLINE int xsm_evtchn_status(XSM_DEFAULT_ARG struct domain *d, struct evtchn *chn) { - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_evtchn_reset(struct domain *d1, struct domain *d2) +static XSM_INLINE int xsm_evtchn_reset(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d1, d2); } static XSM_INLINE int xsm_alloc_security_evtchn(struct evtchn *chn) @@ -294,89 +299,100 @@ static XSM_INLINE char *xsm_show_securit return NULL; } -static XSM_INLINE int xsm_get_pod_target(struct domain *d) +static XSM_INLINE int xsm_get_pod_target(XSM_DEFAULT_ARG struct domain *d) { - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_set_pod_target(struct domain *d) +static XSM_INLINE int xsm_set_pod_target(XSM_DEFAULT_ARG struct domain *d) { - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_get_device_group(uint32_t machine_bdf) +static XSM_INLINE int xsm_get_device_group(XSM_DEFAULT_ARG uint32_t machine_bdf) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_test_assign_device(uint32_t machine_bdf) +static XSM_INLINE int xsm_test_assign_device(XSM_DEFAULT_ARG uint32_t machine_bdf) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_assign_device(struct domain *d, uint32_t machine_bdf) +static XSM_INLINE int xsm_assign_device(XSM_DEFAULT_ARG struct domain *d, uint32_t machine_bdf) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_deassign_device(struct domain *d, uint32_t machine_bdf) +static XSM_INLINE int xsm_deassign_device(XSM_DEFAULT_ARG struct domain *d, uint32_t machine_bdf) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_resource_plug_core(void) +static XSM_INLINE int xsm_resource_plug_core(XSM_DEFAULT_VOID) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_resource_unplug_core(void) +static XSM_INLINE int xsm_resource_unplug_core(XSM_DEFAULT_VOID) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_resource_plug_pci(uint32_t machine_bdf) +static XSM_INLINE int xsm_resource_plug_pci(XSM_DEFAULT_ARG uint32_t machine_bdf) { - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_resource_unplug_pci(uint32_t machine_bdf) +static XSM_INLINE int xsm_resource_unplug_pci(XSM_DEFAULT_ARG uint32_t machine_bdf) { - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_resource_setup_pci(uint32_t machine_bdf) +static XSM_INLINE int xsm_resource_setup_pci(XSM_DEFAULT_ARG uint32_t machine_bdf) { - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_resource_setup_gsi(int gsi) +static XSM_INLINE int xsm_resource_setup_gsi(XSM_DEFAULT_ARG int gsi) { - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_resource_setup_misc(void) +static XSM_INLINE int xsm_resource_setup_misc(XSM_DEFAULT_VOID) { - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_page_offline(uint32_t cmd) +static XSM_INLINE int xsm_page_offline(XSM_DEFAULT_ARG uint32_t cmd) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_lockprof(void) +static XSM_INLINE int xsm_tmem_op(XSM_DEFAULT_VOID) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_cpupool_op(void) +static XSM_INLINE int xsm_tmem_control(XSM_DEFAULT_VOID) { - return 0; -} - -static XSM_INLINE int xsm_sched_op(void) -{ - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } static XSM_INLINE long xsm_do_xsm_op(XEN_GUEST_HANDLE_PARAM(xsm_op_t) op) @@ -389,240 +405,179 @@ static XSM_INLINE char *xsm_show_irq_sid return NULL; } -static XSM_INLINE int xsm_map_domain_pirq(struct domain *d, int irq, void *data) +static XSM_INLINE int xsm_map_domain_pirq(XSM_DEFAULT_ARG struct domain *d, int irq, void *data) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_unmap_domain_pirq(struct domain *d, int irq) +static XSM_INLINE int xsm_unmap_domain_pirq(XSM_DEFAULT_ARG struct domain *d, int irq) { - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_irq_permission(struct domain *d, int pirq, uint8_t allow) +static XSM_INLINE int xsm_irq_permission(XSM_DEFAULT_ARG struct domain *d, int pirq, uint8_t allow) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_iomem_permission(struct domain *d, uint64_t s, uint64_t e, uint8_t allow) +static XSM_INLINE int xsm_iomem_permission(XSM_DEFAULT_ARG struct domain *d, uint64_t s, uint64_t e, uint8_t allow) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_iomem_mapping(struct domain *d, uint64_t s, uint64_t e, uint8_t allow) +static XSM_INLINE int xsm_iomem_mapping(XSM_DEFAULT_ARG struct domain *d, uint64_t s, uint64_t e, uint8_t allow) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_pci_config_permission(struct domain *d, uint32_t machine_bdf, +static XSM_INLINE int xsm_pci_config_permission(XSM_DEFAULT_ARG struct domain *d, uint32_t machine_bdf, uint16_t start, uint16_t end, uint8_t access) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } #ifdef CONFIG_X86 -static XSM_INLINE int xsm_shadow_control(struct domain *d, uint32_t op) +static XSM_INLINE int xsm_shadow_control(XSM_DEFAULT_ARG struct domain *d, uint32_t op) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_getpageframeinfo(struct domain *d) +static XSM_INLINE int xsm_hvm_param(XSM_DEFAULT_ARG struct domain *d, unsigned long op) { - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_getmemlist(struct domain *d) +static XSM_INLINE int xsm_hvm_set_pci_intx_level(XSM_DEFAULT_ARG struct domain *d) { - return 0; + XSM_ASSERT_ACTION(XSM_DM_PRIV); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_hypercall_init(struct domain *d) +static XSM_INLINE int xsm_hvm_set_isa_irq_level(XSM_DEFAULT_ARG struct domain *d) { - return 0; + XSM_ASSERT_ACTION(XSM_DM_PRIV); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_hvmcontext(struct domain *d, uint32_t cmd) +static XSM_INLINE int xsm_hvm_set_pci_link_route(XSM_DEFAULT_ARG struct domain *d) { - return 0; + XSM_ASSERT_ACTION(XSM_DM_PRIV); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_address_size(struct domain *d, uint32_t cmd) +static XSM_INLINE int xsm_hvm_inject_msi(XSM_DEFAULT_ARG struct domain *d) { - return 0; + XSM_ASSERT_ACTION(XSM_DM_PRIV); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_machine_address_size(struct domain *d, uint32_t cmd) +static XSM_INLINE int xsm_mem_event_control(XSM_DEFAULT_ARG struct domain *d, int mode, int op) { - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_hvm_param(struct domain *d, unsigned long op) +static XSM_INLINE int xsm_mem_event_op(XSM_DEFAULT_ARG struct domain *d, int op) { - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_hvm_set_pci_intx_level(struct domain *d) +static XSM_INLINE int xsm_mem_sharing_op(XSM_DEFAULT_ARG struct domain *d, struct domain *cd, int op) { - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, current->domain, cd); } -static XSM_INLINE int xsm_hvm_set_isa_irq_level(struct domain *d) +static XSM_INLINE int xsm_apic(XSM_DEFAULT_ARG struct domain *d, int cmd) { - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, d, NULL); } -static XSM_INLINE int xsm_hvm_set_pci_link_route(struct domain *d) +static XSM_INLINE int xsm_platform_op(XSM_DEFAULT_ARG uint32_t op) { - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_hvm_inject_msi(struct domain *d) +static XSM_INLINE int xsm_machine_memory_map(XSM_DEFAULT_VOID) { - return 0; + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); } -static XSM_INLINE int xsm_mem_event(struct domain *d) +static XSM_INLINE int xsm_domain_memory_map(XSM_DEFAULT_ARG struct domain *d) { - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_mem_sharing(struct domain *d) +static XSM_INLINE int xsm_mmu_update(XSM_DEFAULT_ARG struct domain *d, struct domain *t, + struct domain *f, uint32_t flags) { - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + if ( t && d != t && !IS_PRIV_FOR(d, t) ) + return -EPERM; + return xsm_default_action(action, d, f); } -static XSM_INLINE int xsm_apic(struct domain *d, int cmd) +static XSM_INLINE int xsm_mmuext_op(XSM_DEFAULT_ARG struct domain *d, struct domain *f) { - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d, f); } -static XSM_INLINE int xsm_xen_settime(void) +static XSM_INLINE int xsm_update_va_mapping(XSM_DEFAULT_ARG struct domain *d, struct domain *f, + l1_pgentry_t pte) { - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d, f); } -static XSM_INLINE int xsm_memtype(uint32_t access) +static XSM_INLINE int xsm_add_to_physmap(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_microcode(void) +static XSM_INLINE int xsm_remove_from_physmap(XSM_DEFAULT_ARG struct domain *d1, struct domain *d2) { - return 0; + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d1, d2); } -static XSM_INLINE int xsm_physinfo(void) +static XSM_INLINE int xsm_bind_pt_irq(XSM_DEFAULT_ARG struct domain *d, struct xen_domctl_bind_pt_irq *bind) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_platform_quirk(uint32_t quirk) +static XSM_INLINE int xsm_unbind_pt_irq(XSM_DEFAULT_ARG struct domain *d, struct xen_domctl_bind_pt_irq *bind) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_firmware_info(void) +static XSM_INLINE int xsm_ioport_permission(XSM_DEFAULT_ARG struct domain *d, uint32_t s, uint32_t e, uint8_t allow) { - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_efi_call(void) +static XSM_INLINE int xsm_ioport_mapping(XSM_DEFAULT_ARG struct domain *d, uint32_t s, uint32_t e, uint8_t allow) { - return 0; -} - -static XSM_INLINE int xsm_acpi_sleep(void) -{ - return 0; -} - -static XSM_INLINE int xsm_change_freq(void) -{ - return 0; -} - -static XSM_INLINE int xsm_getidletime(void) -{ - return 0; -} - -static XSM_INLINE int xsm_machine_memory_map(void) -{ - return 0; -} - -static XSM_INLINE int xsm_domain_memory_map(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_mmu_normal_update(struct domain *d, struct domain *t, - struct domain *f, intpte_t fpte) -{ - return 0; -} - -static XSM_INLINE int xsm_mmu_machphys_update(struct domain *d, struct domain *f, - unsigned long mfn) -{ - return 0; -} - -static XSM_INLINE int xsm_update_va_mapping(struct domain *d, struct domain *f, - l1_pgentry_t pte) -{ - return 0; -} - -static XSM_INLINE int xsm_add_to_physmap(struct domain *d1, struct domain *d2) -{ - return 0; -} - -static XSM_INLINE int xsm_remove_from_physmap(struct domain *d1, struct domain *d2) -{ - return 0; -} - -static XSM_INLINE int xsm_sendtrigger(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_bind_pt_irq(struct domain *d, struct xen_domctl_bind_pt_irq *bind) -{ - return 0; -} - -static XSM_INLINE int xsm_unbind_pt_irq(struct domain *d, struct xen_domctl_bind_pt_irq *bind) -{ - return 0; -} - -static XSM_INLINE int xsm_pin_mem_cacheattr(struct domain *d) -{ - return 0; -} - -static XSM_INLINE int xsm_ext_vcpucontext(struct domain *d, uint32_t cmd) -{ - return 0; -} - -static XSM_INLINE int xsm_vcpuextstate(struct domain *d, uint32_t cmd) -{ - return 0; -} - -static XSM_INLINE int xsm_ioport_permission(struct domain *d, uint32_t s, uint32_t e, uint8_t allow) -{ - return 0; -} - -static XSM_INLINE int xsm_ioport_mapping(struct domain *d, uint32_t s, uint32_t e, uint8_t allow) -{ - return 0; + XSM_ASSERT_ACTION(XSM_HOOK); + return xsm_default_action(action, current->domain, d); } #endif diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/include/xsm/xsm.h --- a/xen/include/xsm/xsm.h Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/include/xsm/xsm.h Fri Jan 11 12:23:39 2013 +0000 @@ -27,7 +27,17 @@ typedef u32 xsm_magic_t; #define XSM_MAGIC 0x00000000 #endif -#ifdef XSM_ENABLE +/* These annotations are used by callers and in dummy.h to document the + * default actions of XSM hooks. They should be compiled out otherwise. + */ +enum xsm_default { + XSM_HOOK, /* Guests can normally access the hypercall */ + XSM_DM_PRIV, /* Device model can perform on its target domain */ + XSM_TARGET, /* Can perform on self or your target domain */ + XSM_PRIV, /* Privileged - normally restricted to dom0 */ + XSM_OTHER /* Something more complex */ +}; +typedef enum xsm_default xsm_default_t; extern char *policy_buffer; extern u32 policy_size; @@ -43,35 +53,14 @@ extern xsm_initcall_t __xsm_initcall_sta struct xsm_operations { void (*security_domaininfo) (struct domain *d, struct xen_domctl_getdomaininfo *info); - int (*setvcpucontext) (struct domain *d); - int (*pausedomain) (struct domain *d); - int (*unpausedomain) (struct domain *d); - int (*resumedomain) (struct domain *d); int (*domain_create) (struct domain *d, u32 ssidref); - int (*max_vcpus) (struct domain *d); - int (*destroydomain) (struct domain *d); - int (*vcpuaffinity) (int cmd, struct domain *d); - int (*scheduler) (struct domain *d); int (*getdomaininfo) (struct domain *d); - int (*getvcpucontext) (struct domain *d); - int (*getvcpuinfo) (struct domain *d); - int (*domain_settime) (struct domain *d); + int (*domctl_scheduler_op) (struct domain *d, int op); + int (*sysctl_scheduler_op) (int op); int (*set_target) (struct domain *d, struct domain *e); int (*domctl) (struct domain *d, int cmd); - int (*set_virq_handler) (struct domain *d, uint32_t virq); - int (*tbufcontrol) (void); + int (*sysctl) (int cmd); int (*readconsole) (uint32_t clear); - int (*sched_id) (void); - int (*setdomainmaxmem) (struct domain *d); - int (*setdomainhandle) (struct domain *d); - int (*setdebugging) (struct domain *d); - int (*perfcontrol) (void); - int (*debug_keys) (void); - int (*getcpuinfo) (void); - int (*availheap) (void); - int (*get_pmstat) (void); - int (*setpminfo) (void); - int (*pm_op) (void); int (*do_mca) (void); int (*evtchn_unbound) (struct domain *d, struct evtchn *chn, domid_t id2); @@ -97,6 +86,7 @@ struct xsm_operations { int (*get_pod_target) (struct domain *d); int (*set_pod_target) (struct domain *d); + int (*memory_exchange) (struct domain *d); int (*memory_adjust_reservation) (struct domain *d1, struct domain *d2); int (*memory_stat_reservation) (struct domain *d1, struct domain *d2); int (*memory_pin_page) (struct domain *d1, struct domain *d2, struct page_info *page); @@ -131,56 +121,44 @@ struct xsm_operations { int (*resource_setup_misc) (void); int (*page_offline)(uint32_t cmd); - int (*lockprof)(void); - int (*cpupool_op)(void); - int (*sched_op)(void); + int (*tmem_op)(void); + int (*tmem_control)(void); long (*do_xsm_op) (XEN_GUEST_HANDLE_PARAM(xsm_op_t) op); #ifdef CONFIG_X86 int (*shadow_control) (struct domain *d, uint32_t op); - int (*getpageframeinfo) (struct domain *d); - int (*getmemlist) (struct domain *d); - int (*hypercall_init) (struct domain *d); - int (*hvmcontext) (struct domain *d, uint32_t op); - int (*address_size) (struct domain *d, uint32_t op); - int (*machine_address_size) (struct domain *d, uint32_t op); int (*hvm_param) (struct domain *d, unsigned long op); int (*hvm_set_pci_intx_level) (struct domain *d); int (*hvm_set_isa_irq_level) (struct domain *d); int (*hvm_set_pci_link_route) (struct domain *d); int (*hvm_inject_msi) (struct domain *d); - int (*mem_event) (struct domain *d); - int (*mem_sharing) (struct domain *d); + int (*mem_event_control) (struct domain *d, int mode, int op); + int (*mem_event_op) (struct domain *d, int op); + int (*mem_sharing_op) (struct domain *d, struct domain *cd, int op); int (*apic) (struct domain *d, int cmd); - int (*xen_settime) (void); int (*memtype) (uint32_t access); - int (*microcode) (void); - int (*physinfo) (void); - int (*platform_quirk) (uint32_t); - int (*firmware_info) (void); - int (*efi_call) (void); - int (*acpi_sleep) (void); - int (*change_freq) (void); - int (*getidletime) (void); + int (*platform_op) (uint32_t cmd); int (*machine_memory_map) (void); int (*domain_memory_map) (struct domain *d); - int (*mmu_normal_update) (struct domain *d, struct domain *t, - struct domain *f, intpte_t fpte); - int (*mmu_machphys_update) (struct domain *d1, struct domain *d2, unsigned long mfn); +#define XSM_MMU_UPDATE_READ 1 +#define XSM_MMU_UPDATE_WRITE 2 +#define XSM_MMU_NORMAL_UPDATE 4 +#define XSM_MMU_MACHPHYS_UPDATE 8 + int (*mmu_update) (struct domain *d, struct domain *t, + struct domain *f, uint32_t flags); + int (*mmuext_op) (struct domain *d, struct domain *f); int (*update_va_mapping) (struct domain *d, struct domain *f, l1_pgentry_t pte); int (*add_to_physmap) (struct domain *d1, struct domain *d2); - int (*sendtrigger) (struct domain *d); int (*bind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind); int (*unbind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind); - int (*pin_mem_cacheattr) (struct domain *d); - int (*ext_vcpucontext) (struct domain *d, uint32_t cmd); - int (*vcpuextstate) (struct domain *d, uint32_t cmd); int (*ioport_permission) (struct domain *d, uint32_t s, uint32_t e, uint8_t allow); int (*ioport_mapping) (struct domain *d, uint32_t s, uint32_t e, uint8_t allow); #endif }; +#ifdef XSM_ENABLE + extern struct xsm_operations *xsm_ops; #ifndef XSM_NO_WRAPPERS @@ -191,163 +169,58 @@ static inline void xsm_security_domainin xsm_ops->security_domaininfo(d, info); } -static inline int xsm_setvcpucontext(struct domain *d) -{ - return xsm_ops->setvcpucontext(d); -} - -static inline int xsm_pausedomain (struct domain *d) -{ - return xsm_ops->pausedomain(d); -} - -static inline int xsm_unpausedomain (struct domain *d) -{ - return xsm_ops->unpausedomain(d); -} - -static inline int xsm_resumedomain (struct domain *d) -{ - return xsm_ops->resumedomain(d); -} - -static inline int xsm_domain_create (struct domain *d, u32 ssidref) +static inline int xsm_domain_create (xsm_default_t def, struct domain *d, u32 ssidref) { return xsm_ops->domain_create(d, ssidref); } -static inline int xsm_max_vcpus(struct domain *d) -{ - return xsm_ops->max_vcpus(d); -} - -static inline int xsm_destroydomain (struct domain *d) -{ - return xsm_ops->destroydomain(d); -} - -static inline int xsm_vcpuaffinity (int cmd, struct domain *d) -{ - return xsm_ops->vcpuaffinity(cmd, d); -} - -static inline int xsm_scheduler (struct domain *d) -{ - return xsm_ops->scheduler(d); -} - -static inline int xsm_getdomaininfo (struct domain *d) +static inline int xsm_getdomaininfo (xsm_default_t def, struct domain *d) { return xsm_ops->getdomaininfo(d); } -static inline int xsm_getvcpucontext (struct domain *d) +static inline int xsm_domctl_scheduler_op (xsm_default_t def, struct domain *d, int cmd) { - return xsm_ops->getvcpucontext(d); + return xsm_ops->domctl_scheduler_op(d, cmd); } -static inline int xsm_getvcpuinfo (struct domain *d) +static inline int xsm_sysctl_scheduler_op (xsm_default_t def, int cmd) { - return xsm_ops->getvcpuinfo(d); + return xsm_ops->sysctl_scheduler_op(cmd); } -static inline int xsm_domain_settime (struct domain *d) -{ - return xsm_ops->domain_settime(d); -} - -static inline int xsm_set_target (struct domain *d, struct domain *e) +static inline int xsm_set_target (xsm_default_t def, struct domain *d, struct domain *e) { return xsm_ops->set_target(d, e); } -static inline int xsm_domctl (struct domain *d, int cmd) +static inline int xsm_domctl (xsm_default_t def, struct domain *d, int cmd) { return xsm_ops->domctl(d, cmd); } -static inline int xsm_set_virq_handler (struct domain *d, uint32_t virq) +static inline int xsm_sysctl (xsm_default_t def, int cmd) { - return xsm_ops->set_virq_handler(d, virq); + return xsm_ops->sysctl(cmd); } -static inline int xsm_tbufcontrol (void) -{ - return xsm_ops->tbufcontrol(); -} - -static inline int xsm_readconsole (uint32_t clear) +static inline int xsm_readconsole (xsm_default_t def, uint32_t clear) { return xsm_ops->readconsole(clear); } -static inline int xsm_sched_id (void) -{ - return xsm_ops->sched_id(); -} - -static inline int xsm_setdomainmaxmem (struct domain *d) -{ - return xsm_ops->setdomainmaxmem(d); -} - -static inline int xsm_setdomainhandle (struct domain *d) -{ - return xsm_ops->setdomainhandle(d); -} - -static inline int xsm_setdebugging (struct domain *d) -{ - return xsm_ops->setdebugging(d); -} - -static inline int xsm_perfcontrol (void) -{ - return xsm_ops->perfcontrol(); -} - -static inline int xsm_debug_keys (void) -{ - return xsm_ops->debug_keys(); -} - -static inline int xsm_availheap (void) -{ - return xsm_ops->availheap(); -} - -static inline int xsm_getcpuinfo (void) -{ - return xsm_ops->getcpuinfo(); -} - -static inline int xsm_get_pmstat(void) -{ - return xsm_ops->get_pmstat(); -} - -static inline int xsm_setpminfo(void) -{ - return xsm_ops->setpminfo(); -} - -static inline int xsm_pm_op(void) -{ - return xsm_ops->pm_op(); -} - -static inline int xsm_do_mca(void) +static inline int xsm_do_mca(xsm_default_t def) { return xsm_ops->do_mca(); } -static inline int xsm_evtchn_unbound (struct domain *d1, struct evtchn *chn, +static inline int xsm_evtchn_unbound (xsm_default_t def, struct domain *d1, struct evtchn *chn, domid_t id2) { return xsm_ops->evtchn_unbound(d1, chn, id2); } -static inline int xsm_evtchn_interdomain (struct domain *d1, +static inline int xsm_evtchn_interdomain (xsm_default_t def, struct domain *d1, struct evtchn *chan1, struct domain *d2, struct evtchn *chan2) { return xsm_ops->evtchn_interdomain(d1, chan1, d2, chan2); @@ -358,48 +231,48 @@ static inline void xsm_evtchn_close_post xsm_ops->evtchn_close_post(chn); } -static inline int xsm_evtchn_send (struct domain *d, struct evtchn *chn) +static inline int xsm_evtchn_send (xsm_default_t def, struct domain *d, struct evtchn *chn) { return xsm_ops->evtchn_send(d, chn); } -static inline int xsm_evtchn_status (struct domain *d, struct evtchn *chn) +static inline int xsm_evtchn_status (xsm_default_t def, struct domain *d, struct evtchn *chn) { return xsm_ops->evtchn_status(d, chn); } -static inline int xsm_evtchn_reset (struct domain *d1, struct domain *d2) +static inline int xsm_evtchn_reset (xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->evtchn_reset(d1, d2); } -static inline int xsm_grant_mapref (struct domain *d1, struct domain *d2, +static inline int xsm_grant_mapref (xsm_default_t def, struct domain *d1, struct domain *d2, uint32_t flags) { return xsm_ops->grant_mapref(d1, d2, flags); } -static inline int xsm_grant_unmapref (struct domain *d1, struct domain *d2) +static inline int xsm_grant_unmapref (xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->grant_unmapref(d1, d2); } -static inline int xsm_grant_setup (struct domain *d1, struct domain *d2) +static inline int xsm_grant_setup (xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->grant_setup(d1, d2); } -static inline int xsm_grant_transfer (struct domain *d1, struct domain *d2) +static inline int xsm_grant_transfer (xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->grant_transfer(d1, d2); } -static inline int xsm_grant_copy (struct domain *d1, struct domain *d2) +static inline int xsm_grant_copy (xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->grant_copy(d1, d2); } -static inline int xsm_grant_query_size (struct domain *d1, struct domain *d2) +static inline int xsm_grant_query_size (xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->grant_query_size(d1, d2); } @@ -429,55 +302,60 @@ static inline char *xsm_show_security_ev return xsm_ops->show_security_evtchn(d, chn); } -static inline int xsm_get_pod_target (struct domain *d) +static inline int xsm_get_pod_target (xsm_default_t def, struct domain *d) { return xsm_ops->get_pod_target(d); } -static inline int xsm_set_pod_target (struct domain *d) +static inline int xsm_set_pod_target (xsm_default_t def, struct domain *d) { return xsm_ops->set_pod_target(d); } -static inline int xsm_memory_adjust_reservation (struct domain *d1, struct +static inline int xsm_memory_exchange (xsm_default_t def, struct domain *d) +{ + return xsm_ops->memory_exchange(d); +} + +static inline int xsm_memory_adjust_reservation (xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->memory_adjust_reservation(d1, d2); } -static inline int xsm_memory_stat_reservation (struct domain *d1, +static inline int xsm_memory_stat_reservation (xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->memory_stat_reservation(d1, d2); } -static inline int xsm_memory_pin_page(struct domain *d1, struct domain *d2, +static inline int xsm_memory_pin_page(xsm_default_t def, struct domain *d1, struct domain *d2, struct page_info *page) { return xsm_ops->memory_pin_page(d1, d2, page); } -static inline int xsm_remove_from_physmap(struct domain *d1, struct domain *d2) +static inline int xsm_remove_from_physmap(xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->remove_from_physmap(d1, d2); } -static inline int xsm_console_io (struct domain *d, int cmd) +static inline int xsm_console_io (xsm_default_t def, struct domain *d, int cmd) { return xsm_ops->console_io(d, cmd); } -static inline int xsm_profile (struct domain *d, int op) +static inline int xsm_profile (xsm_default_t def, struct domain *d, int op) { return xsm_ops->profile(d, op); } -static inline int xsm_kexec (void) +static inline int xsm_kexec (xsm_default_t def) { return xsm_ops->kexec(); } -static inline int xsm_schedop_shutdown (struct domain *d1, struct domain *d2) +static inline int xsm_schedop_shutdown (xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->schedop_shutdown(d1, d2); } @@ -487,109 +365,104 @@ static inline char *xsm_show_irq_sid (in return xsm_ops->show_irq_sid(irq); } -static inline int xsm_map_domain_pirq (struct domain *d, int irq, void *data) +static inline int xsm_map_domain_pirq (xsm_default_t def, struct domain *d, int irq, void *data) { return xsm_ops->map_domain_pirq(d, irq, data); } -static inline int xsm_unmap_domain_pirq (struct domain *d, int irq) +static inline int xsm_unmap_domain_pirq (xsm_default_t def, struct domain *d, int irq) { return xsm_ops->unmap_domain_pirq(d, irq); } -static inline int xsm_irq_permission (struct domain *d, int pirq, uint8_t allow) +static inline int xsm_irq_permission (xsm_default_t def, struct domain *d, int pirq, uint8_t allow) { return xsm_ops->irq_permission(d, pirq, allow); } -static inline int xsm_iomem_permission (struct domain *d, uint64_t s, uint64_t e, uint8_t allow) +static inline int xsm_iomem_permission (xsm_default_t def, struct domain *d, uint64_t s, uint64_t e, uint8_t allow) { return xsm_ops->iomem_permission(d, s, e, allow); } -static inline int xsm_iomem_mapping (struct domain *d, uint64_t s, uint64_t e, uint8_t allow) +static inline int xsm_iomem_mapping (xsm_default_t def, struct domain *d, uint64_t s, uint64_t e, uint8_t allow) { return xsm_ops->iomem_mapping(d, s, e, allow); } -static inline int xsm_pci_config_permission (struct domain *d, uint32_t machine_bdf, uint16_t start, uint16_t end, uint8_t access) +static inline int xsm_pci_config_permission (xsm_default_t def, struct domain *d, uint32_t machine_bdf, uint16_t start, uint16_t end, uint8_t access) { return xsm_ops->pci_config_permission(d, machine_bdf, start, end, access); } -static inline int xsm_get_device_group(uint32_t machine_bdf) +static inline int xsm_get_device_group(xsm_default_t def, uint32_t machine_bdf) { return xsm_ops->get_device_group(machine_bdf); } -static inline int xsm_test_assign_device(uint32_t machine_bdf) +static inline int xsm_test_assign_device(xsm_default_t def, uint32_t machine_bdf) { return xsm_ops->test_assign_device(machine_bdf); } -static inline int xsm_assign_device(struct domain *d, uint32_t machine_bdf) +static inline int xsm_assign_device(xsm_default_t def, struct domain *d, uint32_t machine_bdf) { return xsm_ops->assign_device(d, machine_bdf); } -static inline int xsm_deassign_device(struct domain *d, uint32_t machine_bdf) +static inline int xsm_deassign_device(xsm_default_t def, struct domain *d, uint32_t machine_bdf) { return xsm_ops->deassign_device(d, machine_bdf); } -static inline int xsm_resource_plug_pci (uint32_t machine_bdf) +static inline int xsm_resource_plug_pci (xsm_default_t def, uint32_t machine_bdf) { return xsm_ops->resource_plug_pci(machine_bdf); } -static inline int xsm_resource_unplug_pci (uint32_t machine_bdf) +static inline int xsm_resource_unplug_pci (xsm_default_t def, uint32_t machine_bdf) { return xsm_ops->resource_unplug_pci(machine_bdf); } -static inline int xsm_resource_plug_core (void) +static inline int xsm_resource_plug_core (xsm_default_t def) { return xsm_ops->resource_plug_core(); } -static inline int xsm_resource_unplug_core (void) +static inline int xsm_resource_unplug_core (xsm_default_t def) { return xsm_ops->resource_unplug_core(); } -static inline int xsm_resource_setup_pci (uint32_t machine_bdf) +static inline int xsm_resource_setup_pci (xsm_default_t def, uint32_t machine_bdf) { return xsm_ops->resource_setup_pci(machine_bdf); } -static inline int xsm_resource_setup_gsi (int gsi) +static inline int xsm_resource_setup_gsi (xsm_default_t def, int gsi) { return xsm_ops->resource_setup_gsi(gsi); } -static inline int xsm_resource_setup_misc (void) +static inline int xsm_resource_setup_misc (xsm_default_t def) { return xsm_ops->resource_setup_misc(); } -static inline int xsm_page_offline(uint32_t cmd) +static inline int xsm_page_offline(xsm_default_t def, uint32_t cmd) { return xsm_ops->page_offline(cmd); } -static inline int xsm_lockprof(void) +static inline int xsm_tmem_op(xsm_default_t def) { - return xsm_ops->lockprof(); + return xsm_ops->tmem_op(); } -static inline int xsm_cpupool_op(void) +static inline int xsm_tmem_control(xsm_default_t def) { - return xsm_ops->cpupool_op(); -} - -static inline int xsm_sched_op(void) -{ - return xsm_ops->sched_op(); + return xsm_ops->tmem_control(); } static inline long xsm_do_xsm_op (XEN_GUEST_HANDLE_PARAM(xsm_op_t) op) @@ -598,201 +471,116 @@ static inline long xsm_do_xsm_op (XEN_GU } #ifdef CONFIG_X86 -static inline int xsm_shadow_control (struct domain *d, uint32_t op) +static inline int xsm_shadow_control (xsm_default_t def, struct domain *d, uint32_t op) { return xsm_ops->shadow_control(d, op); } -static inline int xsm_getpageframeinfo (struct domain *d) -{ - return xsm_ops->getpageframeinfo(d); -} - -static inline int xsm_getmemlist (struct domain *d) -{ - return xsm_ops->getmemlist(d); -} - -static inline int xsm_hypercall_init (struct domain *d) -{ - return xsm_ops->hypercall_init(d); -} - -static inline int xsm_hvmcontext (struct domain *d, uint32_t cmd) -{ - return xsm_ops->hvmcontext(d, cmd); -} - -static inline int xsm_address_size (struct domain *d, uint32_t cmd) -{ - return xsm_ops->address_size(d, cmd); -} - -static inline int xsm_machine_address_size (struct domain *d, uint32_t cmd) -{ - return xsm_ops->machine_address_size(d, cmd); -} - -static inline int xsm_hvm_param (struct domain *d, unsigned long op) +static inline int xsm_hvm_param (xsm_default_t def, struct domain *d, unsigned long op) { return xsm_ops->hvm_param(d, op); } -static inline int xsm_hvm_set_pci_intx_level (struct domain *d) +static inline int xsm_hvm_set_pci_intx_level (xsm_default_t def, struct domain *d) { return xsm_ops->hvm_set_pci_intx_level(d); } -static inline int xsm_hvm_set_isa_irq_level (struct domain *d) +static inline int xsm_hvm_set_isa_irq_level (xsm_default_t def, struct domain *d) { return xsm_ops->hvm_set_isa_irq_level(d); } -static inline int xsm_hvm_set_pci_link_route (struct domain *d) +static inline int xsm_hvm_set_pci_link_route (xsm_default_t def, struct domain *d) { return xsm_ops->hvm_set_pci_link_route(d); } -static inline int xsm_hvm_inject_msi (struct domain *d) +static inline int xsm_hvm_inject_msi (xsm_default_t def, struct domain *d) { return xsm_ops->hvm_inject_msi(d); } -static inline int xsm_mem_event (struct domain *d) +static inline int xsm_mem_event_control (xsm_default_t def, struct domain *d, int mode, int op) { - return xsm_ops->mem_event(d); + return xsm_ops->mem_event_control(d, mode, op); } -static inline int xsm_mem_sharing (struct domain *d) +static inline int xsm_mem_event_op (xsm_default_t def, struct domain *d, int op) { - return xsm_ops->mem_sharing(d); + return xsm_ops->mem_event_op(d, op); } -static inline int xsm_apic (struct domain *d, int cmd) +static inline int xsm_mem_sharing_op (xsm_default_t def, struct domain *d, struct domain *cd, int op) +{ + return xsm_ops->mem_sharing_op(d, cd, op); +} + +static inline int xsm_apic (xsm_default_t def, struct domain *d, int cmd) { return xsm_ops->apic(d, cmd); } -static inline int xsm_xen_settime (void) -{ - return xsm_ops->xen_settime(); -} - -static inline int xsm_memtype (uint32_t access) +static inline int xsm_memtype (xsm_default_t def, uint32_t access) { return xsm_ops->memtype(access); } -static inline int xsm_microcode (void) +static inline int xsm_platform_op (xsm_default_t def, uint32_t op) { - return xsm_ops->microcode(); + return xsm_ops->platform_op(op); } -static inline int xsm_physinfo (void) -{ - return xsm_ops->physinfo(); -} - -static inline int xsm_platform_quirk (uint32_t quirk) -{ - return xsm_ops->platform_quirk(quirk); -} - -static inline int xsm_firmware_info (void) -{ - return xsm_ops->firmware_info(); -} - -static inline int xsm_efi_call (void) -{ - return xsm_ops->efi_call(); -} - -static inline int xsm_acpi_sleep (void) -{ - return xsm_ops->acpi_sleep(); -} - -static inline int xsm_change_freq (void) -{ - return xsm_ops->change_freq(); -} - -static inline int xsm_getidletime (void) -{ - return xsm_ops->getidletime(); -} - -static inline int xsm_machine_memory_map(void) +static inline int xsm_machine_memory_map(xsm_default_t def) { return xsm_ops->machine_memory_map(); } -static inline int xsm_domain_memory_map(struct domain *d) +static inline int xsm_domain_memory_map(xsm_default_t def, struct domain *d) { return xsm_ops->domain_memory_map(d); } -static inline int xsm_mmu_normal_update (struct domain *d, struct domain *t, - struct domain *f, intpte_t fpte) +static inline int xsm_mmu_update (xsm_default_t def, struct domain *d, struct domain *t, + struct domain *f, uint32_t flags) { - return xsm_ops->mmu_normal_update(d, t, f, fpte); + return xsm_ops->mmu_update(d, t, f, flags); } -static inline int xsm_mmu_machphys_update (struct domain *d1, struct domain *d2, - unsigned long mfn) +static inline int xsm_mmuext_op (xsm_default_t def, struct domain *d, struct domain *f) { - return xsm_ops->mmu_machphys_update(d1, d2, mfn); + return xsm_ops->mmuext_op(d, f); } -static inline int xsm_update_va_mapping(struct domain *d, struct domain *f, +static inline int xsm_update_va_mapping(xsm_default_t def, struct domain *d, struct domain *f, l1_pgentry_t pte) { return xsm_ops->update_va_mapping(d, f, pte); } -static inline int xsm_add_to_physmap(struct domain *d1, struct domain *d2) +static inline int xsm_add_to_physmap(xsm_default_t def, struct domain *d1, struct domain *d2) { return xsm_ops->add_to_physmap(d1, d2); } -static inline int xsm_sendtrigger(struct domain *d) -{ - return xsm_ops->sendtrigger(d); -} - -static inline int xsm_bind_pt_irq(struct domain *d, +static inline int xsm_bind_pt_irq(xsm_default_t def, struct domain *d, struct xen_domctl_bind_pt_irq *bind) { return xsm_ops->bind_pt_irq(d, bind); } -static inline int xsm_unbind_pt_irq(struct domain *d, +static inline int xsm_unbind_pt_irq(xsm_default_t def, struct domain *d, struct xen_domctl_bind_pt_irq *bind) { return xsm_ops->unbind_pt_irq(d, bind); } -static inline int xsm_pin_mem_cacheattr(struct domain *d) -{ - return xsm_ops->pin_mem_cacheattr(d); -} - -static inline int xsm_ext_vcpucontext(struct domain *d, uint32_t cmd) -{ - return xsm_ops->ext_vcpucontext(d, cmd); -} -static inline int xsm_vcpuextstate(struct domain *d, uint32_t cmd) -{ - return xsm_ops->vcpuextstate(d, cmd); -} - -static inline int xsm_ioport_permission (struct domain *d, uint32_t s, uint32_t e, uint8_t allow) +static inline int xsm_ioport_permission (xsm_default_t def, struct domain *d, uint32_t s, uint32_t e, uint8_t allow) { return xsm_ops->ioport_permission(d, s, e, allow); } -static inline int xsm_ioport_mapping (struct domain *d, uint32_t s, uint32_t e, uint8_t allow) +static inline int xsm_ioport_mapping (xsm_default_t def, struct domain *d, uint32_t s, uint32_t e, uint8_t allow) { return xsm_ops->ioport_mapping(d, s, e, allow); } @@ -812,7 +600,6 @@ extern void xsm_fixup_ops(struct xsm_ope #else /* XSM_ENABLE */ -#define XSM_INLINE inline #include <xsm/dummy.h> static inline int xsm_init (unsigned long *module_map, diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/xsm/dummy.c --- a/xen/xsm/dummy.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/xsm/dummy.c Fri Jan 11 12:23:39 2013 +0000 @@ -30,35 +30,14 @@ struct xsm_operations dummy_xsm_ops; void xsm_fixup_ops (struct xsm_operations *ops) { set_to_dummy_if_null(ops, security_domaininfo); - set_to_dummy_if_null(ops, setvcpucontext); - set_to_dummy_if_null(ops, pausedomain); - set_to_dummy_if_null(ops, unpausedomain); - set_to_dummy_if_null(ops, resumedomain); set_to_dummy_if_null(ops, domain_create); - set_to_dummy_if_null(ops, max_vcpus); - set_to_dummy_if_null(ops, destroydomain); - set_to_dummy_if_null(ops, vcpuaffinity); - set_to_dummy_if_null(ops, scheduler); set_to_dummy_if_null(ops, getdomaininfo); - set_to_dummy_if_null(ops, getvcpucontext); - set_to_dummy_if_null(ops, getvcpuinfo); - set_to_dummy_if_null(ops, domain_settime); + set_to_dummy_if_null(ops, domctl_scheduler_op); + set_to_dummy_if_null(ops, sysctl_scheduler_op); set_to_dummy_if_null(ops, set_target); set_to_dummy_if_null(ops, domctl); - set_to_dummy_if_null(ops, set_virq_handler); - set_to_dummy_if_null(ops, tbufcontrol); + set_to_dummy_if_null(ops, sysctl); set_to_dummy_if_null(ops, readconsole); - set_to_dummy_if_null(ops, sched_id); - set_to_dummy_if_null(ops, setdomainmaxmem); - set_to_dummy_if_null(ops, setdomainhandle); - set_to_dummy_if_null(ops, setdebugging); - set_to_dummy_if_null(ops, perfcontrol); - set_to_dummy_if_null(ops, debug_keys); - set_to_dummy_if_null(ops, getcpuinfo); - set_to_dummy_if_null(ops, availheap); - set_to_dummy_if_null(ops, get_pmstat); - set_to_dummy_if_null(ops, setpminfo); - set_to_dummy_if_null(ops, pm_op); set_to_dummy_if_null(ops, do_mca); set_to_dummy_if_null(ops, evtchn_unbound); @@ -83,6 +62,7 @@ void xsm_fixup_ops (struct xsm_operation set_to_dummy_if_null(ops, get_pod_target); set_to_dummy_if_null(ops, set_pod_target); + set_to_dummy_if_null(ops, memory_exchange); set_to_dummy_if_null(ops, memory_adjust_reservation); set_to_dummy_if_null(ops, memory_stat_reservation); set_to_dummy_if_null(ops, memory_pin_page); @@ -116,51 +96,32 @@ void xsm_fixup_ops (struct xsm_operation set_to_dummy_if_null(ops, resource_setup_misc); set_to_dummy_if_null(ops, page_offline); - set_to_dummy_if_null(ops, lockprof); - set_to_dummy_if_null(ops, cpupool_op); - set_to_dummy_if_null(ops, sched_op); + set_to_dummy_if_null(ops, tmem_op); + set_to_dummy_if_null(ops, tmem_control); set_to_dummy_if_null(ops, do_xsm_op); #ifdef CONFIG_X86 set_to_dummy_if_null(ops, shadow_control); - set_to_dummy_if_null(ops, getpageframeinfo); - set_to_dummy_if_null(ops, getmemlist); - set_to_dummy_if_null(ops, hypercall_init); - set_to_dummy_if_null(ops, hvmcontext); - set_to_dummy_if_null(ops, address_size); - set_to_dummy_if_null(ops, machine_address_size); set_to_dummy_if_null(ops, hvm_param); set_to_dummy_if_null(ops, hvm_set_pci_intx_level); set_to_dummy_if_null(ops, hvm_set_isa_irq_level); set_to_dummy_if_null(ops, hvm_set_pci_link_route); set_to_dummy_if_null(ops, hvm_inject_msi); - set_to_dummy_if_null(ops, mem_event); - set_to_dummy_if_null(ops, mem_sharing); + set_to_dummy_if_null(ops, mem_event_control); + set_to_dummy_if_null(ops, mem_event_op); + set_to_dummy_if_null(ops, mem_sharing_op); set_to_dummy_if_null(ops, apic); - set_to_dummy_if_null(ops, xen_settime); - set_to_dummy_if_null(ops, memtype); - set_to_dummy_if_null(ops, microcode); - set_to_dummy_if_null(ops, physinfo); - set_to_dummy_if_null(ops, platform_quirk); - set_to_dummy_if_null(ops, firmware_info); - set_to_dummy_if_null(ops, efi_call); - set_to_dummy_if_null(ops, acpi_sleep); - set_to_dummy_if_null(ops, change_freq); - set_to_dummy_if_null(ops, getidletime); + set_to_dummy_if_null(ops, platform_op); set_to_dummy_if_null(ops, machine_memory_map); set_to_dummy_if_null(ops, domain_memory_map); - set_to_dummy_if_null(ops, mmu_normal_update); - set_to_dummy_if_null(ops, mmu_machphys_update); + set_to_dummy_if_null(ops, mmu_update); + set_to_dummy_if_null(ops, mmuext_op); set_to_dummy_if_null(ops, update_va_mapping); set_to_dummy_if_null(ops, add_to_physmap); set_to_dummy_if_null(ops, remove_from_physmap); - set_to_dummy_if_null(ops, sendtrigger); set_to_dummy_if_null(ops, bind_pt_irq); set_to_dummy_if_null(ops, unbind_pt_irq); - set_to_dummy_if_null(ops, pin_mem_cacheattr); - set_to_dummy_if_null(ops, ext_vcpucontext); - set_to_dummy_if_null(ops, vcpuextstate); set_to_dummy_if_null(ops, ioport_permission); set_to_dummy_if_null(ops, ioport_mapping); #endif diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/xsm/flask/flask_op.c --- a/xen/xsm/flask/flask_op.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/xsm/flask/flask_op.c Fri Jan 11 12:23:39 2013 +0000 @@ -612,6 +612,15 @@ static int flask_relabel_domain(struct x goto out; dsec->sid = arg->sid; + dsec->self_sid = arg->sid; + security_transition_sid(dsec->sid, dsec->sid, SECCLASS_DOMAIN, + &dsec->self_sid); + if ( d->target ) + { + struct domain_security_struct *tsec = d->target->ssid; + security_transition_sid(tsec->sid, dsec->sid, SECCLASS_DOMAIN, + &dsec->target_sid); + } out: rcu_unlock_domain(d); diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/xsm/flask/hooks.c --- a/xen/xsm/flask/hooks.c Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/xsm/flask/hooks.c Fri Jan 11 12:23:39 2013 +0000 @@ -33,38 +33,69 @@ struct xsm_operations *original_ops = NULL; +static u32 domain_sid(struct domain *dom) +{ + struct domain_security_struct *dsec = dom->ssid; + return dsec->sid; +} + +static u32 domain_target_sid(struct domain *src, struct domain *dst) +{ + struct domain_security_struct *ssec = src->ssid; + struct domain_security_struct *dsec = dst->ssid; + if (src == dst) + return ssec->self_sid; + if (src->target == dst) + return ssec->target_sid; + return dsec->sid; +} + +static u32 evtchn_sid(const struct evtchn *chn) +{ + struct evtchn_security_struct *esec = chn->ssid; + return esec->sid; +} + static int domain_has_perm(struct domain *dom1, struct domain *dom2, u16 class, u32 perms) { - struct domain_security_struct *dsec1, *dsec2; + u32 ssid, tsid; struct avc_audit_data ad; AVC_AUDIT_DATA_INIT(&ad, NONE); ad.sdom = dom1; ad.tdom = dom2; - dsec1 = dom1->ssid; - dsec2 = dom2->ssid; + ssid = domain_sid(dom1); + tsid = domain_target_sid(dom1, dom2); - return avc_has_perm(dsec1->sid, dsec2->sid, class, perms, &ad); + return avc_has_perm(ssid, tsid, class, perms, &ad); +} + +static int avc_current_has_perm(u32 tsid, u16 class, u32 perm, + struct avc_audit_data *ad) +{ + u32 csid = domain_sid(current->domain); + return avc_has_perm(csid, tsid, class, perm, ad); +} + +static int current_has_perm(struct domain *d, u16 class, u32 perms) +{ + return domain_has_perm(current->domain, d, class, perms); } static int domain_has_evtchn(struct domain *d, struct evtchn *chn, u32 perms) { - struct domain_security_struct *dsec; - struct evtchn_security_struct *esec; + u32 dsid = domain_sid(d); + u32 esid = evtchn_sid(chn); - dsec = d->ssid; - esec = chn->ssid; - - return avc_has_perm(dsec->sid, esec->sid, SECCLASS_EVENT, perms, NULL); + return avc_has_perm(dsid, esid, SECCLASS_EVENT, perms, NULL); } static int domain_has_xen(struct domain *d, u32 perms) { - struct domain_security_struct *dsec; - dsec = d->ssid; + u32 dsid = domain_sid(d); - return avc_has_perm(dsec->sid, SECINITSID_XEN, SECCLASS_XEN, perms, NULL); + return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_XEN, perms, NULL); } static int get_irq_sid(int irq, u32 *sid, struct avc_audit_data *ad) @@ -123,6 +154,7 @@ static int flask_domain_alloc_security(s dsec->sid = SECINITSID_UNLABELED; } + dsec->self_sid = dsec->sid; d->ssid = dsec; return 0; @@ -142,68 +174,55 @@ static void flask_domain_free_security(s static int flask_evtchn_unbound(struct domain *d1, struct evtchn *chn, domid_t id2) { - u32 newsid; + u32 sid1, sid2, newsid; int rc; - domid_t id; struct domain *d2; - struct domain_security_struct *dsec, *dsec1, *dsec2; struct evtchn_security_struct *esec; - dsec = current->domain->ssid; - dsec1 = d1->ssid; - esec = chn->ssid; - - if ( id2 == DOMID_SELF ) - id = current->domain->domain_id; - else - id = id2; - - d2 = get_domain_by_id(id); + d2 = rcu_lock_domain_by_any_id(id2); if ( d2 == NULL ) return -EPERM; - dsec2 = d2->ssid; - rc = security_transition_sid(dsec1->sid, dsec2->sid, SECCLASS_EVENT, - &newsid); + sid1 = domain_sid(d1); + sid2 = domain_target_sid(d1, d2); + esec = chn->ssid; + + rc = security_transition_sid(sid1, sid2, SECCLASS_EVENT, &newsid); if ( rc ) goto out; - rc = avc_has_perm(dsec->sid, newsid, SECCLASS_EVENT, EVENT__CREATE, NULL); + rc = avc_current_has_perm(newsid, SECCLASS_EVENT, EVENT__CREATE, NULL); if ( rc ) goto out; - rc = avc_has_perm(newsid, dsec2->sid, SECCLASS_EVENT, EVENT__BIND, NULL); + rc = avc_has_perm(newsid, sid2, SECCLASS_EVENT, EVENT__BIND, NULL); if ( rc ) goto out; - else - esec->sid = newsid; + + esec->sid = newsid; out: - put_domain(d2); + rcu_unlock_domain(d2); return rc; } static int flask_evtchn_interdomain(struct domain *d1, struct evtchn *chn1, struct domain *d2, struct evtchn *chn2) { - u32 newsid; + u32 sid1, sid2, newsid, reverse_sid; int rc; - struct domain_security_struct *dsec, *dsec1, *dsec2; - struct evtchn_security_struct *esec1, *esec2; + struct evtchn_security_struct *esec1; struct avc_audit_data ad; AVC_AUDIT_DATA_INIT(&ad, NONE); ad.sdom = d1; ad.tdom = d2; - dsec = current->domain->ssid; - dsec1 = d1->ssid; - dsec2 = d2->ssid; + sid1 = domain_sid(d1); + sid2 = domain_target_sid(d1, d2); esec1 = chn1->ssid; - esec2 = chn2->ssid; - rc = security_transition_sid(dsec1->sid, dsec2->sid, - SECCLASS_EVENT, &newsid); + rc = security_transition_sid(sid1, sid2, SECCLASS_EVENT, &newsid); if ( rc ) { printk("%s: security_transition_sid failed, rc=%d (domain=%d)\n", @@ -211,15 +230,20 @@ static int flask_evtchn_interdomain(stru return rc; } - rc = avc_has_perm(dsec->sid, newsid, SECCLASS_EVENT, EVENT__CREATE, &ad); + rc = avc_current_has_perm(newsid, SECCLASS_EVENT, EVENT__CREATE, &ad); if ( rc ) return rc; - rc = avc_has_perm(newsid, dsec2->sid, SECCLASS_EVENT, EVENT__BIND, &ad); + rc = avc_has_perm(newsid, sid2, SECCLASS_EVENT, EVENT__BIND, &ad); if ( rc ) return rc; - rc = avc_has_perm(esec2->sid, dsec1->sid, SECCLASS_EVENT, EVENT__BIND, &ad); + /* It's possible the target domain has changed (relabel or destroy/create) + * since the unbound part was created; re-validate this binding now. + */ + reverse_sid = evtchn_sid(chn2); + sid1 = domain_target_sid(d2, d1); + rc = avc_has_perm(reverse_sid, sid1, SECCLASS_EVENT, EVENT__BIND, &ad); if ( rc ) return rc; @@ -302,7 +326,6 @@ static void flask_free_security_evtchn(s static char *flask_show_security_evtchn(struct domain *d, const struct evtchn *chn) { - struct evtchn_security_struct *esec; int irq; u32 sid = 0; char *ctx; @@ -312,9 +335,7 @@ static char *flask_show_security_evtchn( { case ECS_UNBOUND: case ECS_INTERDOMAIN: - esec = chn->ssid; - if ( esec ) - sid = esec->sid; + sid = evtchn_sid(chn); break; case ECS_PIRQ: irq = domain_pirq_to_irq(d, chn->u.pirq.irq); @@ -367,12 +388,17 @@ static int flask_grant_query_size(struct static int flask_get_pod_target(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__GETPODTARGET); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETPODTARGET); } static int flask_set_pod_target(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__SETPODTARGET); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETPODTARGET); +} + +static int flask_memory_exchange(struct domain *d) +{ + return current_has_perm(d, SECCLASS_MMU, MMU__EXCHANGE); } static int flask_memory_adjust_reservation(struct domain *d1, struct domain *d2) @@ -455,144 +481,304 @@ static int flask_schedop_shutdown(struct static void flask_security_domaininfo(struct domain *d, struct xen_domctl_getdomaininfo *info) { - struct domain_security_struct *dsec; - - dsec = d->ssid; - info->ssidref = dsec->sid; -} - -static int flask_setvcpucontext(struct domain *d) -{ - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__SETVCPUCONTEXT); -} - -static int flask_pausedomain(struct domain *d) -{ - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__PAUSE); -} - -static int flask_unpausedomain(struct domain *d) -{ - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__UNPAUSE); -} - -static int flask_resumedomain(struct domain *d) -{ - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__RESUME); + info->ssidref = domain_sid(d); } static int flask_domain_create(struct domain *d, u32 ssidref) { int rc; - struct domain_security_struct *dsec1; - struct domain_security_struct *dsec2; + struct domain_security_struct *dsec = d->ssid; static int dom0_created = 0; - dsec1 = current->domain->ssid; - dsec2 = d->ssid; - if ( is_idle_domain(current->domain) && !dom0_created ) { - dsec2->sid = SECINITSID_DOM0; + dsec->sid = SECINITSID_DOM0; dom0_created = 1; - return 0; } + else + { + rc = avc_current_has_perm(ssidref, SECCLASS_DOMAIN, + DOMAIN__CREATE, NULL); + if ( rc ) + return rc; - rc = avc_has_perm(dsec1->sid, ssidref, SECCLASS_DOMAIN, - DOMAIN__CREATE, NULL); - if ( rc ) - return rc; + dsec->sid = ssidref; + } + dsec->self_sid = dsec->sid; - dsec2->sid = ssidref; + rc = security_transition_sid(dsec->sid, dsec->sid, SECCLASS_DOMAIN, + &dsec->self_sid); return rc; } -static int flask_max_vcpus(struct domain *d) +static int flask_getdomaininfo(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__MAX_VCPUS); + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETDOMAININFO); } -static int flask_destroydomain(struct domain *d) +static int flask_domctl_scheduler_op(struct domain *d, int op) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__DESTROY); + switch ( op ) + { + case XEN_DOMCTL_SCHEDOP_putinfo: + return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__SETSCHEDULER); + + case XEN_DOMCTL_SCHEDOP_getinfo: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETSCHEDULER); + + default: + printk("flask_domctl_scheduler_op: Unknown op %d\n", op); + return -EPERM; + } } -static int flask_vcpuaffinity(int cmd, struct domain *d) +static int flask_sysctl_scheduler_op(int op) { - u32 perm; + switch ( op ) + { + case XEN_DOMCTL_SCHEDOP_putinfo: + return domain_has_xen(current->domain, XEN__SETSCHEDULER); - switch ( cmd ) - { - case XEN_DOMCTL_setvcpuaffinity: - perm = DOMAIN__SETVCPUAFFINITY; - break; - case XEN_DOMCTL_getvcpuaffinity: - perm = DOMAIN__GETVCPUAFFINITY; - break; + case XEN_DOMCTL_SCHEDOP_getinfo: + return domain_has_xen(current->domain, XEN__GETSCHEDULER); + default: + printk("flask_domctl_scheduler_op: Unknown op %d\n", op); return -EPERM; } - - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm ); } -static int flask_scheduler(struct domain *d) +static int flask_set_target(struct domain *d, struct domain *t) { - int rc = 0; + int rc; + struct domain_security_struct *dsec, *tsec; + dsec = d->ssid; + tsec = t->ssid; - rc = domain_has_xen(current->domain, XEN__SCHEDULER); + rc = current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__MAKE_PRIV_FOR); + if ( rc ) + return rc; + rc = current_has_perm(t, SECCLASS_DOMAIN2, DOMAIN2__SET_AS_TARGET); + if ( rc ) + return rc; + /* Use avc_has_perm to avoid resolving target/current SID */ + rc = avc_has_perm(dsec->sid, tsec->sid, SECCLASS_DOMAIN, DOMAIN__SET_TARGET, NULL); if ( rc ) return rc; - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__SCHEDULER); -} - -static int flask_getdomaininfo(struct domain *d) -{ - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__GETDOMAININFO); -} - -static int flask_getvcpucontext(struct domain *d) -{ - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__GETVCPUCONTEXT); -} - -static int flask_getvcpuinfo(struct domain *d) -{ - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__GETVCPUINFO); -} - -static int flask_domain_settime(struct domain *d) -{ - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__SETTIME); -} - -static int flask_set_target(struct domain *d, struct domain *e) -{ - return domain_has_perm(d, e, SECCLASS_DOMAIN, DOMAIN__SET_TARGET); + /* (tsec, dsec) defaults the label to tsec, as it should here */ + rc = security_transition_sid(tsec->sid, dsec->sid, SECCLASS_DOMAIN, + &dsec->target_sid); + return rc; } static int flask_domctl(struct domain *d, int cmd) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__SET_MISC_INFO); + switch ( cmd ) + { + /* These have individual XSM hooks (common/domctl.c) */ + case XEN_DOMCTL_createdomain: + case XEN_DOMCTL_getdomaininfo: + case XEN_DOMCTL_scheduler_op: + case XEN_DOMCTL_irq_permission: + case XEN_DOMCTL_iomem_permission: + case XEN_DOMCTL_set_target: +#ifdef CONFIG_X86 + /* These have individual XSM hooks (arch/x86/domctl.c) */ + case XEN_DOMCTL_shadow_op: + case XEN_DOMCTL_ioport_permission: + case XEN_DOMCTL_bind_pt_irq: + case XEN_DOMCTL_unbind_pt_irq: + case XEN_DOMCTL_memory_mapping: + case XEN_DOMCTL_ioport_mapping: + case XEN_DOMCTL_mem_event_op: + /* These have individual XSM hooks (drivers/passthrough/iommu.c) */ + case XEN_DOMCTL_get_device_group: + case XEN_DOMCTL_test_assign_device: + case XEN_DOMCTL_assign_device: + case XEN_DOMCTL_deassign_device: +#endif + return 0; + + case XEN_DOMCTL_destroydomain: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__DESTROY); + + case XEN_DOMCTL_pausedomain: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__PAUSE); + + case XEN_DOMCTL_unpausedomain: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__UNPAUSE); + + case XEN_DOMCTL_setvcpuaffinity: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETVCPUAFFINITY); + + case XEN_DOMCTL_getvcpuaffinity: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETVCPUAFFINITY); + + case XEN_DOMCTL_resumedomain: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__RESUME); + + case XEN_DOMCTL_max_vcpus: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__MAX_VCPUS); + + case XEN_DOMCTL_max_mem: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDOMAINMAXMEM); + + case XEN_DOMCTL_setdomainhandle: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDOMAINHANDLE); + + case XEN_DOMCTL_setvcpucontext: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETVCPUCONTEXT); + + case XEN_DOMCTL_getvcpucontext: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETVCPUCONTEXT); + + case XEN_DOMCTL_getvcpuinfo: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETVCPUINFO); + + case XEN_DOMCTL_settimeoffset: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETTIME); + + case XEN_DOMCTL_setdebugging: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDEBUGGING); + + case XEN_DOMCTL_getpageframeinfo: + case XEN_DOMCTL_getpageframeinfo2: + case XEN_DOMCTL_getpageframeinfo3: + return current_has_perm(d, SECCLASS_MMU, MMU__PAGEINFO); + + case XEN_DOMCTL_getmemlist: + return current_has_perm(d, SECCLASS_MMU, MMU__PAGELIST); + + case XEN_DOMCTL_hypercall_init: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__HYPERCALL); + + case XEN_DOMCTL_sethvmcontext: + return current_has_perm(d, SECCLASS_HVM, HVM__SETHVMC); + + case XEN_DOMCTL_gethvmcontext: + case XEN_DOMCTL_gethvmcontext_partial: + return current_has_perm(d, SECCLASS_HVM, HVM__GETHVMC); + + case XEN_DOMCTL_set_address_size: + case XEN_DOMCTL_set_machine_address_size: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETADDRSIZE); + + case XEN_DOMCTL_get_address_size: + case XEN_DOMCTL_get_machine_address_size: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETADDRSIZE); + + case XEN_DOMCTL_mem_sharing_op: + return current_has_perm(d, SECCLASS_HVM, HVM__MEM_SHARING); + + case XEN_DOMCTL_pin_mem_cacheattr: + return current_has_perm(d, SECCLASS_HVM, HVM__CACHEATTR); + + case XEN_DOMCTL_set_ext_vcpucontext: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETEXTVCPUCONTEXT); + + case XEN_DOMCTL_get_ext_vcpucontext: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETEXTVCPUCONTEXT); + + case XEN_DOMCTL_setvcpuextstate: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETVCPUEXTSTATE); + + case XEN_DOMCTL_getvcpuextstate: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__GETVCPUEXTSTATE); + + case XEN_DOMCTL_sendtrigger: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__TRIGGER); + + case XEN_DOMCTL_set_access_required: + return current_has_perm(d, SECCLASS_HVM, HVM__MEM_EVENT); + + case XEN_DOMCTL_debug_op: + case XEN_DOMCTL_gdbsx_guestmemio: + case XEN_DOMCTL_gdbsx_pausevcpu: + case XEN_DOMCTL_gdbsx_unpausevcpu: + case XEN_DOMCTL_gdbsx_domstatus: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SETDEBUGGING); + + case XEN_DOMCTL_subscribe: + case XEN_DOMCTL_disable_migrate: + case XEN_DOMCTL_suppress_spurious_page_faults: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SET_MISC_INFO); + + case XEN_DOMCTL_set_virq_handler: + return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SET_VIRQ_HANDLER); + + case XEN_DOMCTL_set_cpuid: + return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__SET_CPUID); + + case XEN_DOMCTL_gettscinfo: + return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__GETTSC); + + case XEN_DOMCTL_settscinfo: + return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__SETTSC); + + case XEN_DOMCTL_audit_p2m: + return current_has_perm(d, SECCLASS_HVM, HVM__AUDIT_P2M); + + default: + printk("flask_domctl: Unknown op %d\n", cmd); + return -EPERM; + } } -static int flask_set_virq_handler(struct domain *d, uint32_t virq) +static int flask_sysctl(int cmd) { - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__SET_VIRQ_HANDLER); -} + switch ( cmd ) + { + /* These have individual XSM hooks */ + case XEN_SYSCTL_readconsole: + case XEN_SYSCTL_getdomaininfolist: + case XEN_SYSCTL_page_offline_op: + case XEN_SYSCTL_scheduler_op: +#ifdef CONFIG_X86 + case XEN_SYSCTL_cpu_hotplug: +#endif + return 0; -static int flask_tbufcontrol(void) -{ - return domain_has_xen(current->domain, XEN__TBUFCONTROL); + case XEN_SYSCTL_tbuf_op: + return domain_has_xen(current->domain, XEN__TBUFCONTROL); + + case XEN_SYSCTL_sched_id: + return domain_has_xen(current->domain, XEN__GETSCHEDULER); + + case XEN_SYSCTL_perfc_op: + return domain_has_xen(current->domain, XEN__PERFCONTROL); + + case XEN_SYSCTL_debug_keys: + return domain_has_xen(current->domain, XEN__DEBUG); + + case XEN_SYSCTL_getcpuinfo: + return domain_has_xen(current->domain, XEN__GETCPUINFO); + + case XEN_SYSCTL_availheap: + return domain_has_xen(current->domain, XEN__HEAP); + + case XEN_SYSCTL_get_pmstat: + return domain_has_xen(current->domain, XEN__PM_OP); + + case XEN_SYSCTL_pm_op: + return domain_has_xen(current->domain, XEN__PM_OP); + + case XEN_SYSCTL_lockprof_op: + return domain_has_xen(current->domain, XEN__LOCKPROF); + + case XEN_SYSCTL_cpupool_op: + return domain_has_xen(current->domain, XEN__CPUPOOL_OP); + + case XEN_SYSCTL_physinfo: + case XEN_SYSCTL_topologyinfo: + case XEN_SYSCTL_numainfo: + return domain_has_xen(current->domain, XEN__PHYSINFO); + + default: + printk("flask_sysctl: Unknown op %d\n", cmd); + return -EPERM; + } } static int flask_readconsole(uint32_t clear) @@ -605,59 +791,6 @@ static int flask_readconsole(uint32_t cl return domain_has_xen(current->domain, perms); } -static int flask_sched_id(void) -{ - return domain_has_xen(current->domain, XEN__SCHEDULER); -} - -static int flask_setdomainmaxmem(struct domain *d) -{ - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__SETDOMAINMAXMEM); -} - -static int flask_setdomainhandle(struct domain *d) -{ - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__SETDOMAINHANDLE); -} - -static int flask_setdebugging(struct domain *d) -{ - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__SETDEBUGGING); -} - -static int flask_debug_keys(void) -{ - return domain_has_xen(current->domain, XEN__DEBUG); -} - -static int flask_getcpuinfo(void) -{ - return domain_has_xen(current->domain, XEN__GETCPUINFO); -} - -static int flask_availheap(void) -{ - return domain_has_xen(current->domain, XEN__HEAP); -} - -static int flask_get_pmstat(void) -{ - return domain_has_xen(current->domain, XEN__PM_OP); -} - -static int flask_setpminfo(void) -{ - return domain_has_xen(current->domain, XEN__PM_OP); -} - -static int flask_pm_op(void) -{ - return domain_has_xen(current->domain, XEN__PM_OP); -} - static int flask_do_mca(void) { return domain_has_xen(current->domain, XEN__MCA_OP); @@ -687,14 +820,12 @@ static char *flask_show_irq_sid (int irq static int flask_map_domain_pirq (struct domain *d, int irq, void *data) { - u32 sid; + u32 sid, dsid; int rc = -EPERM; struct msi_info *msi = data; - - struct domain_security_struct *ssec, *tsec; struct avc_audit_data ad; - rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__ADD); + rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD); if ( rc ) return rc; @@ -710,14 +841,13 @@ static int flask_map_domain_pirq (struct if ( rc ) return rc; - ssec = current->domain->ssid; - tsec = d->ssid; + dsid = domain_sid(d); - rc = avc_has_perm(ssec->sid, sid, SECCLASS_RESOURCE, RESOURCE__ADD_IRQ, &ad); + rc = avc_current_has_perm(sid, SECCLASS_RESOURCE, RESOURCE__ADD_IRQ, &ad); if ( rc ) return rc; - rc = avc_has_perm(tsec->sid, sid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); + rc = avc_has_perm(dsid, sid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); return rc; } @@ -725,16 +855,12 @@ static int flask_unmap_domain_pirq (stru { u32 sid; int rc = -EPERM; - - struct domain_security_struct *ssec; struct avc_audit_data ad; - rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__REMOVE); + rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE); if ( rc ) return rc; - ssec = current->domain->ssid; - if ( irq < nr_static_irqs ) { rc = get_irq_sid(irq, &sid, &ad); } else { @@ -745,19 +871,19 @@ static int flask_unmap_domain_pirq (stru if ( rc ) return rc; - rc = avc_has_perm(ssec->sid, sid, SECCLASS_RESOURCE, RESOURCE__REMOVE_IRQ, &ad); + rc = avc_current_has_perm(sid, SECCLASS_RESOURCE, RESOURCE__REMOVE_IRQ, &ad); return rc; } static int flask_irq_permission (struct domain *d, int pirq, uint8_t access) { /* the PIRQ number is not useful; real IRQ is checked during mapping */ - return domain_has_perm(current->domain, d, SECCLASS_RESOURCE, - resource_to_perm(access)); + return current_has_perm(d, SECCLASS_RESOURCE, resource_to_perm(access)); } struct iomem_has_perm_data { - struct domain_security_struct *ssec, *tsec; + u32 ssid; + u32 dsid; u32 perm; }; @@ -771,12 +897,12 @@ static int _iomem_has_perm(void *v, u32 ad.range.start = start; ad.range.end = end; - rc = avc_has_perm(data->ssec->sid, sid, SECCLASS_RESOURCE, data->perm, &ad); + rc = avc_has_perm(data->ssid, sid, SECCLASS_RESOURCE, data->perm, &ad); if ( rc ) return rc; - return avc_has_perm(data->tsec->sid, sid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); + return avc_has_perm(data->dsid, sid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); } static int flask_iomem_permission(struct domain *d, uint64_t start, uint64_t end, uint8_t access) @@ -784,7 +910,7 @@ static int flask_iomem_permission(struct struct iomem_has_perm_data data; int rc; - rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, + rc = current_has_perm(d, SECCLASS_RESOURCE, resource_to_perm(access)); if ( rc ) return rc; @@ -794,18 +920,22 @@ static int flask_iomem_permission(struct else data.perm = RESOURCE__REMOVE_IOMEM; - data.ssec = current->domain->ssid; - data.tsec = d->ssid; + data.ssid = domain_sid(current->domain); + data.dsid = domain_sid(d); return security_iterate_iomem_sids(start, end, _iomem_has_perm, &data); } +static int flask_iomem_mapping(struct domain *d, uint64_t start, uint64_t end, uint8_t access) +{ + return flask_iomem_permission(d, start, end, access); +} + static int flask_pci_config_permission(struct domain *d, uint32_t machine_bdf, uint16_t start, uint16_t end, uint8_t access) { - u32 rsid; + u32 dsid, rsid; int rc = -EPERM; struct avc_audit_data ad; - struct domain_security_struct *ssec; u32 perm = RESOURCE__USE; rc = security_device_sid(machine_bdf, &rsid); @@ -818,33 +948,24 @@ static int flask_pci_config_permission(s AVC_AUDIT_DATA_INIT(&ad, DEV); ad.device = (unsigned long) machine_bdf; - ssec = d->ssid; - return avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, perm, &ad); + dsid = domain_sid(d); + return avc_has_perm(dsid, rsid, SECCLASS_RESOURCE, perm, &ad); } static int flask_resource_plug_core(void) { - struct domain_security_struct *ssec; - - ssec = current->domain->ssid; - return avc_has_perm(ssec->sid, SECINITSID_DOMXEN, SECCLASS_RESOURCE, RESOURCE__PLUG, NULL); + return avc_current_has_perm(SECINITSID_DOMXEN, SECCLASS_RESOURCE, RESOURCE__PLUG, NULL); } static int flask_resource_unplug_core(void) { - struct domain_security_struct *ssec; - - ssec = current->domain->ssid; - return avc_has_perm(ssec->sid, SECINITSID_DOMXEN, SECCLASS_RESOURCE, RESOURCE__UNPLUG, NULL); + return avc_current_has_perm(SECINITSID_DOMXEN, SECCLASS_RESOURCE, RESOURCE__UNPLUG, NULL); } static int flask_resource_use_core(void) { - struct domain_security_struct *ssec; - - ssec = current->domain->ssid; - return avc_has_perm(ssec->sid, SECINITSID_DOMXEN, SECCLASS_RESOURCE, RESOURCE__USE, NULL); + return avc_current_has_perm(SECINITSID_DOMXEN, SECCLASS_RESOURCE, RESOURCE__USE, NULL); } static int flask_resource_plug_pci(uint32_t machine_bdf) @@ -852,7 +973,6 @@ static int flask_resource_plug_pci(uint3 u32 rsid; int rc = -EPERM; struct avc_audit_data ad; - struct domain_security_struct *ssec; rc = security_device_sid(machine_bdf, &rsid); if ( rc ) @@ -860,8 +980,7 @@ static int flask_resource_plug_pci(uint3 AVC_AUDIT_DATA_INIT(&ad, DEV); ad.device = (unsigned long) machine_bdf; - ssec = current->domain->ssid; - return avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__PLUG, &ad); + return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__PLUG, &ad); } static int flask_resource_unplug_pci(uint32_t machine_bdf) @@ -869,7 +988,6 @@ static int flask_resource_unplug_pci(uin u32 rsid; int rc = -EPERM; struct avc_audit_data ad; - struct domain_security_struct *ssec; rc = security_device_sid(machine_bdf, &rsid); if ( rc ) @@ -877,8 +995,7 @@ static int flask_resource_unplug_pci(uin AVC_AUDIT_DATA_INIT(&ad, DEV); ad.device = (unsigned long) machine_bdf; - ssec = current->domain->ssid; - return avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__UNPLUG, &ad); + return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__UNPLUG, &ad); } static int flask_resource_setup_pci(uint32_t machine_bdf) @@ -886,7 +1003,6 @@ static int flask_resource_setup_pci(uint u32 rsid; int rc = -EPERM; struct avc_audit_data ad; - struct domain_security_struct *ssec; rc = security_device_sid(machine_bdf, &rsid); if ( rc ) @@ -894,8 +1010,7 @@ static int flask_resource_setup_pci(uint AVC_AUDIT_DATA_INIT(&ad, DEV); ad.device = (unsigned long) machine_bdf; - ssec = current->domain->ssid; - return avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__SETUP, &ad); + return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__SETUP, &ad); } static int flask_resource_setup_gsi(int gsi) @@ -903,22 +1018,17 @@ static int flask_resource_setup_gsi(int u32 rsid; int rc = -EPERM; struct avc_audit_data ad; - struct domain_security_struct *ssec; rc = get_irq_sid(gsi, &rsid, &ad); if ( rc ) return rc; - ssec = current->domain->ssid; - return avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__SETUP, &ad); + return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__SETUP, &ad); } static int flask_resource_setup_misc(void) { - struct domain_security_struct *ssec; - - ssec = current->domain->ssid; - return avc_has_perm(ssec->sid, SECINITSID_XEN, SECCLASS_RESOURCE, RESOURCE__SETUP, NULL); + return avc_current_has_perm(SECINITSID_XEN, SECCLASS_RESOURCE, RESOURCE__SETUP, NULL); } static inline int flask_page_offline(uint32_t cmd) @@ -935,24 +1045,14 @@ static inline int flask_page_offline(uin } } -static inline int flask_lockprof(void) +static inline int flask_tmem_op(void) { - return domain_has_xen(current->domain, XEN__LOCKPROF); + return domain_has_xen(current->domain, XEN__TMEM_OP); } -static inline int flask_cpupool_op(void) +static inline int flask_tmem_control(void) { - return domain_has_xen(current->domain, XEN__CPUPOOL_OP); -} - -static inline int flask_sched_op(void) -{ - return domain_has_xen(current->domain, XEN__SCHED_OP); -} - -static int flask_perfcontrol(void) -{ - return domain_has_xen(current->domain, XEN__PERFCONTROL); + return domain_has_xen(current->domain, XEN__TMEM_CONTROL); } #ifdef CONFIG_X86 @@ -981,11 +1081,12 @@ static int flask_shadow_control(struct d return -EPERM; } - return domain_has_perm(current->domain, d, SECCLASS_SHADOW, perm); + return current_has_perm(d, SECCLASS_SHADOW, perm); } struct ioport_has_perm_data { - struct domain_security_struct *ssec, *tsec; + u32 ssid; + u32 dsid; u32 perm; }; @@ -999,21 +1100,20 @@ static int _ioport_has_perm(void *v, u32 ad.range.start = start; ad.range.end = end; - rc = avc_has_perm(data->ssec->sid, sid, SECCLASS_RESOURCE, data->perm, &ad); + rc = avc_has_perm(data->ssid, sid, SECCLASS_RESOURCE, data->perm, &ad); if ( rc ) return rc; - return avc_has_perm(data->tsec->sid, sid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); + return avc_has_perm(data->dsid, sid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); } - static int flask_ioport_permission(struct domain *d, uint32_t start, uint32_t end, uint8_t access) { int rc; struct ioport_has_perm_data data; - rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, + rc = current_has_perm(d, SECCLASS_RESOURCE, resource_to_perm(access)); if ( rc ) @@ -1024,68 +1124,15 @@ static int flask_ioport_permission(struc else data.perm = RESOURCE__REMOVE_IOPORT; - data.ssec = current->domain->ssid; - data.tsec = d->ssid; + data.ssid = domain_sid(current->domain); + data.dsid = domain_sid(d); return security_iterate_ioport_sids(start, end, _ioport_has_perm, &data); } -static int flask_getpageframeinfo(struct domain *d) +static int flask_ioport_mapping(struct domain *d, uint32_t start, uint32_t end, uint8_t access) { - return domain_has_perm(current->domain, d, SECCLASS_MMU, MMU__PAGEINFO); -} - -static int flask_getmemlist(struct domain *d) -{ - return domain_has_perm(current->domain, d, SECCLASS_MMU, MMU__PAGELIST); -} - -static int flask_hypercall_init(struct domain *d) -{ - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, - DOMAIN__HYPERCALL); -} - -static int flask_hvmcontext(struct domain *d, uint32_t cmd) -{ - u32 perm; - - switch ( cmd ) - { - case XEN_DOMCTL_sethvmcontext: - perm = HVM__SETHVMC; - break; - case XEN_DOMCTL_gethvmcontext: - case XEN_DOMCTL_gethvmcontext_partial: - perm = HVM__GETHVMC; - break; - case HVMOP_track_dirty_vram: - perm = HVM__TRACKDIRTYVRAM; - break; - default: - return -EPERM; - } - - return domain_has_perm(current->domain, d, SECCLASS_HVM, perm); -} - -static int flask_address_size(struct domain *d, uint32_t cmd) -{ - u32 perm; - - switch ( cmd ) - { - case XEN_DOMCTL_set_address_size: - perm = DOMAIN__SETADDRSIZE; - break; - case XEN_DOMCTL_get_address_size: - perm = DOMAIN__GETADDRSIZE; - break; - default: - return -EPERM; - } - - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm); + return flask_ioport_permission(d, start, end, access); } static int flask_hvm_param(struct domain *d, unsigned long op) @@ -1107,32 +1154,45 @@ static int flask_hvm_param(struct domain perm = HVM__HVMCTL; } - return domain_has_perm(current->domain, d, SECCLASS_HVM, perm); + return current_has_perm(d, SECCLASS_HVM, perm); } static int flask_hvm_set_pci_intx_level(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__PCILEVEL); + return current_has_perm(d, SECCLASS_HVM, HVM__PCILEVEL); } static int flask_hvm_set_isa_irq_level(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__IRQLEVEL); + return current_has_perm(d, SECCLASS_HVM, HVM__IRQLEVEL); } static int flask_hvm_set_pci_link_route(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__PCIROUTE); + return current_has_perm(d, SECCLASS_HVM, HVM__PCIROUTE); } -static int flask_mem_event(struct domain *d) +static int flask_hvm_inject_msi(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__MEM_EVENT); + return current_has_perm(d, SECCLASS_HVM, HVM__SEND_IRQ); } -static int flask_mem_sharing(struct domain *d) +static int flask_mem_event_control(struct domain *d, int mode, int op) { - return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__MEM_SHARING); + return current_has_perm(d, SECCLASS_HVM, HVM__MEM_EVENT); +} + +static int flask_mem_event_op(struct domain *d, int op) +{ + return current_has_perm(d, SECCLASS_HVM, HVM__MEM_EVENT); +} + +static int flask_mem_sharing_op(struct domain *d, struct domain *cd, int op) +{ + int rc = current_has_perm(cd, SECCLASS_HVM, HVM__MEM_SHARING); + if ( rc ) + return rc; + return domain_has_perm(d, cd, SECCLASS_HVM, HVM__SHARE_MEM); } static int flask_apic(struct domain *d, int cmd) @@ -1141,10 +1201,11 @@ static int flask_apic(struct domain *d, switch ( cmd ) { - case PHYSDEVOP_APIC_READ: + case PHYSDEVOP_apic_read: + case PHYSDEVOP_alloc_irq_vector: perm = XEN__READAPIC; break; - case PHYSDEVOP_APIC_WRITE: + case PHYSDEVOP_apic_write: perm = XEN__WRITEAPIC; break; default: @@ -1154,150 +1215,114 @@ static int flask_apic(struct domain *d, return domain_has_xen(d, perm); } -static int flask_xen_settime(void) +static int flask_platform_op(uint32_t op) { - return domain_has_xen(current->domain, XEN__SETTIME); -} + switch ( op ) + { +#ifdef CONFIG_X86 + /* These operations have their own XSM hooks */ + case XENPF_cpu_online: + case XENPF_cpu_offline: + case XENPF_cpu_hotadd: + case XENPF_mem_hotadd: + return 0; +#endif -static int flask_memtype(uint32_t access) -{ - u32 perm; + case XENPF_settime: + return domain_has_xen(current->domain, XEN__SETTIME); - switch ( access ) - { case XENPF_add_memtype: - perm = XEN__MTRR_ADD; - break; + return domain_has_xen(current->domain, XEN__MTRR_ADD); + case XENPF_del_memtype: - perm = XEN__MTRR_DEL; - break; + return domain_has_xen(current->domain, XEN__MTRR_DEL); + case XENPF_read_memtype: - perm = XEN__MTRR_READ; - break; + return domain_has_xen(current->domain, XEN__MTRR_READ); + + case XENPF_microcode_update: + return domain_has_xen(current->domain, XEN__MICROCODE); + + case XENPF_platform_quirk: + return domain_has_xen(current->domain, XEN__QUIRK); + + case XENPF_firmware_info: + return domain_has_xen(current->domain, XEN__FIRMWARE); + + case XENPF_efi_runtime_call: + return domain_has_xen(current->domain, XEN__FIRMWARE); + + case XENPF_enter_acpi_sleep: + return domain_has_xen(current->domain, XEN__SLEEP); + + case XENPF_change_freq: + return domain_has_xen(current->domain, XEN__FREQUENCY); + + case XENPF_getidletime: + return domain_has_xen(current->domain, XEN__GETIDLE); + + case XENPF_set_processor_pminfo: + case XENPF_core_parking: + return domain_has_xen(current->domain, XEN__PM_OP); + + case XENPF_get_cpu_version: + case XENPF_get_cpuinfo: + return domain_has_xen(current->domain, XEN__GETCPUINFO); + default: + printk("flask_platform_op: Unknown op %d\n", op); return -EPERM; } - - return domain_has_xen(current->domain, perm); -} - -static int flask_microcode(void) -{ - return domain_has_xen(current->domain, XEN__MICROCODE); -} - -static int flask_physinfo(void) -{ - return domain_has_xen(current->domain, XEN__PHYSINFO); -} - -static int flask_platform_quirk(uint32_t quirk) -{ - struct domain_security_struct *dsec; - dsec = current->domain->ssid; - - return avc_has_perm(dsec->sid, SECINITSID_XEN, SECCLASS_XEN, - XEN__QUIRK, NULL); -} - -static int flask_firmware_info(void) -{ - return domain_has_xen(current->domain, XEN__FIRMWARE); -} - -static int flask_efi_call(void) -{ - return domain_has_xen(current->domain, XEN__FIRMWARE); -} - -static int flask_acpi_sleep(void) -{ - return domain_has_xen(current->domain, XEN__SLEEP); -} - -static int flask_change_freq(void) -{ - return domain_has_xen(current->domain, XEN__FREQUENCY); -} - -static int flask_getidletime(void) -{ - return domain_has_xen(current->domain, XEN__GETIDLE); } static int flask_machine_memory_map(void) { - struct domain_security_struct *dsec; - dsec = current->domain->ssid; - - return avc_has_perm(dsec->sid, SECINITSID_XEN, SECCLASS_MMU, - MMU__MEMORYMAP, NULL); + return avc_current_has_perm(SECINITSID_XEN, SECCLASS_MMU, MMU__MEMORYMAP, NULL); } static int flask_domain_memory_map(struct domain *d) { - return domain_has_perm(current->domain, d, SECCLASS_MMU, MMU__MEMORYMAP); + return current_has_perm(d, SECCLASS_MMU, MMU__MEMORYMAP); } -static int domain_memory_perm(struct domain *d, struct domain *f, l1_pgentry_t pte) +static int flask_mmu_update(struct domain *d, struct domain *t, + struct domain *f, uint32_t flags) { int rc = 0; - u32 map_perms = MMU__MAP_READ; - unsigned long fgfn, fmfn; - p2m_type_t p2mt; + u32 map_perms = 0; - if ( !(l1e_get_flags(pte) & _PAGE_PRESENT) ) - return 0; - - if ( l1e_get_flags(pte) & _PAGE_RW ) - map_perms |= MMU__MAP_WRITE; - - fgfn = l1e_get_pfn(pte); - fmfn = mfn_x(get_gfn_query(f, fgfn, &p2mt)); - put_gfn(f, fgfn); - - if ( f->domain_id == DOMID_IO || !mfn_valid(fmfn) ) - { - struct avc_audit_data ad; - struct domain_security_struct *dsec = d->ssid; - u32 fsid; - AVC_AUDIT_DATA_INIT(&ad, MEMORY); - ad.sdom = d; - ad.tdom = f; - ad.memory.pte = pte.l1; - ad.memory.mfn = fmfn; - rc = security_iomem_sid(fmfn, &fsid); - if ( rc ) - return rc; - return avc_has_perm(dsec->sid, fsid, SECCLASS_MMU, map_perms, &ad); - } - - return domain_has_perm(d, f, SECCLASS_MMU, map_perms); -} - -static int flask_mmu_normal_update(struct domain *d, struct domain *t, - struct domain *f, intpte_t fpte) -{ - int rc = 0; - - if (d != t) + if ( t && d != t ) rc = domain_has_perm(d, t, SECCLASS_MMU, MMU__REMOTE_REMAP); if ( rc ) return rc; - return domain_memory_perm(d, f, l1e_from_intpte(fpte)); + if ( flags & XSM_MMU_UPDATE_READ ) + map_perms |= MMU__MAP_READ; + if ( flags & XSM_MMU_UPDATE_WRITE ) + map_perms |= MMU__MAP_WRITE; + if ( flags & XSM_MMU_MACHPHYS_UPDATE ) + map_perms |= MMU__UPDATEMP; + + if ( map_perms ) + rc = domain_has_perm(d, f, SECCLASS_MMU, map_perms); + return rc; } -static int flask_mmu_machphys_update(struct domain *d1, struct domain *d2, - unsigned long mfn) +static int flask_mmuext_op(struct domain *d, struct domain *f) { - return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__UPDATEMP); + return domain_has_perm(d, f, SECCLASS_MMU, MMU__MMUEXT_OP); } static int flask_update_va_mapping(struct domain *d, struct domain *f, l1_pgentry_t pte) { - return domain_memory_perm(d, f, pte); + u32 map_perms = MMU__MAP_READ; + if ( !(l1e_get_flags(pte) & _PAGE_PRESENT) ) + return 0; + if ( l1e_get_flags(pte) & _PAGE_RW ) + map_perms |= MMU__MAP_WRITE; + + return domain_has_perm(d, f, SECCLASS_MMU, map_perms); } static int flask_add_to_physmap(struct domain *d1, struct domain *d2) @@ -1310,45 +1335,37 @@ static int flask_remove_from_physmap(str return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__PHYSMAP); } -static int flask_sendtrigger(struct domain *d) -{ - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__TRIGGER); -} - static int flask_get_device_group(uint32_t machine_bdf) { u32 rsid; int rc = -EPERM; - struct domain_security_struct *ssec = current->domain->ssid; rc = security_device_sid(machine_bdf, &rsid); if ( rc ) return rc; - return avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__STAT_DEVICE, NULL); + return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__STAT_DEVICE, NULL); } static int flask_test_assign_device(uint32_t machine_bdf) { u32 rsid; int rc = -EPERM; - struct domain_security_struct *ssec = current->domain->ssid; rc = security_device_sid(machine_bdf, &rsid); if ( rc ) return rc; - return rc = avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__STAT_DEVICE, NULL); + return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__STAT_DEVICE, NULL); } static int flask_assign_device(struct domain *d, uint32_t machine_bdf) { - u32 rsid; + u32 dsid, rsid; int rc = -EPERM; - struct domain_security_struct *ssec, *tsec; struct avc_audit_data ad; - rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__ADD); + rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD); if ( rc ) return rc; @@ -1358,22 +1375,20 @@ static int flask_assign_device(struct do AVC_AUDIT_DATA_INIT(&ad, DEV); ad.device = (unsigned long) machine_bdf; - ssec = current->domain->ssid; - rc = avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__ADD_DEVICE, &ad); + rc = avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__ADD_DEVICE, &ad); if ( rc ) return rc; - tsec = d->ssid; - return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); + dsid = domain_sid(d); + return avc_has_perm(dsid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); } static int flask_deassign_device(struct domain *d, uint32_t machine_bdf) { u32 rsid; int rc = -EPERM; - struct domain_security_struct *ssec = current->domain->ssid; - rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__REMOVE); + rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE); if ( rc ) return rc; @@ -1381,18 +1396,17 @@ static int flask_deassign_device(struct if ( rc ) return rc; - return rc = avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__REMOVE_DEVICE, NULL); + return avc_current_has_perm(rsid, SECCLASS_RESOURCE, RESOURCE__REMOVE_DEVICE, NULL); } static int flask_bind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *bind) { - u32 rsid; + u32 dsid, rsid; int rc = -EPERM; int irq; - struct domain_security_struct *ssec, *tsec; struct avc_audit_data ad; - rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__ADD); + rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD); if ( rc ) return rc; @@ -1402,61 +1416,17 @@ static int flask_bind_pt_irq (struct dom if ( rc ) return rc; - ssec = current->domain->ssid; - rc = avc_has_perm(ssec->sid, rsid, SECCLASS_HVM, HVM__BIND_IRQ, &ad); + rc = avc_current_has_perm(rsid, SECCLASS_HVM, HVM__BIND_IRQ, &ad); if ( rc ) return rc; - tsec = d->ssid; - return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); + dsid = domain_sid(d); + return avc_has_perm(dsid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, &ad); } static int flask_unbind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *bind) { - return domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__REMOVE); -} - -static int flask_pin_mem_cacheattr (struct domain *d) -{ - return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__CACHEATTR); -} - -static int flask_ext_vcpucontext (struct domain *d, uint32_t cmd) -{ - u32 perm; - - switch ( cmd ) - { - case XEN_DOMCTL_set_ext_vcpucontext: - perm = DOMAIN__SETEXTVCPUCONTEXT; - break; - case XEN_DOMCTL_get_ext_vcpucontext: - perm = DOMAIN__GETEXTVCPUCONTEXT; - break; - default: - return -EPERM; - } - - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm); -} - -static int flask_vcpuextstate (struct domain *d, uint32_t cmd) -{ - u32 perm; - - switch ( cmd ) - { - case XEN_DOMCTL_setvcpuextstate: - perm = DOMAIN__SETVCPUEXTSTATE; - break; - case XEN_DOMCTL_getvcpuextstate: - perm = DOMAIN__GETVCPUEXTSTATE; - break; - default: - return -EPERM; - } - - return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm); + return current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__REMOVE); } #endif @@ -1464,35 +1434,14 @@ long do_flask_op(XEN_GUEST_HANDLE_PARAM( static struct xsm_operations flask_ops = { .security_domaininfo = flask_security_domaininfo, - .setvcpucontext = flask_setvcpucontext, - .pausedomain = flask_pausedomain, - .unpausedomain = flask_unpausedomain, - .resumedomain = flask_resumedomain, .domain_create = flask_domain_create, - .max_vcpus = flask_max_vcpus, - .destroydomain = flask_destroydomain, - .vcpuaffinity = flask_vcpuaffinity, - .scheduler = flask_scheduler, .getdomaininfo = flask_getdomaininfo, - .getvcpucontext = flask_getvcpucontext, - .getvcpuinfo = flask_getvcpuinfo, - .domain_settime = flask_domain_settime, + .domctl_scheduler_op = flask_domctl_scheduler_op, + .sysctl_scheduler_op = flask_sysctl_scheduler_op, .set_target = flask_set_target, .domctl = flask_domctl, - .set_virq_handler = flask_set_virq_handler, - .tbufcontrol = flask_tbufcontrol, + .sysctl = flask_sysctl, .readconsole = flask_readconsole, - .sched_id = flask_sched_id, - .setdomainmaxmem = flask_setdomainmaxmem, - .setdomainhandle = flask_setdomainhandle, - .setdebugging = flask_setdebugging, - .perfcontrol = flask_perfcontrol, - .debug_keys = flask_debug_keys, - .getcpuinfo = flask_getcpuinfo, - .availheap = flask_availheap, - .get_pmstat = flask_get_pmstat, - .setpminfo = flask_setpminfo, - .pm_op = flask_pm_op, .do_mca = flask_do_mca, .evtchn_unbound = flask_evtchn_unbound, @@ -1517,6 +1466,7 @@ static struct xsm_operations flask_ops = .get_pod_target = flask_get_pod_target, .set_pod_target = flask_set_pod_target, + .memory_exchange = flask_memory_exchange, .memory_adjust_reservation = flask_memory_adjust_reservation, .memory_stat_reservation = flask_memory_stat_reservation, .memory_pin_page = flask_memory_pin_page, @@ -1534,6 +1484,7 @@ static struct xsm_operations flask_ops = .unmap_domain_pirq = flask_unmap_domain_pirq, .irq_permission = flask_irq_permission, .iomem_permission = flask_iomem_permission, + .iomem_mapping = flask_iomem_mapping, .pci_config_permission = flask_pci_config_permission, .resource_plug_core = flask_resource_plug_core, @@ -1545,54 +1496,38 @@ static struct xsm_operations flask_ops = .resource_setup_misc = flask_resource_setup_misc, .page_offline = flask_page_offline, - .lockprof = flask_lockprof, - .cpupool_op = flask_cpupool_op, - .sched_op = flask_sched_op, + .tmem_op = flask_tmem_op, + .tmem_control = flask_tmem_control, .do_xsm_op = do_flask_op, #ifdef CONFIG_X86 .shadow_control = flask_shadow_control, - .getpageframeinfo = flask_getpageframeinfo, - .getmemlist = flask_getmemlist, - .hypercall_init = flask_hypercall_init, - .hvmcontext = flask_hvmcontext, - .address_size = flask_address_size, .hvm_param = flask_hvm_param, .hvm_set_pci_intx_level = flask_hvm_set_pci_intx_level, .hvm_set_isa_irq_level = flask_hvm_set_isa_irq_level, .hvm_set_pci_link_route = flask_hvm_set_pci_link_route, - .mem_event = flask_mem_event, - .mem_sharing = flask_mem_sharing, + .hvm_inject_msi = flask_hvm_inject_msi, + .mem_event_control = flask_mem_event_control, + .mem_event_op = flask_mem_event_op, + .mem_sharing_op = flask_mem_sharing_op, .apic = flask_apic, - .xen_settime = flask_xen_settime, - .memtype = flask_memtype, - .microcode = flask_microcode, - .physinfo = flask_physinfo, - .platform_quirk = flask_platform_quirk, - .firmware_info = flask_firmware_info, - .efi_call = flask_efi_call, - .acpi_sleep = flask_acpi_sleep, - .change_freq = flask_change_freq, - .getidletime = flask_getidletime, + .platform_op = flask_platform_op, .machine_memory_map = flask_machine_memory_map, .domain_memory_map = flask_domain_memory_map, - .mmu_normal_update = flask_mmu_normal_update, - .mmu_machphys_update = flask_mmu_machphys_update, + .mmu_update = flask_mmu_update, + .mmuext_op = flask_mmuext_op, .update_va_mapping = flask_update_va_mapping, .add_to_physmap = flask_add_to_physmap, .remove_from_physmap = flask_remove_from_physmap, - .sendtrigger = flask_sendtrigger, .get_device_group = flask_get_device_group, .test_assign_device = flask_test_assign_device, .assign_device = flask_assign_device, .deassign_device = flask_deassign_device, .bind_pt_irq = flask_bind_pt_irq, .unbind_pt_irq = flask_unbind_pt_irq, - .pin_mem_cacheattr = flask_pin_mem_cacheattr, - .ext_vcpucontext = flask_ext_vcpucontext, - .vcpuextstate = flask_vcpuextstate, .ioport_permission = flask_ioport_permission, + .ioport_mapping = flask_ioport_mapping, #endif }; diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/xsm/flask/include/objsec.h --- a/xen/xsm/flask/include/objsec.h Fri Jan 11 12:22:30 2013 +0000 +++ b/xen/xsm/flask/include/objsec.h Fri Jan 11 12:23:39 2013 +0000 @@ -19,6 +19,8 @@ struct domain_security_struct { u32 sid; /* current SID */ + u32 self_sid; /* SID for target when operating on DOMID_SELF */ + u32 target_sid; /* SID for device model target domain */ }; struct evtchn_security_struct { diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/xsm/flask/policy/access_vectors --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/xsm/flask/policy/access_vectors Fri Jan 11 12:23:39 2013 +0000 @@ -0,0 +1,436 @@ +# +# Define the access vectors. +# +# class class_name { permission_name ... } + +# Class xen consists of dom0-only operations dealing with the hypervisor itself. +# Unless otherwise specified, the source is the domain executing the hypercall, +# and the target is the xen initial sid (type xen_t). +class xen +{ +# XENPF_settime + settime +# XEN_SYSCTL_tbuf_op + tbufcontrol +# CONSOLEIO_read, XEN_SYSCTL_readconsole + readconsole +# XEN_SYSCTL_readconsole with clear=1 + clearconsole +# XEN_SYSCTL_perfc_op + perfcontrol +# XENPF_add_memtype + mtrr_add +# XENPF_del_memtype + mtrr_del +# XENPF_read_memtype + mtrr_read +# XENPF_microcode_update + microcode +# XEN_SYSCTL_physinfo, XEN_SYSCTL_topologyinfo, XEN_SYSCTL_numainfo + physinfo +# XENPF_platform_quirk + quirk +# CONSOLEIO_write + writeconsole +# PHYSDEVOP_apic_read, PHYSDEVOP_alloc_irq_vector + readapic +# PHYSDEVOP_apic_write + writeapic +# Most XENOPROF_* + privprofile +# XENOPROF_{init,enable_virq,disable_virq,get_buffer} + nonprivprofile +# kexec hypercall + kexec +# XENPF_firmware_info, XENPF_efi_runtime_call + firmware +# XENPF_enter_acpi_sleep + sleep +# XENPF_change_freq + frequency +# XENPF_getidletime + getidle +# XEN_SYSCTL_debug_keys + debug +# XEN_SYSCTL_getcpuinfo, XENPF_get_cpu_version, XENPF_get_cpuinfo + getcpuinfo +# XEN_SYSCTL_availheap + heap +# XEN_SYSCTL_get_pmstat, XEN_SYSCTL_pm_op, XENPF_set_processor_pminfo, +# XENPF_core_parking + pm_op +# mca hypercall + mca_op +# XEN_SYSCTL_lockprof_op + lockprof +# XEN_SYSCTL_cpupool_op + cpupool_op +# tmem hypercall (any access) + tmem_op +# TMEM_CONTROL command of tmem hypercall + tmem_control +# XEN_SYSCTL_scheduler_op with XEN_DOMCTL_SCHEDOP_getinfo, XEN_SYSCTL_sched_id + getscheduler +# XEN_SYSCTL_scheduler_op with XEN_DOMCTL_SCHEDOP_putinfo + setscheduler +} + +# Classes domain and domain2 consist of operations that a domain performs on +# another domain or on itself. Unless otherwise specified, the source is the +# domain executing the hypercall, and the target is the domain being operated on +# (which may result in a _self or _target type). +# +# transitions in class domain are used to produce the _self and _target types; +# see docs/misc/xsm-flask.txt and the example XSM policy for details. +class domain +{ +# XEN_DOMCTL_setvcpucontext + setvcpucontext +# XEN_DOMCTL_pausedomain + pause +# XEN_DOMCTL_unpausedomain + unpause +# XEN_DOMCTL_resumedomain + resume +# XEN_DOMCTL_createdomain + create +# checked in FLASK_RELABEL_DOMAIN for any relabel operation: +# source = the old label of the domain +# target = the new label of the domain +# see also the domain2 relabel{from,to,self} permissions + transition +# XEN_DOMCTL_max_vcpus + max_vcpus +# XEN_DOMCTL_destroydomain + destroy +# XEN_DOMCTL_setvcpuaffinity + setvcpuaffinity +# XEN_DOMCTL_getvcpuaffinity + getvcpuaffinity +# XEN_DOMCTL_scheduler_op with XEN_DOMCTL_SCHEDOP_getinfo + getscheduler +# XEN_DOMCTL_getdomaininfo, XEN_SYSCTL_getdomaininfolist + getdomaininfo +# XEN_DOMCTL_getvcpuinfo + getvcpuinfo +# XEN_DOMCTL_getvcpucontext + getvcpucontext +# XEN_DOMCTL_max_mem + setdomainmaxmem +# XEN_DOMCTL_setdomainhandle + setdomainhandle +# XEN_DOMCTL_setdebugging + setdebugging +# XEN_DOMCTL_hypercall_init + hypercall +# XEN_DOMCTL_settimeoffset + settime +# checked in XEN_DOMCTL_set_target: +# source = the new device model domain +# target = the new target domain +# see also the domain2 make_priv_for and set_as_target checks + set_target +# SCHEDOP_remote_shutdown + shutdown +# XEN_DOMCTL_set{,_machine}_address_size + setaddrsize +# XEN_DOMCTL_get{,_machine}_address_size + getaddrsize +# XEN_DOMCTL_sendtrigger + trigger +# XEN_DOMCTL_get_ext_vcpucontext + getextvcpucontext +# XEN_DOMCTL_set_ext_vcpucontext + setextvcpucontext +# XEN_DOMCTL_getvcpuextstate + getvcpuextstate +# XEN_DOMCTL_setvcpuextstate + setvcpuextstate +# XENMEM_get_pod_target + getpodtarget +# XENMEM_set_pod_target + setpodtarget +# XEN_DOMCTL_subscribe, XEN_DOMCTL_disable_migrate, +# XEN_DOMCTL_suppress_spurious_page_faults + set_misc_info +# XEN_DOMCTL_set_virq_handler + set_virq_handler +} + +# This is a continuation of class domain, since only 32 permissions can be +# defined per class +class domain2 +{ +# checked in FLASK_RELABEL_DOMAIN with non-DOMID_SELF: +# source = the domain making the hypercall +# target = the old label of the domain being relabeled + relabelfrom +# checked in FLASK_RELABEL_DOMAIN with non-DOMID_SELF: +# source = the domain making the hypercall +# target = the new label of the domain being relabeled + relabelto +# checked in FLASK_RELABEL_DOMAIN, only with DOMID_SELF: +# source = the old label of the domain +# target = the new label of the domain +# see also domain__transition + relabelself +# checked in XEN_DOMCTL_set_target: +# source = the domain making the hypercall +# target = the new device model domain + make_priv_for +# checked in XEN_DOMCTL_set_target: +# source = the domain making the hypercall +# target = the new target domain + set_as_target +# XEN_DOMCTL_set_cpuid + set_cpuid +# XEN_DOMCTL_gettscinfo + gettsc +# XEN_DOMCTL_settscinfo + settsc +# XEN_DOMCTL_scheduler_op with XEN_DOMCTL_SCHEDOP_putinfo + setscheduler +} + +# Similar to class domain, but primarily contains domctls related to HVM domains +class hvm +{ +# XEN_DOMCTL_sethvmcontext + sethvmc +# XEN_DOMCTL_gethvmcontext, XEN_DOMCTL_gethvmcontext_partial + gethvmc +# HVMOP_set_param + setparam +# HVMOP_get_param + getparam +# HVMOP_set_pci_intx_level (also needs hvmctl) + pcilevel +# HVMOP_set_isa_irq_level + irqlevel +# HVMOP_set_pci_link_route + pciroute + bind_irq +# XEN_DOMCTL_pin_mem_cacheattr + cacheattr +# HVMOP_track_dirty_vram + trackdirtyvram +# HVMOP_modified_memory, HVMOP_get_mem_type, HVMOP_set_mem_type, +# HVMOP_set_mem_access, HVMOP_get_mem_access, HVMOP_pagetable_dying, +# HVMOP_inject_trap + hvmctl +# XEN_DOMCTL_set_access_required + mem_event +# XEN_DOMCTL_mem_sharing_op and XENMEM_sharing_op_{share,add_physmap} with: +# source = the domain making the hypercall +# target = domain whose memory is being shared + mem_sharing +# XEN_DOMCTL_audit_p2m + audit_p2m +# HVMOP_inject_msi + send_irq +# checked in XENMEM_sharing_op_{share,add_physmap} with: +# source = domain whose memory is being shared +# target = client domain + share_mem +} + +# Class event describes event channels. Interdomain event channels have their +# own security label which is computed using a type transition between the +# source and target domains. Each endpoint has its own label, and the +# permission checks must pass on both endpoints for an event channel to be +# established. +class event +{ +# when creating an interdomain event channel endpoint: +# source = event channel label +# target = remote domain the event channel binds to. This may be a _self or +# _target label if the endpoints are related as such. +# This permission is checked when creating an unbound event channel and when the +# interdomain event channel is established. + bind +# EVTCHNOP_send: +# source = domain sending the event +# target = event channel label + send +# EVTCHNOP_status; same as _send + status +# when creating an interdomain event channel endpoint: +# source = the domain creating the channel (which might not be an endpoint) +# target = event channel label + create +# EVTCHNOP_reset: +# source = domain making the hypercall +# target = domain whose event channels are being reset + reset +} + +# Class grant describes pages shared by grant mappings. Pages use the security +# label of their owning domain. +class grant +{ +# GNTTABOP_map_grant_ref with any access + map_read +# GNTTABOP_map_grant_ref with write access + map_write +# GNTTABOP_unmap_grant_ref + unmap +# GNTTABOP_transfer + transfer +# GNTTABOP_setup_table, GNTTABOP_get_status_frames (target is commonly _self) + setup +# GNTTABOP_copy + copy +# GNTTABOP_query_size, GNTTABOP_get_version + query +} + +# Class mmu describes pages of memory not accessed using grants. Permissions +# are checked using the domain ID used to access the page - the most common case +# is a domain's own ID (the _self label). Using DOMID_IO in the map command to +# restrict the mapping to IO memory will result in the target being domio_t, and +# migration uses read-only mappings with a target of DOMID_XEN (domxen_t). +class mmu +{ +# checked when using mmu_update to map a page readably +# source = domain making the hypercall (which might not own the page table) +# target = domain whose pages are being mapped + map_read +# checked when using mmu_update to map a page writably +# source = domain making the hypercall +# target = domain whose pages are being mapped + map_write +# XEN_DOMCTL_getpageframeinfo* + pageinfo +# XEN_DOMCTL_getmemlist + pagelist +# XENMEM_{increase,decrease}_reservation, XENMEM_populate_physmap + adjust +# XENMEM_{current,maximum}_reservation, XENMEM_maximum_gpfn + stat +# mmu_update MMU_MACHPHYS_UPDATE + updatemp +# XENMEM_add_to_physmap, XENMEM_remove_from_physmap + physmap +# MMUEXT_PIN_L*_TABLE + pinpage +# XENMEM_machine_memory_map (with target xen_t) +# XENMEM_set_memory_map (with domain target) + memorymap +# checked when using mmu_update to update the page tables of another domain +# source = domain making the hypercall +# target = domain whose page tables are being modified + remote_remap +# the mmuext_op hypercall acting on the target domain + mmuext_op +# XENMEM_exchange: +# source = domain making the hypercall +# target = domain whose pages are being exchanged + exchange +} + +# control of the paging_domctl split by subop +class shadow +{ +# XEN_DOMCTL_SHADOW_OP_OFF + disable +# enable, get/set allocation + enable +# enable, read, and clean log + logdirty +} + +# Class resource is used to describe the resources used in hardware device +# passthrough. Resources include: hardware IRQs, MMIO regions, x86 I/O ports, +# and PCI devices; see docs/misc/xsm-flask.txt for how to label them. +# +# Access to the legacy PCI configuration space on x86 via port 0xCF8/CFC +# requires IS_PRIV, even with FLASK. Writes to the BARs are checked as "setup", +# while other reads/writes are "use"; the target is the PCI device whose +# configuration space is being modified. Accesses to the MMIO-based PCI express +# configuration space described by the ACPI MCFG table are controlled as MMIO +# accesses, and cannot special-case BAR writes. +# +# The {add,remove}_{irq,ioport,iomem,device} permissions use: +# source = domain making the hypercall +# target = resource's security label +class resource +{ +# checked when adding a resource to a domain: +# source = domain making the hypercall +# target = domain which will have access to the resource + add +# checked when removing a resource from a domain: +# source = domain making the hypercall +# target = domain which will no longer have access to the resource + remove +# checked when adding a resource to a domain: +# source = domain which will have access to the resource +# target = resource's security label +# also checked when using some core Xen devices (target xen_t) + use +# PHYSDEVOP_map_pirq and ioapic writes for dom0 +# For GSI interrupts, the IRQ's label is indexed by the IRQ number +# For MSI interrupts, the label of the PCI device is used + add_irq +# PHYSDEVOP_unmap_pirq: +# This is currently only checked for GSI interrupts + remove_irq +# XEN_DOMCTL_ioport_permission, XEN_DOMCTL_ioport_mapping + add_ioport + remove_ioport +# XEN_DOMCTL_iomem_permission, XEN_DOMCTL_memory_mapping + add_iomem + remove_iomem +# XEN_DOMCTL_get_device_group, XEN_DOMCTL_test_assign_device: +# source = domain making the hypercall +# target = PCI device being queried + stat_device +# XEN_DOMCTL_assign_device + add_device +# XEN_DOMCTL_deassign_device + remove_device +# checked for PCI hot and cold-plug hypercalls, with target as the PCI device +# checked for CPU and memory hotplug with xen_t as the target + plug +# checked for PCI hot-unplug hypercalls, with target as the PCI device +# checked for CPU offlining with xen_t as the target + unplug +# checked for PHYSDEVOP_restore_msi* (target PCI device) +# checked for PHYSDEVOP_setup_gsi (target IRQ) +# checked for PHYSDEVOP_pci_mmcfg_reserved (target xen_t) + setup +} + +# Class security describes the FLASK security server itself; these operations +# are accessed using the xsm_op hypercall. The source is the domain invoking +# the hypercall, and the target is security_t. +# +# Any domain with access to load_policy or setenforce must be trusted, since it +# can bypass the rest of the security policy. +class security +{ +# use the security server to compute an access check + compute_av +# use the security server to compute a type transition + compute_create +# use the security server to compute member selection + compute_member +# sid <-> context string conversions + check_context +# allow loading a new XSM/FLASK policy + load_policy +# use the security server to compute an object relabel + compute_relabel +# use the security server to list the SIDs reachable by a given user + compute_user +# allow switching between enforcing and permissive mode + setenforce +# allow changing policy booleans + setbool +# allow changing security server configuration parmeters + setsecparam +# add ocontext label definitions for resources + add_ocontext +# remove ocontext label definitions for resources + del_ocontext +} diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/xsm/flask/policy/initial_sids --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/xsm/flask/policy/initial_sids Fri Jan 11 12:23:39 2013 +0000 @@ -0,0 +1,16 @@ +# FLASK + +# +# Define initial security identifiers +# +sid xen +sid dom0 +sid domio +sid domxen +sid unlabeled +sid security +sid ioport +sid iomem +sid irq +sid device +# FLASK diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/xsm/flask/policy/mkaccess_vector.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/xsm/flask/policy/mkaccess_vector.sh Fri Jan 11 12:23:39 2013 +0000 @@ -0,0 +1,138 @@ +#!/bin/sh - +# + +# FLASK + +set -e + +awk=$1 +shift + +# output files +av_permissions="include/av_permissions.h" +av_perm_to_string="include/av_perm_to_string.h" + +cat $* | $awk " +BEGIN { + outfile = \"$av_permissions\" + avpermfile = \"$av_perm_to_string\" + "' + nextstate = "COMMON_OR_AV"; + printf("/* This file is automatically generated. Do not edit. */\n") > outfile; + printf("/* This file is automatically generated. Do not edit. */\n") > avpermfile; +; + } +/^[ \t]*#/ { + next; + } +$1 == "class" { + if (nextstate != "COMMON_OR_AV" && + nextstate != "CLASS_OR_CLASS-OPENBRACKET") + { + printf("Parse error: Unexpected class definition on line %d\n", NR); + next; + } + + tclass = $2; + + if (tclass in av_defined) + { + printf("Duplicate access vector definition for %s on line %d\n", tclass, NR); + next; + } + av_defined[tclass] = 1; + + permission = 1; + + nextstate = "INHERITS_OR_CLASS-OPENBRACKET"; + next; + } +$1 == "{" { + if (nextstate != "INHERITS_OR_CLASS-OPENBRACKET" && + nextstate != "CLASS_OR_CLASS-OPENBRACKET" && + nextstate != "COMMON-OPENBRACKET") + { + printf("Parse error: Unexpected { on line %d\n", NR); + next; + } + + if (nextstate == "INHERITS_OR_CLASS-OPENBRACKET") + nextstate = "CLASS-CLOSEBRACKET"; + + if (nextstate == "CLASS_OR_CLASS-OPENBRACKET") + nextstate = "CLASS-CLOSEBRACKET"; + + if (nextstate == "COMMON-OPENBRACKET") + nextstate = "COMMON-CLOSEBRACKET"; + } +/[a-z][a-z_]*/ { + if (nextstate != "COMMON-CLOSEBRACKET" && + nextstate != "CLASS-CLOSEBRACKET") + { + printf("Parse error: Unexpected symbol %s on line %d\n", $1, NR); + next; + } + + if (nextstate == "COMMON-CLOSEBRACKET") + { + if ((common_name,$1) in common_perms) + { + printf("Duplicate permission %s for common %s on line %d.\n", $1, common_name, NR); + next; + } + + common_perms[common_name,$1] = permission; + + printf("#define COMMON_%s__%s", toupper(common_name), toupper($1)) > outfile; + + printf(" S_(\"%s\")\n", $1) > cpermfile; + } + else + { + if ((tclass,$1) in av_perms) + { + printf("Duplicate permission %s for %s on line %d.\n", $1, tclass, NR); + next; + } + + av_perms[tclass,$1] = permission; + + printf("#define %s__%s", toupper(tclass), toupper($1)) > outfile; + + printf(" S_(SECCLASS_%s, %s__%s, \"%s\")\n", toupper(tclass), toupper(tclass), toupper($1), $1) > avpermfile; + } + + spaces = 40 - (length($1) + length(tclass)); + if (spaces < 1) + spaces = 1; + + for (i = 0; i < spaces; i++) + printf(" ") > outfile; + printf("0x%08xUL\n", permission) > outfile; + permission = permission * 2; + } +$1 == "}" { + if (nextstate != "CLASS-CLOSEBRACKET" && + nextstate != "COMMON-CLOSEBRACKET") + { + printf("Parse error: Unexpected } on line %d\n", NR); + next; + } + + if (nextstate == "COMMON-CLOSEBRACKET") + { + common_base[common_name] = permission; + printf("TE_(common_%s_perm_to_string)\n\n", common_name) > cpermfile; + } + + printf("\n") > outfile; + + nextstate = "COMMON_OR_AV"; + } +END { + if (nextstate != "COMMON_OR_AV" && nextstate != "CLASS_OR_CLASS-OPENBRACKET") + printf("Parse error: Unexpected end of file\n"); + + }' + +# FLASK diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/xsm/flask/policy/mkflask.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/xsm/flask/policy/mkflask.sh Fri Jan 11 12:23:39 2013 +0000 @@ -0,0 +1,95 @@ +#!/bin/sh - +# + +# FLASK + +set -e + +awk=$1 +shift 1 + +# output file +output_file="include/flask.h" +debug_file="include/class_to_string.h" +debug_file2="include/initial_sid_to_string.h" + +cat $* | $awk " +BEGIN { + outfile = \"$output_file\" + debugfile = \"$debug_file\" + debugfile2 = \"$debug_file2\" + "' + nextstate = "CLASS"; + + printf("/* This file is automatically generated. Do not edit. */\n") > outfile; + + printf("#ifndef _SELINUX_FLASK_H_\n") > outfile; + printf("#define _SELINUX_FLASK_H_\n") > outfile; + printf("\n/*\n * Security object class definitions\n */\n") > outfile; + printf("/* This file is automatically generated. Do not edit. */\n") > debugfile; + printf("/*\n * Security object class definitions\n */\n") > debugfile; + printf(" S_(\"null\")\n") > debugfile; + printf("/* This file is automatically generated. Do not edit. */\n") > debugfile2; + printf("static char *initial_sid_to_string[] =\n{\n") > debugfile2; + printf(" \"null\",\n") > debugfile2; + } +/^[ \t]*#/ { + next; + } +$1 == "class" { + if (nextstate != "CLASS") + { + printf("Parse error: Unexpected class definition on line %d\n", NR); + next; + } + + if ($2 in class_found) + { + printf("Duplicate class definition for %s on line %d.\n", $2, NR); + next; + } + class_found[$2] = 1; + + class_value++; + + printf("#define SECCLASS_%s", toupper($2)) > outfile; + for (i = 0; i < 40 - length($2); i++) + printf(" ") > outfile; + printf("%d\n", class_value) > outfile; + + printf(" S_(\"%s\")\n", $2) > debugfile; + } +$1 == "sid" { + if (nextstate == "CLASS") + { + nextstate = "SID"; + printf("\n/*\n * Security identifier indices for initial entities\n */\n") > outfile; + } + + if ($2 in sid_found) + { + printf("Duplicate SID definition for %s on line %d.\n", $2, NR); + next; + } + sid_found[$2] = 1; + sid_value++; + + printf("#define SECINITSID_%s", toupper($2)) > outfile; + for (i = 0; i < 37 - length($2); i++) + printf(" ") > outfile; + printf("%d\n", sid_value) > outfile; + printf(" \"%s\",\n", $2) > debugfile2; + } +END { + if (nextstate != "SID") + printf("Parse error: Unexpected end of file\n"); + + printf("\n#define SECINITSID_NUM") > outfile; + for (i = 0; i < 34; i++) + printf(" ") > outfile; + printf("%d\n", sid_value) > outfile; + printf("\n#endif\n") > outfile; + printf("};\n\n") > debugfile2; + }' + +# FLASK diff -r 0b9dfd067b42 -r f54b7b1f65ea xen/xsm/flask/policy/security_classes --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/xsm/flask/policy/security_classes Fri Jan 11 12:23:39 2013 +0000 @@ -0,0 +1,21 @@ +# FLASK + +# +# Define the security object classes +# + +# Classes marked as userspace are classes +# for userspace object managers + +class xen +class domain +class domain2 +class hvm +class mmu +class resource +class shadow +class event +class grant +class security + +# FLASK _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |