ia64/xen-unstable

view xen/common/acm_ops.c @ 15717:c229802cedbb

[32on64] Copy the right grant table status code back to the guest.

Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
author Ian Campbell <ian.campbell@xensource.com>
date Mon Aug 06 13:19:44 2007 +0100 (2007-08-06)
parents 96915ca8d5f2
children
line source
1 /******************************************************************************
2 * acm_ops.c
3 *
4 * Copyright (C) 2005 IBM Corporation
5 *
6 * Author:
7 * Reiner Sailer <sailer@watson.ibm.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation, version 2 of the
12 * License.
13 *
14 * Process acm command requests from guest OS.
15 */
17 #include <xen/config.h>
18 #include <xen/types.h>
19 #include <xen/lib.h>
20 #include <xen/mm.h>
21 #include <public/acm.h>
22 #include <public/acm_ops.h>
23 #include <xen/sched.h>
24 #include <xen/event.h>
25 #include <xen/trace.h>
26 #include <xen/console.h>
27 #include <xen/guest_access.h>
28 #include <acm/acm_hooks.h>
30 #ifndef ACM_SECURITY
32 long do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg)
33 {
34 return -ENOSYS;
35 }
37 #else
39 int acm_authorize_acm_ops(struct domain *d)
40 {
41 /* currently, policy management functions are restricted to privileged domains */
42 return (IS_PRIV(d) ? 0 : -EPERM);
43 }
46 long do_acm_op(XEN_GUEST_HANDLE(xen_acmctl_t) u_acmctl)
47 {
48 long rc = -EFAULT;
49 struct xen_acmctl curop, *op = &curop;
51 if (acm_authorize_acm_ops(current->domain))
52 return -EPERM;
54 if ( copy_from_guest(op, u_acmctl, 1) )
55 return -EFAULT;
57 if (op->interface_version != ACM_INTERFACE_VERSION)
58 return -EACCES;
60 switch ( op->cmd )
61 {
63 case ACMOP_setpolicy: {
64 rc = acm_set_policy(op->u.setpolicy.pushcache,
65 op->u.setpolicy.pushcache_size);
66 break;
67 }
69 case ACMOP_getpolicy: {
70 rc = acm_get_policy(op->u.getpolicy.pullcache,
71 op->u.getpolicy.pullcache_size);
72 break;
73 }
75 case ACMOP_dumpstats: {
76 rc = acm_dump_statistics(op->u.dumpstats.pullcache,
77 op->u.dumpstats.pullcache_size);
78 break;
79 }
81 case ACMOP_getssid: {
82 ssidref_t ssidref;
84 if (op->u.getssid.get_ssid_by == ACM_GETBY_ssidref)
85 ssidref = op->u.getssid.id.ssidref;
86 else if (op->u.getssid.get_ssid_by == ACM_GETBY_domainid)
87 {
88 struct domain *subj = rcu_lock_domain_by_id(op->u.getssid.id.domainid);
89 if (!subj)
90 {
91 rc = -ESRCH; /* domain not found */
92 break;
93 }
94 if (subj->ssid == NULL)
95 {
96 rcu_unlock_domain(subj);
97 rc = -ESRCH;
98 break;
99 }
100 ssidref = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
101 rcu_unlock_domain(subj);
102 }
103 else
104 {
105 rc = -ESRCH;
106 break;
107 }
108 rc = acm_get_ssid(ssidref, op->u.getssid.ssidbuf,
109 op->u.getssid.ssidbuf_size);
110 break;
111 }
113 case ACMOP_getdecision: {
114 ssidref_t ssidref1, ssidref2;
116 if (op->u.getdecision.get_decision_by1 == ACM_GETBY_ssidref)
117 ssidref1 = op->u.getdecision.id1.ssidref;
118 else if (op->u.getdecision.get_decision_by1 == ACM_GETBY_domainid)
119 {
120 struct domain *subj = rcu_lock_domain_by_id(op->u.getdecision.id1.domainid);
121 if (!subj)
122 {
123 rc = -ESRCH; /* domain not found */
124 break;
125 }
126 if (subj->ssid == NULL)
127 {
128 rcu_unlock_domain(subj);
129 rc = -ESRCH;
130 break;
131 }
132 ssidref1 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
133 rcu_unlock_domain(subj);
134 }
135 else
136 {
137 rc = -ESRCH;
138 break;
139 }
140 if (op->u.getdecision.get_decision_by2 == ACM_GETBY_ssidref)
141 ssidref2 = op->u.getdecision.id2.ssidref;
142 else if (op->u.getdecision.get_decision_by2 == ACM_GETBY_domainid)
143 {
144 struct domain *subj = rcu_lock_domain_by_id(op->u.getdecision.id2.domainid);
145 if (!subj)
146 {
147 rc = -ESRCH; /* domain not found */
148 break;;
149 }
150 if (subj->ssid == NULL)
151 {
152 rcu_unlock_domain(subj);
153 rc = -ESRCH;
154 break;
155 }
156 ssidref2 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
157 rcu_unlock_domain(subj);
158 }
159 else
160 {
161 rc = -ESRCH;
162 break;
163 }
164 rc = acm_get_decision(ssidref1, ssidref2, op->u.getdecision.hook);
166 if (rc == ACM_ACCESS_PERMITTED)
167 {
168 op->u.getdecision.acm_decision = ACM_ACCESS_PERMITTED;
169 rc = 0;
170 }
171 else if (rc == ACM_ACCESS_DENIED)
172 {
173 op->u.getdecision.acm_decision = ACM_ACCESS_DENIED;
174 rc = 0;
175 }
176 else
177 rc = -ESRCH;
179 if ( (rc == 0) && (copy_to_guest(u_acmctl, op, 1) != 0) )
180 rc = -EFAULT;
181 break;
182 }
184 case ACMOP_chgpolicy: {
185 rc = acm_change_policy(&op->u.change_policy);
186 break;
187 }
189 case ACMOP_relabeldoms: {
190 rc = acm_relabel_domains(&op->u.relabel_doms);
191 break;
192 }
194 default:
195 rc = -ENOSYS;
196 break;
197 }
199 return rc;
200 }
202 #endif
204 /*
205 * Local variables:
206 * mode: C
207 * c-set-style: "BSD"
208 * c-basic-offset: 4
209 * tab-width: 4
210 * indent-tabs-mode: nil
211 * End:
212 */