Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
libvirt
提交
d0aa10fd
L
libvirt
项目概览
openeuler
/
libvirt
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
libvirt
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d0aa10fd
编写于
3月 03, 2009
作者:
D
Daniel P. Berrange
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
QEMU security driver usage for sVirt support (James Morris, Dan Walsh, Daniel Berrange)
上级
b756b005
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
236 addition
and
8 deletion
+236
-8
ChangeLog
ChangeLog
+9
-0
src/qemu.conf
src/qemu.conf
+9
-0
src/qemu_conf.c
src/qemu_conf.c
+10
-0
src/qemu_conf.h
src/qemu_conf.h
+4
-0
src/qemu_driver.c
src/qemu_driver.c
+202
-6
src/util.c
src/util.c
+2
-2
未找到文件。
ChangeLog
浏览文件 @
d0aa10fd
Tue Mar 3 12:01:13 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
QEMU security driver usage for sVirt support (James Morris, Dan Walsh
& Daniel Berrange)
* src/qemu.conf: Add security_driver config option
* src/qemu_conf.c, src/qemu_conf.h, src/qemu_driver.c,
src/util.c: Use a security driver (if available) when
running virtual machines
Tue Mar 3 11:31:13 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
Tue Mar 3 11:31:13 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
* src/iptables.c, src/qemu_conf.c, src/qemu_driver.c,
* src/iptables.c, src/qemu_conf.c, src/qemu_driver.c,
...
...
src/qemu.conf
浏览文件 @
d0aa10fd
...
@@ -58,3 +58,12 @@
...
@@ -58,3 +58,12 @@
# example here before you set this
# example here before you set this
#
#
# vnc_password = "XYZ12345"
# vnc_password = "XYZ12345"
# The default security driver is SELinux. If SELinux is disabled
# on the host, then the security driver will automatically disable
# itself. If you wish to disable QEMU SELinux security driver while
# leaving SELinux enabled for the host in general, then set this
# to 'none' instead
#
# security_driver = "selinux"
src/qemu_conf.c
浏览文件 @
d0aa10fd
...
@@ -151,6 +151,16 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
...
@@ -151,6 +151,16 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
}
}
}
}
p
=
virConfGetValue
(
conf
,
"security_driver"
);
CHECK_TYPE
(
"security_river"
,
VIR_CONF_STRING
);
if
(
p
&&
p
->
str
)
{
if
(
!
(
driver
->
securityDriverName
=
strdup
(
p
->
str
)))
{
virReportOOMError
(
NULL
);
virConfFree
(
conf
);
return
-
1
;
}
}
virConfFree
(
conf
);
virConfFree
(
conf
);
return
0
;
return
0
;
}
}
...
...
src/qemu_conf.h
浏览文件 @
d0aa10fd
...
@@ -33,6 +33,7 @@
...
@@ -33,6 +33,7 @@
#include "domain_conf.h"
#include "domain_conf.h"
#include "domain_event.h"
#include "domain_event.h"
#include "threads.h"
#include "threads.h"
#include "security.h"
#define qemudDebug(fmt, ...) do {} while(0)
#define qemudDebug(fmt, ...) do {} while(0)
...
@@ -83,6 +84,9 @@ struct qemud_driver {
...
@@ -83,6 +84,9 @@ struct qemud_driver {
virDomainEventQueuePtr
domainEventQueue
;
virDomainEventQueuePtr
domainEventQueue
;
int
domainEventTimer
;
int
domainEventTimer
;
int
domainEventDispatching
;
int
domainEventDispatching
;
char
*
securityDriverName
;
virSecurityDriverPtr
securityDriver
;
};
};
/* Status needed to reconenct to running VMs */
/* Status needed to reconenct to running VMs */
...
...
src/qemu_driver.c
浏览文件 @
d0aa10fd
...
@@ -70,6 +70,8 @@
...
@@ -70,6 +70,8 @@
#include "domain_conf.h"
#include "domain_conf.h"
#include "node_device_conf.h"
#include "node_device_conf.h"
#include "pci.h"
#include "pci.h"
#include "security.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
#define VIR_FROM_THIS VIR_FROM_QEMU
...
@@ -351,6 +353,57 @@ next:
...
@@ -351,6 +353,57 @@ next:
return
0
;
return
0
;
}
}
static
int
qemudSecurityInit
(
struct
qemud_driver
*
qemud_drv
)
{
int
ret
;
const
char
*
doi
,
*
model
;
virCapsPtr
caps
;
virSecurityDriverPtr
security_drv
;
ret
=
virSecurityDriverStartup
(
&
security_drv
,
qemud_drv
->
securityDriverName
);
if
(
ret
==
-
1
)
{
VIR_ERROR0
(
_
(
"Failed to start security driver"
));
return
-
1
;
}
/* No security driver wanted to be enabled: just return */
if
(
ret
==
-
2
)
{
VIR_INFO0
(
_
(
"No security driver available"
));
return
0
;
}
qemud_drv
->
securityDriver
=
security_drv
;
doi
=
virSecurityDriverGetDOI
(
security_drv
);
model
=
virSecurityDriverGetModel
(
security_drv
);
VIR_DEBUG
(
"Initialized security driver
\"
%s
\"
with "
"DOI
\"
%s
\"
"
,
model
,
doi
);
/*
* Add security policy host caps now that the security driver is
* initialized.
*/
caps
=
qemud_drv
->
caps
;
caps
->
host
.
secModel
.
model
=
strdup
(
model
);
if
(
!
caps
->
host
.
secModel
.
model
)
{
char
ebuf
[
1024
];
VIR_ERROR
(
_
(
"Failed to copy secModel model: %s"
),
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
return
-
1
;
}
caps
->
host
.
secModel
.
doi
=
strdup
(
doi
);
if
(
!
caps
->
host
.
secModel
.
doi
)
{
char
ebuf
[
1024
];
VIR_ERROR
(
_
(
"Failed to copy secModel DOI: %s"
),
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
return
-
1
;
}
return
0
;
}
/**
/**
* qemudStartup:
* qemudStartup:
...
@@ -443,6 +496,10 @@ qemudStartup(void) {
...
@@ -443,6 +496,10 @@ qemudStartup(void) {
if
((
qemu_driver
->
caps
=
qemudCapsInit
())
==
NULL
)
if
((
qemu_driver
->
caps
=
qemudCapsInit
())
==
NULL
)
goto
out_of_memory
;
goto
out_of_memory
;
if
(
qemudSecurityInit
(
qemu_driver
)
<
0
)
{
goto
error
;
}
if
(
qemudLoadDriverConfig
(
qemu_driver
,
driverConf
)
<
0
)
{
if
(
qemudLoadDriverConfig
(
qemu_driver
,
driverConf
)
<
0
)
{
goto
error
;
goto
error
;
}
}
...
@@ -555,6 +612,7 @@ qemudShutdown(void) {
...
@@ -555,6 +612,7 @@ qemudShutdown(void) {
virDomainObjListFree
(
&
qemu_driver
->
domains
);
virDomainObjListFree
(
&
qemu_driver
->
domains
);
VIR_FREE
(
qemu_driver
->
securityDriverName
);
VIR_FREE
(
qemu_driver
->
logDir
);
VIR_FREE
(
qemu_driver
->
logDir
);
VIR_FREE
(
qemu_driver
->
configDir
);
VIR_FREE
(
qemu_driver
->
configDir
);
VIR_FREE
(
qemu_driver
->
autostartDir
);
VIR_FREE
(
qemu_driver
->
autostartDir
);
...
@@ -1204,9 +1262,35 @@ error:
...
@@ -1204,9 +1262,35 @@ error:
return
-
1
;
return
-
1
;
}
}
static
int
qemudDomainSetSecurityLabel
(
virConnectPtr
conn
,
struct
qemud_driver
*
driver
,
virDomainObjPtr
vm
)
{
if
(
vm
->
def
->
seclabel
.
label
!=
NULL
)
if
(
driver
->
securityDriver
&&
driver
->
securityDriver
->
domainSetSecurityLabel
)
return
driver
->
securityDriver
->
domainSetSecurityLabel
(
conn
,
driver
->
securityDriver
,
vm
);
return
0
;
}
static
virDomainPtr
qemudDomainLookupByName
(
virConnectPtr
conn
,
static
virDomainPtr
qemudDomainLookupByName
(
virConnectPtr
conn
,
const
char
*
name
);
const
char
*
name
);
struct
gemudHookData
{
virConnectPtr
conn
;
virDomainObjPtr
vm
;
struct
qemud_driver
*
driver
;
};
static
int
qemudSecurityHook
(
void
*
data
)
{
struct
gemudHookData
*
h
=
(
struct
gemudHookData
*
)
data
;
if
(
qemudDomainSetSecurityLabel
(
h
->
conn
,
h
->
driver
,
h
->
vm
)
<
0
)
{
qemudReportError
(
h
->
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"Failed to set security label"
));
return
-
1
;
}
return
0
;
}
static
int
qemudStartVMDaemon
(
virConnectPtr
conn
,
static
int
qemudStartVMDaemon
(
virConnectPtr
conn
,
struct
qemud_driver
*
driver
,
struct
qemud_driver
*
driver
,
virDomainObjPtr
vm
,
virDomainObjPtr
vm
,
...
@@ -1225,6 +1309,21 @@ static int qemudStartVMDaemon(virConnectPtr conn,
...
@@ -1225,6 +1309,21 @@ static int qemudStartVMDaemon(virConnectPtr conn,
int
pos
=
-
1
;
int
pos
=
-
1
;
char
ebuf
[
1024
];
char
ebuf
[
1024
];
struct
gemudHookData
hookData
;
hookData
.
conn
=
conn
;
hookData
.
vm
=
vm
;
hookData
.
driver
=
driver
;
/* If you are using a SecurityDriver and there was no security label in
database, then generate a security label for isolation */
if
(
vm
->
def
->
seclabel
.
label
==
NULL
&&
driver
->
securityDriver
)
{
if
(
driver
->
securityDriver
->
domainGenSecurityLabel
(
vm
)
<
0
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"Unable to generate Security Label"
));
return
-
1
;
}
}
FD_ZERO
(
&
keepfd
);
FD_ZERO
(
&
keepfd
);
if
(
virDomainIsActive
(
vm
))
{
if
(
virDomainIsActive
(
vm
))
{
...
@@ -1325,9 +1424,10 @@ static int qemudStartVMDaemon(virConnectPtr conn,
...
@@ -1325,9 +1424,10 @@ static int qemudStartVMDaemon(virConnectPtr conn,
for
(
i
=
0
;
i
<
ntapfds
;
i
++
)
for
(
i
=
0
;
i
<
ntapfds
;
i
++
)
FD_SET
(
tapfds
[
i
],
&
keepfd
);
FD_SET
(
tapfds
[
i
],
&
keepfd
);
ret
=
virExec
(
conn
,
argv
,
progenv
,
&
keepfd
,
&
child
,
ret
=
virExecWithHook
(
conn
,
argv
,
progenv
,
&
keepfd
,
&
child
,
stdin_fd
,
&
vm
->
logfile
,
&
vm
->
logfile
,
stdin_fd
,
&
vm
->
logfile
,
&
vm
->
logfile
,
VIR_EXEC_NONBLOCK
|
VIR_EXEC_DAEMON
);
VIR_EXEC_NONBLOCK
|
VIR_EXEC_DAEMON
,
qemudSecurityHook
,
&
hookData
);
/* wait for qemu process to to show up */
/* wait for qemu process to to show up */
if
(
ret
==
0
)
{
if
(
ret
==
0
)
{
...
@@ -1423,6 +1523,10 @@ static void qemudShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
...
@@ -1423,6 +1523,10 @@ static void qemudShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
/* shut it off for sure */
/* shut it off for sure */
virKillProcess
(
vm
->
pid
,
SIGKILL
);
virKillProcess
(
vm
->
pid
,
SIGKILL
);
/* Reset Security Labels */
if
(
driver
->
securityDriver
)
driver
->
securityDriver
->
domainRestoreSecurityLabel
(
conn
,
vm
);
if
(
qemudRemoveDomainStatus
(
conn
,
driver
,
vm
)
<
0
)
{
if
(
qemudRemoveDomainStatus
(
conn
,
driver
,
vm
)
<
0
)
{
VIR_WARN
(
_
(
"Failed to remove domain status for %s"
),
VIR_WARN
(
_
(
"Failed to remove domain status for %s"
),
vm
->
def
->
name
);
vm
->
def
->
name
);
...
@@ -2832,7 +2936,94 @@ cleanup:
...
@@ -2832,7 +2936,94 @@ cleanup:
return
ret
;
return
ret
;
}
}
static
int
qemudDomainGetSecurityLabel
(
virDomainPtr
dom
,
virSecurityLabelPtr
seclabel
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
;
const
char
*
type
;
int
ret
=
-
1
;
qemuDriverLock
(
driver
);
vm
=
virDomainFindByUUID
(
&
driver
->
domains
,
dom
->
uuid
);
qemuDriverUnlock
(
driver
);
if
(
!
vm
)
{
char
uuidstr
[
VIR_UUID_STRING_BUFLEN
];
virUUIDFormat
(
dom
->
uuid
,
uuidstr
);
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INVALID_DOMAIN
,
_
(
"no domain with matching uuid '%s'"
),
uuidstr
);
goto
cleanup
;
}
if
(
!
(
type
=
virDomainVirtTypeToString
(
vm
->
def
->
virtType
)))
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"unknown virt type in domain definition '%d'"
),
vm
->
def
->
virtType
);
goto
cleanup
;
}
/*
* Theoretically, the pid can be replaced during this operation and
* return the label of a different process. If atomicity is needed,
* further validation will be required.
*
* Comment from Dan Berrange:
*
* Well the PID as stored in the virDomainObjPtr can't be changed
* because you've got a locked object. The OS level PID could have
* exited, though and in extreme circumstances have cycled through all
* PIDs back to ours. We could sanity check that our PID still exists
* after reading the label, by checking that our FD connecting to the
* QEMU monitor hasn't seen SIGHUP/ERR on poll().
*/
if
(
virDomainIsActive
(
vm
))
{
if
(
driver
->
securityDriver
&&
driver
->
securityDriver
->
domainGetSecurityLabel
)
{
if
(
driver
->
securityDriver
->
domainGetSecurityLabel
(
dom
->
conn
,
vm
,
seclabel
)
==
-
1
)
{
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"Failed to get security label"
));
goto
cleanup
;
}
}
}
ret
=
0
;
cleanup:
if
(
vm
)
virDomainObjUnlock
(
vm
);
return
ret
;
}
static
int
qemudNodeGetSecurityModel
(
virConnectPtr
conn
,
virSecurityModelPtr
secmodel
)
{
struct
qemud_driver
*
driver
=
(
struct
qemud_driver
*
)
conn
->
privateData
;
char
*
p
;
if
(
!
driver
->
securityDriver
)
return
-
2
;
p
=
driver
->
caps
->
host
.
secModel
.
model
;
if
(
strlen
(
p
)
>=
VIR_SECURITY_MODEL_BUFLEN
-
1
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"security model string exceeds max %d bytes"
),
VIR_SECURITY_MODEL_BUFLEN
-
1
);
return
-
1
;
}
strcpy
(
secmodel
->
model
,
p
);
p
=
driver
->
caps
->
host
.
secModel
.
doi
;
if
(
strlen
(
p
)
>=
VIR_SECURITY_DOI_BUFLEN
-
1
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"security DOI string exceeds max %d bytes"
),
VIR_SECURITY_DOI_BUFLEN
-
1
);
return
-
1
;
}
strcpy
(
secmodel
->
doi
,
p
);
return
0
;
}
/* TODO: check seclabel restore */
static
int
qemudDomainRestore
(
virConnectPtr
conn
,
static
int
qemudDomainRestore
(
virConnectPtr
conn
,
const
char
*
path
)
{
const
char
*
path
)
{
struct
qemud_driver
*
driver
=
conn
->
privateData
;
struct
qemud_driver
*
driver
=
conn
->
privateData
;
...
@@ -3559,6 +3750,8 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
...
@@ -3559,6 +3750,8 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
virDomainDiskBusTypeToString
(
dev
->
data
.
disk
->
bus
));
virDomainDiskBusTypeToString
(
dev
->
data
.
disk
->
bus
));
goto
cleanup
;
goto
cleanup
;
}
}
if
(
driver
->
securityDriver
)
driver
->
securityDriver
->
domainSetSecurityImageLabel
(
dom
->
conn
,
vm
,
dev
);
break
;
break
;
default:
default:
...
@@ -3691,8 +3884,11 @@ static int qemudDomainDetachDevice(virDomainPtr dom,
...
@@ -3691,8 +3884,11 @@ static int qemudDomainDetachDevice(virDomainPtr dom,
if
(
dev
->
type
==
VIR_DOMAIN_DEVICE_DISK
&&
if
(
dev
->
type
==
VIR_DOMAIN_DEVICE_DISK
&&
dev
->
data
.
disk
->
device
==
VIR_DOMAIN_DISK_DEVICE_DISK
&&
dev
->
data
.
disk
->
device
==
VIR_DOMAIN_DISK_DEVICE_DISK
&&
(
dev
->
data
.
disk
->
bus
==
VIR_DOMAIN_DISK_BUS_SCSI
||
(
dev
->
data
.
disk
->
bus
==
VIR_DOMAIN_DISK_BUS_SCSI
||
dev
->
data
.
disk
->
bus
==
VIR_DOMAIN_DISK_BUS_VIRTIO
))
dev
->
data
.
disk
->
bus
==
VIR_DOMAIN_DISK_BUS_VIRTIO
))
{
ret
=
qemudDomainDetachPciDiskDevice
(
dom
->
conn
,
vm
,
dev
);
ret
=
qemudDomainDetachPciDiskDevice
(
dom
->
conn
,
vm
,
dev
);
if
(
driver
->
securityDriver
)
driver
->
securityDriver
->
domainRestoreSecurityImageLabel
(
dom
->
conn
,
vm
,
dev
);
}
else
else
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
"%s"
,
_
(
"only SCSI or virtio disk device can be detached dynamically"
));
"%s"
,
_
(
"only SCSI or virtio disk device can be detached dynamically"
));
...
@@ -4741,8 +4937,8 @@ static virDriver qemuDriver = {
...
@@ -4741,8 +4937,8 @@ static virDriver qemuDriver = {
NULL
,
/* domainGetVcpus */
NULL
,
/* domainGetVcpus */
#endif
#endif
qemudDomainGetMaxVcpus
,
/* domainGetMaxVcpus */
qemudDomainGetMaxVcpus
,
/* domainGetMaxVcpus */
NULL
,
/* domainGetSecurityLabel */
qemudDomainGetSecurityLabel
,
/* domainGetSecurityLabel */
NULL
,
/* nodeGetSecurityModel */
qemudNodeGetSecurityModel
,
/* nodeGetSecurityModel */
qemudDomainDumpXML
,
/* domainDumpXML */
qemudDomainDumpXML
,
/* domainDumpXML */
qemudListDefinedDomains
,
/* listDomains */
qemudListDefinedDomains
,
/* listDomains */
qemudNumDefinedDomains
,
/* numOfDomains */
qemudNumDefinedDomains
,
/* numOfDomains */
...
...
src/util.c
浏览文件 @
d0aa10fd
...
@@ -420,8 +420,8 @@ __virExec(virConnectPtr conn,
...
@@ -420,8 +420,8 @@ __virExec(virConnectPtr conn,
close
(
childerr
);
close
(
childerr
);
if
(
hook
)
if
(
hook
)
(
hook
)(
data
);
if
((
hook
)(
data
)
!=
0
)
_exit
(
1
);
if
(
envp
)
if
(
envp
)
execve
(
argv
[
0
],
(
char
**
)
argv
,
(
char
**
)
envp
);
execve
(
argv
[
0
],
(
char
**
)
argv
,
(
char
**
)
envp
);
else
else
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录