Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
libvirt
提交
41ed6eb3
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,发现更多精彩内容 >>
提交
41ed6eb3
编写于
3月 03, 2009
作者:
D
Daniel P. Berrange
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
SELinux security driver for sVirt support (James Morris, Dan Walsh & Daniel Berrange)
上级
aa2c9726
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
461 addition
and
0 deletion
+461
-0
ChangeLog
ChangeLog
+10
-0
configure.in
configure.in
+43
-0
po/POTFILES.in
po/POTFILES.in
+1
-0
src/Makefile.am
src/Makefile.am
+6
-0
src/security.c
src/security.c
+6
-0
src/security_selinux.c
src/security_selinux.c
+377
-0
src/security_selinux.h
src/security_selinux.h
+18
-0
未找到文件。
ChangeLog
浏览文件 @
41ed6eb3
Tue Mar 3 10:01:13 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
SELinux security driver for sVirt support (James Morris, Dan Walsh & Daniel
Berrange)
* configure.in: Check for selinux_virtual_domain_context_path() and
selinux_virtual_image_context_path() methods in libselinux.so
* po/POTFILES.in: add src/security_selinux.c
* src/Makefile.am, src/security.c, src/security_selinux.c,
src/security_selinux.h: Add SELinux impl of security driver API
Tue Mar 3 09:55:13 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
virsh additions for sVirt support (James Morris & Dan Walsh)
...
...
configure.in
浏览文件 @
41ed6eb3
...
...
@@ -640,6 +640,45 @@ AM_CONDITIONAL([HAVE_SELINUX], [test "$with_selinux" != "no"])
AC_SUBST([SELINUX_CFLAGS])
AC_SUBST([SELINUX_LIBS])
AC_ARG_WITH([secdriver-selinux],
[ --with-secdriver-selinux use SELinux security driver],
[],
[with_secdriver_selinux=check])
if test "$with_selinux" != "yes" ; then
if test "$with_secdriver_selinux" = "check" ; then
with_secdriver_selinux=no
else
AC_MSG_ERROR([You must install the SELinux development package in order to compile libvirt])
fi
else
old_cflags="$CFLAGS"
old_libs="$LIBS"
CFLAGS="$CFLAGS $SELINUX_CFLAGS"
LIBS="$CFLAGS $SELINUX_LIBS"
fail=0
AC_CHECK_FUNC([selinux_virtual_domain_context_path], [], [fail=1])
AC_CHECK_FUNC([selinux_virtual_image_context_path], [], [fail=1])
CFLAGS="$old_cflags"
LIBS="$old_libs"
if test "$fail" = "1" ; then
if test "$with_secdriver_selinux" = "check" ; then
with_secdriver_selinux=no
else
AC_MSG_ERROR([You must install the SELinux development package in order to compile libvirt])
fi
else
with_secdriver_selinux=yes
AC_DEFINE_UNQUOTED([WITH_SECDRIVER_SELINUX], 1, [whether SELinux security driver is available])
fi
fi
AM_CONDITIONAL([WITH_SECDRIVER_SELINUX], [test "$with_secdriver_selinux" != "no"])
dnl NUMA lib
AC_ARG_WITH([numactl],
[ --with-numactl use numactl for host topology info],
...
...
@@ -1320,6 +1359,10 @@ AC_MSG_NOTICE([ LVM: $with_storage_lvm])
AC_MSG_NOTICE([ iSCSI: $with_storage_iscsi])
AC_MSG_NOTICE([ Disk: $with_storage_disk])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([Security Drivers])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([ SELinux: $with_secdriver_selinux])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([Driver Loadable Modules])
AC_MSG_NOTICE([])
if test "$with_driver_modules" != "no" ; then
...
...
po/POTFILES.in
浏览文件 @
41ed6eb3
...
...
@@ -24,6 +24,7 @@ src/qemu_conf.c
src/qemu_driver.c
src/remote_internal.c
src/security.c
src/security_selinux.c
src/storage_backend.c
src/storage_backend_disk.c
src/storage_backend_fs.c
...
...
src/Makefile.am
浏览文件 @
41ed6eb3
...
...
@@ -170,6 +170,9 @@ STORAGE_HELPER_DISK_SOURCES = \
SECURITY_DRIVER_SOURCES
=
\
security.h security.c
SECURITY_DRIVER_SELINUX_SOURCES
=
\
security_selinux.h security_selinux.c
NODE_DEVICE_DRIVER_SOURCES
=
\
node_device.c node_device.h
...
...
@@ -387,6 +390,9 @@ endif
libvirt_driver_security_la_SOURCES
=
$(SECURITY_DRIVER_SOURCES)
noinst_LTLIBRARIES
+=
libvirt_driver_security.la
libvirt_la_LIBADD
+=
libvirt_driver_security.la
if
WITH_SECDRIVER_SELINUX
libvirt_driver_security_la_SOURCES
+=
$(SECURITY_DRIVER_SELINUX_SOURCES)
endif
# Add all conditional sources just in case...
EXTRA_DIST
+=
\
...
...
src/security.c
浏览文件 @
41ed6eb3
...
...
@@ -16,8 +16,14 @@
#include "virterror_internal.h"
#include "security.h"
#ifdef WITH_SECDRIVER_SELINUX
#include "security_selinux.h"
#endif
static
virSecurityDriverPtr
security_drivers
[]
=
{
#ifdef WITH_SECDRIVER_SELINUX
&
virSELinuxSecurityDriver
,
#endif
NULL
};
...
...
src/security_selinux.c
0 → 100644
浏览文件 @
41ed6eb3
/*
* Copyright (C) 2008 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Authors:
* James Morris <jmorris@namei.org>
*
* SELinux security driver.
*/
#include <config.h>
#include <selinux/selinux.h>
#include <selinux/context.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "security.h"
#include "security_selinux.h"
#include "virterror_internal.h"
#include "util.h"
#include "memory.h"
static
char
default_domain_context
[
1024
];
static
char
default_image_context
[
1024
];
#define SECURITY_SELINUX_VOID_DOI "0"
#define SECURITY_SELINUX_NAME "selinux"
/* TODO
The data struct of used mcs should be replaced with a better data structure in the future
*/
struct
MCS
{
char
*
mcs
;
struct
MCS
*
next
;
};
static
struct
MCS
*
mcsList
=
NULL
;
static
int
mcsAdd
(
const
char
*
mcs
)
{
struct
MCS
*
ptr
;
for
(
ptr
=
mcsList
;
ptr
;
ptr
=
ptr
->
next
)
{
if
(
STREQ
(
ptr
->
mcs
,
mcs
)
==
0
)
return
-
1
;
}
ptr
=
malloc
(
sizeof
(
struct
MCS
));
ptr
->
mcs
=
strdup
(
mcs
);
ptr
->
next
=
mcsList
;
mcsList
=
ptr
;
return
0
;
}
static
int
mcsRemove
(
const
char
*
mcs
)
{
struct
MCS
*
prevptr
=
NULL
;
struct
MCS
*
ptr
=
NULL
;
for
(
ptr
=
mcsList
;
ptr
;
ptr
=
ptr
->
next
)
{
if
(
STREQ
(
ptr
->
mcs
,
mcs
)
==
0
)
{
if
(
prevptr
)
prevptr
->
next
=
ptr
->
next
;
else
{
mcsList
=
ptr
->
next
;
}
free
(
ptr
->
mcs
);
free
(
ptr
);
return
0
;
}
prevptr
=
ptr
;
}
return
-
1
;
}
static
char
*
SELinuxGenNewContext
(
const
char
*
oldcontext
,
const
char
*
mcs
)
{
char
*
newcontext
=
NULL
;
char
*
scontext
=
strdup
(
oldcontext
);
if
(
!
scontext
)
goto
err
;
context_t
con
=
context_new
(
scontext
);
if
(
!
con
)
goto
err
;
context_range_set
(
con
,
mcs
);
newcontext
=
strdup
(
context_str
(
con
));
context_free
(
con
);
err:
freecon
(
scontext
);
return
(
newcontext
);
}
static
int
SELinuxInitialize
(
virConnectPtr
conn
)
{
char
*
ptr
=
NULL
;
int
fd
=
0
;
char
ebuf
[
1024
];
virRandomInitialize
(
time
(
NULL
)
^
getpid
());
fd
=
open
(
selinux_virtual_domain_context_path
(),
O_RDONLY
);
if
(
fd
<
0
)
{
virSecurityReportError
(
conn
,
VIR_ERR_ERROR
,
_
(
"%s: cannot open SELinux virtual domain context file %s: %s"
),
__func__
,
selinux_virtual_domain_context_path
(),
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
return
-
1
;
}
if
(
saferead
(
fd
,
default_domain_context
,
sizeof
(
default_domain_context
))
<
0
)
{
virSecurityReportError
(
conn
,
VIR_ERR_ERROR
,
_
(
"%s: cannot read SELinux virtual domain context file %s: %s"
),
__func__
,
selinux_virtual_domain_context_path
(),
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
close
(
fd
);
return
-
1
;
}
close
(
fd
);
ptr
=
strchrnul
(
default_domain_context
,
'\n'
);
*
ptr
=
'\0'
;
if
((
fd
=
open
(
selinux_virtual_image_context_path
(),
O_RDONLY
))
<
0
)
{
virSecurityReportError
(
conn
,
VIR_ERR_ERROR
,
_
(
"%s: cannot open SELinux virtual image context file %s: %s"
),
__func__
,
selinux_virtual_image_context_path
(),
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
return
-
1
;
}
if
(
saferead
(
fd
,
default_image_context
,
sizeof
(
default_image_context
))
<
0
)
{
virSecurityReportError
(
conn
,
VIR_ERR_ERROR
,
_
(
"%s: cannot read SELinux virtual image context file %s: %s"
),
__func__
,
selinux_virtual_image_context_path
(),
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
close
(
fd
);
return
-
1
;
}
close
(
fd
);
ptr
=
strchrnul
(
default_image_context
,
'\n'
);
*
ptr
=
'\0'
;
return
0
;
}
static
int
SELinuxGenSecurityLabel
(
virDomainObjPtr
vm
)
{
int
rc
=
-
1
;
char
mcs
[
1024
];
char
*
scontext
=
NULL
;
int
c1
=
0
;
int
c2
=
0
;
if
(
(
vm
->
def
->
seclabel
.
label
)
||
(
vm
->
def
->
seclabel
.
model
)
||
(
vm
->
def
->
seclabel
.
imagelabel
))
return
rc
;
do
{
c1
=
virRandom
(
1024
);
c2
=
virRandom
(
1024
);
if
(
c1
==
c2
)
{
sprintf
(
mcs
,
"s0:c%d"
,
c1
);
}
else
{
if
(
c1
==
c2
)
sprintf
(
mcs
,
"s0:c%d,c%d"
,
c1
,
c2
);
else
sprintf
(
mcs
,
"s0:c%d,c%d"
,
c2
,
c1
);
}
}
while
(
mcsAdd
(
mcs
)
==
-
1
);
vm
->
def
->
seclabel
.
label
=
SELinuxGenNewContext
(
default_domain_context
,
mcs
);
if
(
!
vm
->
def
->
seclabel
.
label
)
goto
err
;
vm
->
def
->
seclabel
.
imagelabel
=
SELinuxGenNewContext
(
default_image_context
,
mcs
);
if
(
!
vm
->
def
->
seclabel
.
imagelabel
)
goto
err
;
vm
->
def
->
seclabel
.
model
=
strdup
(
SECURITY_SELINUX_NAME
);
if
(
!
vm
->
def
->
seclabel
.
model
)
goto
err
;
rc
=
0
;
goto
done
;
err:
free
(
vm
->
def
->
seclabel
.
label
);
vm
->
def
->
seclabel
.
label
=
NULL
;
free
(
vm
->
def
->
seclabel
.
imagelabel
);
vm
->
def
->
seclabel
.
imagelabel
=
NULL
;
free
(
vm
->
def
->
seclabel
.
model
);
vm
->
def
->
seclabel
.
model
=
NULL
;
done:
free
(
scontext
);
return
rc
;
}
static
int
SELinuxSecurityDriverProbe
(
void
)
{
return
is_selinux_enabled
()
?
SECURITY_DRIVER_ENABLE
:
SECURITY_DRIVER_DISABLE
;
}
static
int
SELinuxSecurityDriverOpen
(
virConnectPtr
conn
,
virSecurityDriverPtr
drv
)
{
/*
* Where will the DOI come from? SELinux configuration, or qemu
* configuration? For the moment, we'll just set it to "0".
*/
virSecurityDriverSetDOI
(
conn
,
drv
,
SECURITY_SELINUX_VOID_DOI
);
return
SELinuxInitialize
(
conn
);
}
static
int
SELinuxGetSecurityLabel
(
virConnectPtr
conn
,
virDomainObjPtr
vm
,
virSecurityLabelPtr
sec
)
{
security_context_t
ctx
;
if
(
getpidcon
(
vm
->
pid
,
&
ctx
)
==
-
1
)
{
char
ebuf
[
1024
];
virSecurityReportError
(
conn
,
VIR_ERR_ERROR
,
_
(
"%s: error calling "
"getpidcon(): %s"
),
__func__
,
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
return
-
1
;
}
if
(
strlen
((
char
*
)
ctx
)
>=
VIR_SECURITY_LABEL_BUFLEN
)
{
virSecurityReportError
(
conn
,
VIR_ERR_ERROR
,
_
(
"%s: security label exceeds "
"maximum lenth: %d"
),
__func__
,
VIR_SECURITY_LABEL_BUFLEN
-
1
);
return
-
1
;
}
strcpy
(
sec
->
label
,
(
char
*
)
ctx
);
free
(
ctx
);
sec
->
enforcing
=
security_getenforce
();
if
(
sec
->
enforcing
==
-
1
)
{
char
ebuf
[
1024
];
virSecurityReportError
(
conn
,
VIR_ERR_ERROR
,
_
(
"%s: error calling "
"security_getenforce(): %s"
),
__func__
,
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
return
-
1
;
}
return
0
;
}
static
int
SELinuxSetFilecon
(
virConnectPtr
conn
,
char
*
path
,
char
*
tcon
)
{
char
ebuf
[
1024
];
if
(
setfilecon
(
path
,
tcon
)
<
0
)
{
virSecurityReportError
(
conn
,
VIR_ERR_ERROR
,
_
(
"%s: unable to set security context "
"'\%s
\'
on %s: %s."
),
__func__
,
tcon
,
path
,
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
if
(
security_getenforce
()
==
1
)
return
-
1
;
}
return
0
;
}
static
int
SELinuxRestoreSecurityImageLabel
(
virConnectPtr
conn
,
virDomainObjPtr
vm
,
virDomainDeviceDefPtr
dev
)
{
const
virSecurityLabelDefPtr
secdef
=
&
vm
->
def
->
seclabel
;
if
(
secdef
->
imagelabel
)
{
return
SELinuxSetFilecon
(
conn
,
dev
->
data
.
disk
->
src
,
default_image_context
);
}
return
0
;
}
static
int
SELinuxSetSecurityImageLabel
(
virConnectPtr
conn
,
virDomainObjPtr
vm
,
virDomainDeviceDefPtr
dev
)
{
const
virSecurityLabelDefPtr
secdef
=
&
vm
->
def
->
seclabel
;
if
(
secdef
->
imagelabel
)
{
return
SELinuxSetFilecon
(
conn
,
dev
->
data
.
disk
->
src
,
secdef
->
imagelabel
);
}
return
0
;
}
static
int
SELinuxRestoreSecurityLabel
(
virConnectPtr
conn
,
virDomainObjPtr
vm
)
{
const
virSecurityLabelDefPtr
secdef
=
&
vm
->
def
->
seclabel
;
int
i
;
int
rc
=
0
;
if
(
secdef
->
imagelabel
)
{
for
(
i
=
0
;
i
<
vm
->
def
->
ndisks
;
i
++
)
{
if
(
SELinuxSetFilecon
(
conn
,
vm
->
def
->
disks
[
i
]
->
src
,
default_image_context
)
<
0
)
rc
=
-
1
;
}
VIR_FREE
(
secdef
->
model
);
VIR_FREE
(
secdef
->
label
);
context_t
con
=
context_new
(
secdef
->
imagelabel
);
if
(
con
)
{
mcsRemove
(
context_range_get
(
con
));
context_free
(
con
);
}
VIR_FREE
(
secdef
->
imagelabel
);
}
return
rc
;
}
static
int
SELinuxSetSecurityLabel
(
virConnectPtr
conn
,
virSecurityDriverPtr
drv
,
virDomainObjPtr
vm
)
{
/* TODO: verify DOI */
const
virSecurityLabelDefPtr
secdef
=
&
vm
->
def
->
seclabel
;
int
i
;
char
ebuf
[
1024
];
if
(
!
STREQ
(
drv
->
name
,
secdef
->
model
))
{
virSecurityReportError
(
conn
,
VIR_ERR_ERROR
,
_
(
"%s: security label driver mismatch: "
"
\'
%s
\'
model configured for domain, but "
"hypervisor driver is
\'
%s
\'
."
),
__func__
,
secdef
->
model
,
drv
->
name
);
if
(
security_getenforce
()
==
1
)
return
-
1
;
}
if
(
setexeccon
(
secdef
->
label
)
==
-
1
)
{
virSecurityReportError
(
conn
,
VIR_ERR_ERROR
,
_
(
"%s: unable to set security context "
"'\%s
\'
: %s."
),
__func__
,
secdef
->
label
,
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
if
(
security_getenforce
()
==
1
)
return
-
1
;
}
if
(
secdef
->
imagelabel
)
{
for
(
i
=
0
;
i
<
vm
->
def
->
ndisks
;
i
++
)
{
if
(
setfilecon
(
vm
->
def
->
disks
[
i
]
->
src
,
secdef
->
imagelabel
)
<
0
)
{
virSecurityReportError
(
conn
,
VIR_ERR_ERROR
,
_
(
"%s: unable to set security context "
"'\%s
\'
on %s: %s."
),
__func__
,
secdef
->
imagelabel
,
vm
->
def
->
disks
[
i
]
->
src
,
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
if
(
security_getenforce
()
==
1
)
return
-
1
;
}
}
}
return
0
;
}
virSecurityDriver
virSELinuxSecurityDriver
=
{
.
name
=
SECURITY_SELINUX_NAME
,
.
probe
=
SELinuxSecurityDriverProbe
,
.
open
=
SELinuxSecurityDriverOpen
,
.
domainSetSecurityImageLabel
=
SELinuxSetSecurityImageLabel
,
.
domainRestoreSecurityImageLabel
=
SELinuxRestoreSecurityImageLabel
,
.
domainGenSecurityLabel
=
SELinuxGenSecurityLabel
,
.
domainGetSecurityLabel
=
SELinuxGetSecurityLabel
,
.
domainRestoreSecurityLabel
=
SELinuxRestoreSecurityLabel
,
.
domainSetSecurityLabel
=
SELinuxSetSecurityLabel
,
};
src/security_selinux.h
0 → 100644
浏览文件 @
41ed6eb3
/*
* Copyright (C) 2008 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Authors:
* James Morris <jmorris@namei.org>
*
*/
#ifndef __VIR_SECURITY_SELINUX_H__
#define __VIR_SECURITY_SELINUX_H__
extern
virSecurityDriver
virSELinuxSecurityDriver
;
#endif
/* __VIR_SECURITY_SELINUX_H__ */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录