[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Xen-devel] [PATCH 4/6] xsm: flask: change the interface and default policy for xsm_map_gmfn_foregin
- To: Zhongze Liu <blackskygg@xxxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>
- From: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
- Date: Wed, 23 Aug 2017 11:56:12 -0400
- Cc: George Dunlap <george.dunlap@xxxxxxxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Julien Grall <julien.grall@xxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, xen-devel@xxxxxxxxxxxxx
- Delivery-date: Wed, 23 Aug 2017 15:56:30 +0000
- Ironport-phdr: 9a23:Px2RYRyzAXUDP0XXCy+O+j09IxM/srCxBDY+r6Qd0ugRKfad9pjvdHbS+e9qxAeQG96KurQc0aGH6ejJYi8p2d65qncMcZhBBVcuqP49uEgeOvODElDxN/XwbiY3T4xoXV5h+GynYwAOQJ6tL1LdrWev4jEMBx7xKRR6JvjvGo7Vks+7y/2+94fdbghMgDexe69+IAu5oQjVqMUdnJdvJLs2xhbVuHVDZv5YxXlvJVKdnhb84tm/8Zt++ClOuPwv6tBNX7zic6s3UbJXAjImM3so5MLwrhnMURGP5noHXWoIlBdDHhXI4wv7Xpf1tSv6q/Z91SyHNsD4Ubw4RTKv5LpwRRT2lCkIKSI28GDPisxxkq1bpg6hpwdiyILQeY2ZKeZycr/Ycd4cS2VBRMJRXDFfDI26YYUEEu4NMf9Fo4XholcDqwa1CwuxC+P10jJGm2H43aM63eoiHw/J0gMvENASv3rbt9j1KKUfXPqpwKXUwzjObfVb0ir95ojSdRAhpOmBU7xqfsrXyEkgCQfFhUiep4P7Ijib1/4NvHKB4OpuSOmijHMoqw5srTexyccskJPGi5kJylHE6Sp5wIE1Kce+SE5ge9GoCpRQtyaEN4ZvRM4pXm9muCE/yrIcuJ67ejAHyZs5yB7Zc/yHaY+I4hD9W+mNPTd0nnVleKiwhxu07EOuyfX8W9Gp3FtFoSdJiNnBum0X2xDN5cWLVOFx8lqn1D2SzQ7c8PtELloxlafDLp4hxaM/mYQLvETYGy/2hF32jKiLdkU44uSo6/roYrHhppKEK497kBv+MqUzmsykG+g4LggPUHSb+eS7zrHj+1H2QK5WgfEsl6nZsZTaKdwapq6/HQBVzp4u5wuwAjqpytgVnWQLIEhbdB+IkYTlIUzCLOj9DfilglSslDlrx+rBPr3kGpjCM3fDn6r/crZy8U5T0hE+zcxf5p1ICrEBJ+j/WknqtNPCFBM5PAu0w/j/BNVnyoweQX6PArOeMK7KqlCI4vggLPWPZI8Ouzb8K/cl5/H1gH82nF8SZ6ip3Z8NZH+kGfRmJl2TYWDwjdcZDWcKog0+QfTxiF2ZTT5cfW29ULw45jE/CYKmC4bDS5uugLOfxie7GINZZmRcBlCLC3foeJ2OW+0QZyKKPs9hjjsEWKCuSoA/0xGirRL1xKR5LuXK/i0Vrpbj1Nlu5+3PjhE+7zN1ANqb022XSGF0hGwITScs3K9juUx91kuD0a9gjvxaCNxT4/JJXRk8NZLGwOx6Ecr9WgbFftqSUlmmWNCmDSstQdI2xt8Ee1x9FMm6jhDfwyqqBKcYl7OVC5wz6KLc0Gb+K9xgxHbb0qkhi0MpQtNUOGK4m65z7RTcB4/Vk0WDlqarer4Q0zLK9GeG1WCOpl1XUBZsUaXZWnASfknWos/n6UPfS7+uCKgoMgtaxM6ZN6tKccPmgU9aS/fkPdTUe3ixlHuoBRaU2rOMa5LndH8b3CrAEkgLjQ4S8WyaOgg5ASehu3zRDCZgGF/0f0zs8PV+qGm6Tk471Q2Fc0ph17/msiIS0M6cTPUczL9MnCY842F+GF+23MnVGtWPjwVkdaRYJ9g65QEDnVnFugJ0OJvoFLxrjFMadwVxvgu6zA5rA49NlcwrqnICzwdoL6+cllRbeGXL84r3P+j7I2/z8RTnR6Oe9UvX2djerqsA5Pk3sVzLoBCiFk1k9W5uldZSzS3Ptd3xEAMOXMepAQ4M/B9gquSfO3Bl6g==
- List-id: Xen developer discussion <xen-devel.lists.xen.org>
On 08/22/2017 10:18 PM, Zhongze Liu wrote:
Hi Stefano,
2017-08-23 3:58 GMT+08:00 Stefano Stabellini <sstabellini@xxxxxxxxxx>:
On Wed, 23 Aug 2017, Zhongze Liu wrote:
The original xsm_map_gmfn_foregin policy checks if source domain has the proper
privileges over the target domain. Under this policy, it's not allowed if a Dom0
wants to map pages from one DomU to another, this restricts some useful yet not
dangerous usages of the API, such as sharing pages among DomU's by calling
XENMEM_add_to_physmap from Dom0.
Change the policy to: IIF current domain has the proper privilege on the
^ IFF
target domain and source domain, grant the access.
References to this xsm check have also been updated to pass the current
domain as a new parameter.
This is for the proposal "Allow setting up shared memory areas between VMs
from xl config file" (see [1]).
[1] https://lists.xenproject.org/archives/html/xen-devel/2017-07/msg03047.html
Signed-off-by: Zhongze Liu <blackskygg@xxxxxxxxx>
Cc: Stefano Stabellini <sstabellini@xxxxxxxxxx>
Cc: Julien Grall <julien.grall@xxxxxxx>
Cc: George Dunlap <george.dunlap@xxxxxxxxxxxxx>
Cc: Jan Beulich <jbeulich@xxxxxxxx>
Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Cc: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
Cc: xen-devel@xxxxxxxxxxxxx
---
xen/arch/arm/mm.c | 2 +-
xen/arch/x86/mm/p2m.c | 2 +-
xen/include/xsm/dummy.h | 6 ++++--
xen/include/xsm/xsm.h | 7 ++++---
xen/xsm/flask/hooks.c | 6 ++++--
5 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index a810a056d7..9ec78d8c03 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -1284,7 +1284,7 @@ int xenmem_add_to_physmap_one(
return -EINVAL;
}
- rc = xsm_map_gmfn_foreign(XSM_TARGET, d, od);
+ rc = xsm_map_gmfn_foreign(XSM_TARGET, current->domain, d, od);
if ( rc )
{
rcu_unlock_domain(od);
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index e8a57d118c..a547fd00c0 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -2545,7 +2545,7 @@ int p2m_add_foreign(struct domain *tdom, unsigned long
fgfn,
if ( tdom == fdom )
goto out;
- rc = xsm_map_gmfn_foreign(XSM_TARGET, tdom, fdom);
+ rc = xsm_map_gmfn_foreign(XSM_TARGET, current->domain, tdom, fdom);
if ( rc )
goto out;
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index 62fcea6f04..28dbc6f2a2 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -525,10 +525,12 @@ static XSM_INLINE int
xsm_remove_from_physmap(XSM_DEFAULT_ARG struct domain *d1,
return xsm_default_action(action, d1, d2);
}
-static XSM_INLINE int xsm_map_gmfn_foreign(XSM_DEFAULT_ARG struct domain *d,
struct domain *t)
+static XSM_INLINE int xsm_map_gmfn_foreign(XSM_DEFAULT_ARG struct domain *cd,
+ struct domain *d, struct domain *t)
{
XSM_ASSERT_ACTION(XSM_TARGET);
- return xsm_default_action(action, d, t);
+ return xsm_default_action(action, cd, d) ||
+ xsm_default_action(action, cd, t);
We need to preserve the returned errors:
rc = xsm_default_action(action, cd, d);
if (rc) return rc;
return xsm_default_action(action, cd, t);
OK, will correct this.
}
static XSM_INLINE int xsm_hvm_param(XSM_DEFAULT_ARG struct domain *d,
unsigned long op)
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 60c0fd6a62..a20654a803 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -85,7 +85,7 @@ struct xsm_operations {
int (*memory_pin_page) (struct domain *d1, struct domain *d2, struct
page_info *page);
int (*add_to_physmap) (struct domain *d1, struct domain *d2);
int (*remove_from_physmap) (struct domain *d1, struct domain *d2);
- int (*map_gmfn_foreign) (struct domain *d, struct domain *t);
+ int (*map_gmfn_foreign) (struct domain *cd, struct domain *d, struct
domain *t);
int (*claim_pages) (struct domain *d);
int (*console_io) (struct domain *d, int cmd);
@@ -372,9 +372,10 @@ static inline int xsm_remove_from_physmap(xsm_default_t
def, struct domain *d1,
return xsm_ops->remove_from_physmap(d1, d2);
}
-static inline int xsm_map_gmfn_foreign (xsm_default_t def, struct domain *d,
struct domain *t)
+static inline int xsm_map_gmfn_foreign (xsm_default_t def, struct domain *cd,
+ struct domain *d, struct domain *t)
{
- return xsm_ops->map_gmfn_foreign(d, t);
+ return xsm_ops->map_gmfn_foreign(cd, d, t);
}
static inline int xsm_claim_pages(xsm_default_t def, struct domain *d)
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 91146275bb..3408b6b9e1 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -1165,9 +1165,11 @@ static int flask_remove_from_physmap(struct domain *d1,
struct domain *d2)
return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__PHYSMAP);
}
-static int flask_map_gmfn_foreign(struct domain *d, struct domain *t)
+static int flask_map_gmfn_foreign(struct domain *cd,
+ struct domain *d, struct domain *t)
{
- return domain_has_perm(d, t, SECCLASS_MMU, MMU__MAP_READ | MMU__MAP_WRITE);
+ return domain_has_perm(cd, d, SECCLASS_MMU, MMU__MAP_READ |
MMU__MAP_WRITE) ||
+ domain_has_perm(cd, t, SECCLASS_MMU, MMU__MAP_READ | MMU__MAP_WRITE);
}
Same here:
rc = domain_has_perm(cd, d, SECCLASS_MMU, MMU__MAP_READ | MMU__MAP_WRITE);
if (rc) return rc;
return domain_has_perm(cd, t, SECCLASS_MMU, MMU__MAP_READ | MMU__MAP_WRITE);
Also, I just want to point out that in the regular case cd and d are one
and the same. The code assumes that domain_has_perm returns 0 in that
case. I think that is correct, but I don't know enough about XSM to be
sure about it.
I also assume that domain_has_perm returns 0 when cd == d, but let's
wait for other
maintainers' comments.
While this permission check with (cd == d) should succeed in all sane policies,
it's faster to compare for equality than to look up the access vector.
In addition, I think it would be useful to have a check that (d) and (t) can
share memory (so that a security policy could be written preventing them from
communicating directly). Normally, this would be allowed between all domains
that allow grant mapping/event channels.
rc = domain_has_perm(d, t, SECCLASS_MMU, MMU__SHARE_MEM);
if (rc) return rc;
To allow this in the policy the same as grants:
--- a/tools/flask/policy/modules/xen.if
+++ b/tools/flask/policy/modules/xen.if
@@ -127,6 +127,8 @@ define(`domain_comms', `
domain_event_comms($1, $2)
allow $1 $2:grant { map_read map_write copy unmap };
allow $2 $1:grant { map_read map_write copy unmap };
+ allow $1 $2:mmu share_mem;
+ allow $2 $1:mmu share_mem;
')
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|