[libvirt] [PATCH v3] Added new attribute mount_security to filesystem element

This patch introduces new attribute to filesystem element to support customizable security for mount type. Valid mount_security are: passthrough and mapped. Usage: <filesystem type='mount' mount_security='passthrough'> <source dir='/export/to/guest'/> <target dir='mount_tag'/> </filesystem> Here is the detailed explanation on these security models: Security model: mapped ---------------------- Fileserver intercepts and maps all the file object create requests. Files on the fileserver will be created with Fileserver's user credentials and the client-user's credentials are stored in extended attributes. During getattr() server extracts the client-user's credentials from extended attributes and sends to the client. This adds a great deal of security in the cloud environments where the guest's(client) user space is kept completely isolated from host's user space. Security model : passthrough ---------------------------- In this security model, Fileserver passes down all requests to the underlying filesystem. File system objects on the fileserver will be created with client-user's credentials. This is done by setting setuid()/setgid() during creation or chmod/chown after file creation. At the end of create protocol request, files on the fileserver will be owned by cleint-user's uid/gid. This model mimic's current NFSv3 level of security. Note: This patch is based on Daniel's patch to support 9pfs. It shall be applied after applying Daniel's patch to support 9pfs. v3: - QEMU cmdline still uses security_model, changes done by mistake reverted. Signed-off-by: Harsh Prateek Bora <harsh@linux.vnet.ibm.com> --- docs/schemas/domain.rng | 6 ++++++ src/conf/domain_conf.c | 29 +++++++++++++++++++++++++++-- src/conf/domain_conf.h | 10 ++++++++++ src/qemu/qemu_conf.c | 9 +++++++-- 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index ccb8cf3..36eec63 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -761,6 +761,12 @@ </choice> <optional> <ref name="address"/> + <attribute name="mount_security"> + <choice> + <value>passthrough</value> + <value>mapped</value> + </choice> + </attribute> </optional> </element> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e05d5d7..ece6937 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -161,6 +161,11 @@ VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST, "file", "template") +VIR_ENUM_IMPL(virDomainFSMountSecurity, VIR_DOMAIN_FS_SECURITY_LAST, + "passthrough", + "mapped") + + VIR_ENUM_IMPL(virDomainNet, VIR_DOMAIN_NET_TYPE_LAST, "user", "ethernet", @@ -1847,6 +1852,7 @@ virDomainFSDefParseXML(xmlNodePtr node, char *type = NULL; char *source = NULL; char *target = NULL; + char *mount_security = NULL; if (VIR_ALLOC(def) < 0) { virReportOOMError(); @@ -1864,6 +1870,17 @@ virDomainFSDefParseXML(xmlNodePtr node, def->type = VIR_DOMAIN_FS_TYPE_MOUNT; } + mount_security = virXMLPropString(node, "mount_security"); + if (mount_security) { + if ((def->mount_security = virDomainFSMountSecurityTypeFromString(mount_security)) < 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("unknown mount security '%s'"), mount_security); + goto error; + } + } else { + def->mount_security = VIR_DOMAIN_FS_SECURITY_PASSTHROUGH; + } + cur = node->children; while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE) { @@ -5602,6 +5619,7 @@ virDomainFSDefFormat(virBufferPtr buf, int flags) { const char *type = virDomainFSTypeToString(def->type); + const char *mount_sec = virDomainFSMountSecurityTypeToString(def->mount_security); if (!type) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, @@ -5609,9 +5627,16 @@ virDomainFSDefFormat(virBufferPtr buf, return -1; } + if (!mount_sec) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected mount security %d"), def->mount_security); + return -1; + } + + virBufferVSprintf(buf, - " <filesystem type='%s'>\n", - type); + " <filesystem type='%s' mount_security='%s'>\n", + type, mount_sec); if (def->src) { switch (def->type) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 7195c04..3463942 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -236,10 +236,19 @@ enum virDomainFSType { VIR_DOMAIN_FS_TYPE_LAST }; +/* Filesystem mount security model */ +enum virDomainFSMountSecurity { + VIR_DOMAIN_FS_SECURITY_PASSTHROUGH, + VIR_DOMAIN_FS_SECURITY_MAPPED, + + VIR_DOMAIN_FS_SECURITY_LAST +}; + typedef struct _virDomainFSDef virDomainFSDef; typedef virDomainFSDef *virDomainFSDefPtr; struct _virDomainFSDef { int type; + int mount_security; char *src; char *dst; unsigned int readonly : 1; @@ -1167,6 +1176,7 @@ VIR_ENUM_DECL(virDomainDiskErrorPolicy) VIR_ENUM_DECL(virDomainController) VIR_ENUM_DECL(virDomainControllerModel) VIR_ENUM_DECL(virDomainFS) +VIR_ENUM_DECL(virDomainFSMountSecurity) VIR_ENUM_DECL(virDomainNet) VIR_ENUM_DECL(virDomainChrDevice) VIR_ENUM_DECL(virDomainChrChannelTarget) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 18a302a..53ebe5a 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -2014,6 +2014,7 @@ qemuAssignDeviceAliases(virDomainDefPtr def, unsigned long long qemuCmdFlags) if (virAsprintf(&def->fss[i]->info.alias, "fs%d", i) < 0) goto no_memory; } + for (i = 0; i < def->nsounds ; i++) { if (virAsprintf(&def->sounds[i]->info.alias, "sound%d", i) < 0) goto no_memory; @@ -2783,11 +2784,15 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs, if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("can only passthrough directories")); + _("only supports mount filesystem type")); goto error; } - virBufferAddLit(&opt, "local,security_model=passthrough"); + virBufferAddLit(&opt, "local"); + if (fs->mount_security == VIR_DOMAIN_FS_SECURITY_PASSTHROUGH) + virBufferAddLit(&opt, ",security_model=passthrough"); + else if (fs->mount_security == VIR_DOMAIN_FS_SECURITY_MAPPED) + virBufferAddLit(&opt, ",security_model=mapped"); virBufferVSprintf(&opt, ",id=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias); virBufferVSprintf(&opt, ",path=%s", fs->src); -- 1.7.1.1

On Mon, Oct 11, 2010 at 12:21:19PM +0530, Harsh Prateek Bora wrote:
This patch introduces new attribute to filesystem element to support customizable security for mount type. Valid mount_security are: passthrough and mapped.
Usage: <filesystem type='mount' mount_security='passthrough'> <source dir='/export/to/guest'/> <target dir='mount_tag'/> </filesystem>
Here is the detailed explanation on these security models:
Security model: mapped ----------------------
Fileserver intercepts and maps all the file object create requests. Files on the fileserver will be created with Fileserver's user credentials and the client-user's credentials are stored in extended attributes. During getattr() server extracts the client-user's credentials from extended attributes and sends to the client.
This adds a great deal of security in the cloud environments where the guest's(client) user space is kept completely isolated from host's user space.
Security model : passthrough ----------------------------
In this security model, Fileserver passes down all requests to the underlying filesystem. File system objects on the fileserver will be created with client-user's credentials. This is done by setting setuid()/setgid() during creation or chmod/chown after file creation. At the end of create protocol request, files on the fileserver will be owned by cleint-user's uid/gid. This model mimic's current NFSv3 level of security.
In your first patch you had a 3rd option 'none', whose semantics I had asked about, because they appeared to be the same as passthrough. Looking at the QEMU virtio-9p.c file comments though, it appears that there is in fact a difference. - In 'passthrough' the user/group ownership is preserved from the guest requests. - In 'mapped' the guest user/group ownership is stored in xtended attrs with files on host keeping same uid/gid as the QEMU process - In 'none' the user/group ownership from guest is completely ignored, and all files just have uid/gid matching the QEMU process. If this interpretation of QEMU code is correct, then I think we should support all 3 options in libvirt after all. The 'passthrough' option should be the default in libvirt, because that matches the semantics of the <filesystem> element usage in LXC / OpenVZ drivers in libvirt. I think I'd give 'none' a different name in the XML , perhaps call it 'squash', inspired by NFS root squash, which squashes uid/gid onto a single user. Finally I'm thinking that the security attribute should be called 'accessmode' rather than 'mount_security', mostly because I don't like underscores in XML attribute/element names. Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On 10/13/2010 8:21 AM, Daniel P. Berrange wrote:
On Mon, Oct 11, 2010 at 12:21:19PM +0530, Harsh Prateek Bora wrote:
This patch introduces new attribute to filesystem element to support customizable security for mount type. Valid mount_security are: passthrough and mapped.
Usage: <filesystem type='mount' mount_security='passthrough'> <source dir='/export/to/guest'/> <target dir='mount_tag'/> </filesystem>
Here is the detailed explanation on these security models:
Security model: mapped ----------------------
Fileserver intercepts and maps all the file object create requests. Files on the fileserver will be created with Fileserver's user credentials and the client-user's credentials are stored in extended attributes. During getattr() server extracts the client-user's credentials from extended attributes and sends to the client.
This adds a great deal of security in the cloud environments where the guest's(client) user space is kept completely isolated from host's user space.
Security model : passthrough ----------------------------
In this security model, Fileserver passes down all requests to the underlying filesystem. File system objects on the fileserver will be created with client-user's credentials. This is done by setting setuid()/setgid() during creation or chmod/chown after file creation. At the end of create protocol request, files on the fileserver will be owned by cleint-user's uid/gid. This model mimic's current NFSv3 level of security.
In your first patch you had a 3rd option 'none', whose semantics I had asked about, because they appeared to be the same as passthrough. Looking at the QEMU virtio-9p.c file comments though, it appears that there is in fact a difference.
- In 'passthrough' the user/group ownership is preserved from the guest requests. - In 'mapped' the guest user/group ownership is stored in xtended attrs with files on host keeping same uid/gid as the QEMU process - In 'none' the user/group ownership from guest is completely ignored, and all files just have uid/gid matching the QEMU process.
If this interpretation of QEMU code is correct, then I think we should support all 3 options in libvirt after all.
The 'passthrough' option should be the default in libvirt, because that matches the semantics of the <filesystem> element usage in LXC / OpenVZ drivers in libvirt.
I think I'd give 'none' a different name in the XML , perhaps call it 'squash', inspired by NFS root squash, which squashes uid/gid onto a single user.
Finally I'm thinking that the security attribute should be called 'accessmode' rather than 'mount_security', mostly because I don't like underscores in XML attribute/element names.
I am complete in agreement with all the observations above. Harsh can quickly make these changes and repost the patch. Thanks, JV
Regards, Daniel

2010/10/11 Harsh Prateek Bora <harsh@linux.vnet.ibm.com>:
This patch introduces new attribute to filesystem element to support customizable security for mount type. Valid mount_security are: passthrough and mapped.
Usage: <filesystem type='mount' mount_security='passthrough'> <source dir='/export/to/guest'/> <target dir='mount_tag'/> </filesystem>
Here is the detailed explanation on these security models:
Security model: mapped ----------------------
Fileserver intercepts and maps all the file object create requests. Files on the fileserver will be created with Fileserver's user credentials and the client-user's credentials are stored in extended attributes. During getattr() server extracts the client-user's credentials from extended attributes and sends to the client.
This adds a great deal of security in the cloud environments where the guest's(client) user space is kept completely isolated from host's user space.
Security model : passthrough ----------------------------
In this security model, Fileserver passes down all requests to the underlying filesystem. File system objects on the fileserver will be created with client-user's credentials. This is done by setting setuid()/setgid() during creation or chmod/chown after file creation. At the end of create protocol request, files on the fileserver will be owned by cleint-user's uid/gid. This model mimic's current NFSv3 level of security.
Note: This patch is based on Daniel's patch to support 9pfs. It shall be applied after applying Daniel's patch to support 9pfs.
v3: - QEMU cmdline still uses security_model, changes done by mistake reverted.
Signed-off-by: Harsh Prateek Bora <harsh@linux.vnet.ibm.com> --- docs/schemas/domain.rng | 6 ++++++ src/conf/domain_conf.c | 29 +++++++++++++++++++++++++++-- src/conf/domain_conf.h | 10 ++++++++++ src/qemu/qemu_conf.c | 9 +++++++-- 4 files changed, 50 insertions(+), 4 deletions(-)
This patch lacks documentation about the new domain XML attributes in docs/formatdomain.html.in. Matthias

On 10/13/2010 09:22 PM, Matthias Bolte wrote:
2010/10/11 Harsh Prateek Bora<harsh@linux.vnet.ibm.com>:
This patch introduces new attribute to filesystem element to support customizable security for mount type. Valid mount_security are: passthrough and mapped.
Usage: <filesystem type='mount' mount_security='passthrough'> <source dir='/export/to/guest'/> <target dir='mount_tag'/> </filesystem>
Here is the detailed explanation on these security models:
Security model: mapped ----------------------
Fileserver intercepts and maps all the file object create requests. Files on the fileserver will be created with Fileserver's user credentials and the client-user's credentials are stored in extended attributes. During getattr() server extracts the client-user's credentials from extended attributes and sends to the client.
This adds a great deal of security in the cloud environments where the guest's(client) user space is kept completely isolated from host's user space.
Security model : passthrough ----------------------------
In this security model, Fileserver passes down all requests to the underlying filesystem. File system objects on the fileserver will be created with client-user's credentials. This is done by setting setuid()/setgid() during creation or chmod/chown after file creation. At the end of create protocol request, files on the fileserver will be owned by cleint-user's uid/gid. This model mimic's current NFSv3 level of security.
Note: This patch is based on Daniel's patch to support 9pfs. It shall be applied after applying Daniel's patch to support 9pfs.
v3: - QEMU cmdline still uses security_model, changes done by mistake reverted.
Signed-off-by: Harsh Prateek Bora<harsh@linux.vnet.ibm.com> --- docs/schemas/domain.rng | 6 ++++++ src/conf/domain_conf.c | 29 +++++++++++++++++++++++++++-- src/conf/domain_conf.h | 10 ++++++++++ src/qemu/qemu_conf.c | 9 +++++++-- 4 files changed, 50 insertions(+), 4 deletions(-)
This patch lacks documentation about the new domain XML attributes in docs/formatdomain.html.in.
Hi Matthias, I wanted to put the documentation for the new attributes in the formatdomain.html.in, however, found that we are actually missing the documentation for the <filesystem> element itself there. I discussed about the same with DV and he suggested to put the documentation text in the patch itself, so that once the documentation for <filesystem> element is in place, this text can be added to it for the new attributes. Regards, Harsh
Matthias

On Thu, Oct 14, 2010 at 11:00:24AM +0530, Harsh Bora wrote:
On 10/13/2010 09:22 PM, Matthias Bolte wrote:
2010/10/11 Harsh Prateek Bora<harsh@linux.vnet.ibm.com>:
This patch introduces new attribute to filesystem element to support customizable security for mount type. Valid mount_security are: passthrough and mapped.
Usage: <filesystem type='mount' mount_security='passthrough'> <source dir='/export/to/guest'/> <target dir='mount_tag'/> </filesystem>
Here is the detailed explanation on these security models:
Security model: mapped ----------------------
Fileserver intercepts and maps all the file object create requests. Files on the fileserver will be created with Fileserver's user credentials and the client-user's credentials are stored in extended attributes. During getattr() server extracts the client-user's credentials from extended attributes and sends to the client.
This adds a great deal of security in the cloud environments where the guest's(client) user space is kept completely isolated from host's user space.
Security model : passthrough ----------------------------
In this security model, Fileserver passes down all requests to the underlying filesystem. File system objects on the fileserver will be created with client-user's credentials. This is done by setting setuid()/setgid() during creation or chmod/chown after file creation. At the end of create protocol request, files on the fileserver will be owned by cleint-user's uid/gid. This model mimic's current NFSv3 level of security.
Note: This patch is based on Daniel's patch to support 9pfs. It shall be applied after applying Daniel's patch to support 9pfs.
v3: - QEMU cmdline still uses security_model, changes done by mistake reverted.
Signed-off-by: Harsh Prateek Bora<harsh@linux.vnet.ibm.com> --- docs/schemas/domain.rng | 6 ++++++ src/conf/domain_conf.c | 29 +++++++++++++++++++++++++++-- src/conf/domain_conf.h | 10 ++++++++++ src/qemu/qemu_conf.c | 9 +++++++-- 4 files changed, 50 insertions(+), 4 deletions(-)
This patch lacks documentation about the new domain XML attributes in docs/formatdomain.html.in.
Hi Matthias, I wanted to put the documentation for the new attributes in the formatdomain.html.in, however, found that we are actually missing the documentation for the <filesystem> element itself there. I discussed about the same with DV and he suggested to put the documentation text in the patch itself, so that once the documentation for <filesystem> element is in place, this text can be added to it for the new attributes.
Yep, don't worry about the docs, i'll write up full docs for the entire <filesystem> element. Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
participants (5)
-
Daniel P. Berrange
-
Harsh Bora
-
Harsh Prateek Bora
-
Matthias Bolte
-
Venkateswararao Jujjuri (JV)