详解SELinux SID
Intro
SID = Security Identifier (即Security ID)。其作用就是取代安全上下文,在权限匹配时,提升规则搜索速度,以及降低整个策略数据的空间复杂度,提升了整个SELinux特性的性能损耗。
例如一次权限匹配的函数调用原型如下:
int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass,
u32 requested, struct common_audit_data *auditdata)
其中ssid, tsid就代表了源(source)SID和目的(target)SID。在最终的av(access vector)计算中,SID被转化为context。
什么是context?
context,即安全上下文,是SELinux的核心概念。形如user_u:role_r:type_t:s0-s1:c0,c1-c255
的就是context。其中user字段和role字段用于RBAC,type字段用于TEAC,后面的s0-s1,c1-c255用于mls/mcs。而所有的这些字段,都由策略编译工具生成了整数数据,在SELinux加载策略时一并加载到内存policydb中。
// context定义
struct context {
u32 user;
u32 role;
u32 type;
u32 len; /* length of string in bytes */
struct mls_range range;
char *str; /* string representation if context cannot be mapped. */
};
// context加载
static int context_read_and_validate(struct context *c,
struct policydb *p,
void *fp)
{
...
c->user = le32_to_cpu(buf[0]);
c->role = le32_to_cpu(buf[1]);
c->type = le32_to_cpu(buf[2]);
...
}
在真正的权限匹配时,SELinux通过SID获取到对应的context,再通过context中的type属性,所搜policydb中相应的hash表找到对应的map array,并获取对应某个权限的一个bit位,来得到权限判定结果。
// 搜索sidtab获取SID对应的context,并用context数据结构来计算权限
void security_compute_av(struct selinux_state *state,
u32 ssid,
u32 tsid,
u16 orig_tclass,
struct av_decision *avd,
struct extended_perms *xperms)
{
scontext = sidtab_search(sidtab, ssid);
...
tcontext = sidtab_search(sidtab, tsid);
...
context_struct_compute_av(policydb, scontext, tcontext, tclass, avd,
xperms);
...
}
// 通过context的type字段从policydb中获取权限数据
static void context_struct_compute_av(struct policydb *policydb,
struct context *scontext,
struct context *tcontext,
u16 tclass,
struct av_decision *avd,
struct extended_perms *xperms)
{
...
sattr = flex_array_get(policydb->type_attr_map_array,
scontext->type - 1);
tattr = flex_array_get(policydb->type_attr_map_array,
tcontext->type - 1);
ebitmap_for_each_positive_bit(sattr, snode, i) {
ebitmap_for_each_positive_bit(tattr, tnode, j) {
...
for (node = avtab_search_node(&policydb->te_avtab,
&avkey);
node;
node = avtab_search_node_next(node, avkey.specified)) {
// Get and assign perm data
}
...
}
}
...
}
initial SID
initial SID是一种比较特殊的SID。他在策略编译和SELinux启动中都扮演了非常重要的角色。通常在编译policy的时候,需要一些flask文件,例如Fedora refpolicy:
> ls refpolicy-master/policy/flask/
access_vectors initial_sids security_classes
其中initial_sids就指定了policy二进制中所有的initial SID。内容如下:
# FLASK
#
# Define initial security identifiers
#
sid kernel
sid security
sid unlabeled
sid fs
sid file
sid file_labels
sid init
sid any_socket
sid port
sid netif
sid netmsg
sid node
sid igmp_packet
sid icmp_socket
sid tcp_socket
sid sysctl_modprobe
sid sysctl
sid sysctl_fs
sid sysctl_kernel
sid sysctl_net
sid sysctl_net_unix
sid sysctl_vm
sid sysctl_dev
sid kmod
sid policy
sid scmp_packet
sid devnull
# FLASK
参考《Building The Sample Policy》中的介绍,这些flask文件的内容将被写到最终的policy二进制文件中(即policy.conf),如下:
notebook-tools/build-sepolicy -o policy.conf -d ../../flask-files
build-sepolicy是一个python的示例程序,他是这样处理flask文件的:
try:
f = Flask()
f.parseSids(flask_dir + "/initial_sids")
f.parseClasses(flask_dir + "/security_classes")
f.parseVectors(flask_dir + "/access_vectors")
# Open the file and then create the requested policy source file
of = open(outf, 'w')
if include == 1:
of.writelines(f.createPolicyHdr(mode))
print("Output header file")
elif cil == 1:
of.writelines(f.createCilPolicy(mode))
print("Output CIL policy")
elif class_perm == 1:
of.writelines(f.createCilClassPerms(mode))
print("Output CIL class permission sets")
elif sids == 1:
of.writelines(f.createCilInitialSIDS(mode))
print("Output CIL initial SIDs")
else:
of.writelines(f.createPolicy(mode))
print("Output Kernel Language policy")
of.close()
可见这些文件的内容,被写入到一个Flask对象中,而该对象的内容最终会被写入策略二进制数据。在后续的策略编译中,这些文件会被checkpolicy来处理。
initial SID的作用
from "SELinux by Example: Using Security Enhanced Linux"
Some objects are labeled via an initial SID early in system initialization, even before the policy is loaded. This labeling behavior is needed, for example, to label objects such as the kernel security server and the root filesystem, which are present in the system before the first policy load. When the policy is eventually loaded, the initial SIDs are then associated with the appropriate security context.
Initial SIDs are also used to prevent objects from having a missing or invalid security context, which would make it impossible for SELinux to correctly enforce access. Instead, SELinux associates these objects with the special unlabeled initial SID. The unlabeled initial SID should have a security context that allows only limited access, thereby preventing inappropriate access until the objects can be relabeled by the administrator or destroyed.
Invalid security contexts most commonly result from loading a new policy that removes users, roles, or types, or changes role or type authorizations. In this situation, the SIDs representing security contexts that use these invalid names or associations will become invalid and are mapped to the unlabeled SID at policy load. Invalid security contexts can also arise when transferring object instances between systems (for example, using removable media). Further, if the objects are created on a non-SELinux system, they will have no associated security context. Regardless of whether the security context is invalid or missing, SELinux will use the unlabeled initial SID on first access to the object as the security context.
总结一下,一共有这几点:
- 系统启动时,policy尚未加载,也就是所有的context还没被抽象成SID,存储在内存中的policydb里。allow规则也还没加载,这时候,为了保证代码归一,所以需要这些unlabeled SID,在SELinux启动流程中,再具体介绍。
- 当系统策略变化时,有些role,user或type被删除,导致一些安全上下文失效了,此时这些安全上下文,在策略加载时,会被映射到这些initial SID上。(这里还没找到具体的代码位置)
启动时的使用
init进程在加载策略之前,首先将SELinux的enforcing模式打开。其打开的方式就是往selinuxfs的enforce文件写1。注意此时策略未加载,初始化也未完成。所以策略判断直接取allow。
void security_compute_av(struct selinux_state *state,
u32 ssid,
u32 tsid,
u16 orig_tclass,
struct av_decision *avd,
struct extended_perms *xperms)
{
...
if (!state->initialized)
goto allow;
...
allow:
avd->allowed = 0xffffffff;
}
但由于用户态的入口是一致的,即启动完成后,用户态可以写同样的enforce文件完成SELinux状态的切换,所以为了判断此时用户态进程是否具有设置的权限,在enforce文件的入口处,对用户态进程权限进行了判定:
length = avc_has_perm(&selinux_state,
current_sid(), SECINITSID_SECURITY,
SECCLASS_SECURITY, SECURITY__SETENFORCE,
NULL);
这里就用到了initial SID - SECINITSID_SECURITY
。这里其实已经可以使用selinuxfs的inode.i_security.sid,但由于selinuxfs未通过系统的file open调用,所以无法使用到inode下的SID标签。
系统标签无效时
以socket bind时,对IP地址进行权限判断为例。该权限判断流程大致如下:
PHN2ZyBpZD0iZHdmaXRrZHZ0NGsiIHdpZHRoPSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXgtd2lkdGg6IDI0OS4wNjI1cHg7IiB2aWV3Qm94PSIwIDAgMjQ5LjA2MjUgMzExLjEyNSI+PHN0eWxlPgoKCiNkd2ZpdGtkdnQ0ayAubGFiZWwgewogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgY29sb3I6ICMzMzM7IH0KCiNkd2ZpdGtkdnQ0ayAubm9kZSByZWN0LAojZHdmaXRrZHZ0NGsgLm5vZGUgY2lyY2xlLAojZHdmaXRrZHZ0NGsgLm5vZGUgZWxsaXBzZSwKI2R3Zml0a2R2dDRrIC5ub2RlIHBvbHlnb24gewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMXB4OyB9CgojZHdmaXRrZHZ0NGsgLm5vZGUuY2xpY2thYmxlIHsKICBjdXJzb3I6IHBvaW50ZXI7IH0KCiNkd2ZpdGtkdnQ0ayAuYXJyb3doZWFkUGF0aCB7CiAgZmlsbDogIzMzMzMzMzsgfQoKI2R3Zml0a2R2dDRrIC5lZGdlUGF0aCAucGF0aCB7CiAgc3Ryb2tlOiAjMzMzMzMzOwogIHN0cm9rZS13aWR0aDogMS41cHg7IH0KCiNkd2ZpdGtkdnQ0ayAuZWRnZUxhYmVsIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZThlOGU4OyB9CgojZHdmaXRrZHZ0NGsgLmNsdXN0ZXIgcmVjdCB7CiAgZmlsbDogI2ZmZmZkZSAhaW1wb3J0YW50OwogIHN0cm9rZTogI2FhYWEzMyAhaW1wb3J0YW50OwogIHN0cm9rZS13aWR0aDogMXB4ICFpbXBvcnRhbnQ7IH0KCiNkd2ZpdGtkdnQ0ayAuY2x1c3RlciB0ZXh0IHsKICBmaWxsOiAjMzMzOyB9CgojZHdmaXRrZHZ0NGsgZGl2Lm1lcm1haWRUb29sdGlwIHsKICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIG1heC13aWR0aDogMjAwcHg7CiAgcGFkZGluZzogMnB4OwogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgZm9udC1zaXplOiAxMnB4OwogIGJhY2tncm91bmQ6ICNmZmZmZGU7CiAgYm9yZGVyOiAxcHggc29saWQgI2FhYWEzMzsKICBib3JkZXItcmFkaXVzOiAycHg7CiAgcG9pbnRlci1ldmVudHM6IG5vbmU7CiAgei1pbmRleDogMTAwOyB9CgojZHdmaXRrZHZ0NGsgLmFjdG9yIHsKICBzdHJva2U6ICNDQ0NDRkY7CiAgZmlsbDogI0VDRUNGRjsgfQoKI2R3Zml0a2R2dDRrIHRleHQuYWN0b3IgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsgfQoKI2R3Zml0a2R2dDRrIC5hY3Rvci1saW5lIHsKICBzdHJva2U6IGdyZXk7IH0KCiNkd2ZpdGtkdnQ0ayAubWVzc2FnZUxpbmUwIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICMzMzM7IH0KCiNkd2ZpdGtkdnQ0ayAubWVzc2FnZUxpbmUxIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICMzMzM7IH0KCiNkd2ZpdGtkdnQ0ayAjYXJyb3doZWFkIHsKICBmaWxsOiAjMzMzOyB9CgojZHdmaXRrZHZ0NGsgI2Nyb3NzaGVhZCBwYXRoIHsKICBmaWxsOiAjMzMzICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjMzMzICFpbXBvcnRhbnQ7IH0KCiNkd2ZpdGtkdnQ0ayAubWVzc2FnZVRleHQgewogIGZpbGw6ICMzMzM7CiAgc3Ryb2tlOiBub25lOyB9CgojZHdmaXRrZHZ0NGsgLmxhYmVsQm94IHsKICBzdHJva2U6ICNDQ0NDRkY7CiAgZmlsbDogI0VDRUNGRjsgfQoKI2R3Zml0a2R2dDRrIC5sYWJlbFRleHQgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsgfQoKI2R3Zml0a2R2dDRrIC5sb29wVGV4dCB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOyB9CgojZHdmaXRrZHZ0NGsgLmxvb3BMaW5lIHsKICBzdHJva2Utd2lkdGg6IDI7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjQ0NDQ0ZGOyB9CgojZHdmaXRrZHZ0NGsgLm5vdGUgewogIHN0cm9rZTogI2FhYWEzMzsKICBmaWxsOiAjZmZmNWFkOyB9CgojZHdmaXRrZHZ0NGsgLm5vdGVUZXh0IHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBmb250LXNpemU6IDE0cHg7IH0KCiNkd2ZpdGtkdnQ0ayAuYWN0aXZhdGlvbjAgewogIGZpbGw6ICNmNGY0ZjQ7CiAgc3Ryb2tlOiAjNjY2OyB9CgojZHdmaXRrZHZ0NGsgLmFjdGl2YXRpb24xIHsKICBmaWxsOiAjZjRmNGY0OwogIHN0cm9rZTogIzY2NjsgfQoKI2R3Zml0a2R2dDRrIC5hY3RpdmF0aW9uMiB7CiAgZmlsbDogI2Y0ZjRmNDsKICBzdHJva2U6ICM2NjY7IH0KCgojZHdmaXRrZHZ0NGsgLnNlY3Rpb24gewogIHN0cm9rZTogbm9uZTsKICBvcGFjaXR5OiAwLjI7IH0KCiNkd2ZpdGtkdnQ0ayAuc2VjdGlvbjAgewogIGZpbGw6IHJnYmEoMTAyLCAxMDIsIDI1NSwgMC40OSk7IH0KCiNkd2ZpdGtkdnQ0ayAuc2VjdGlvbjIgewogIGZpbGw6ICNmZmY0MDA7IH0KCiNkd2ZpdGtkdnQ0ayAuc2VjdGlvbjEsCiNkd2ZpdGtkdnQ0ayAuc2VjdGlvbjMgewogIGZpbGw6IHdoaXRlOwogIG9wYWNpdHk6IDAuMjsgfQoKI2R3Zml0a2R2dDRrIC5zZWN0aW9uVGl0bGUwIHsKICBmaWxsOiAjMzMzOyB9CgojZHdmaXRrZHZ0NGsgLnNlY3Rpb25UaXRsZTEgewogIGZpbGw6ICMzMzM7IH0KCiNkd2ZpdGtkdnQ0ayAuc2VjdGlvblRpdGxlMiB7CiAgZmlsbDogIzMzMzsgfQoKI2R3Zml0a2R2dDRrIC5zZWN0aW9uVGl0bGUzIHsKICBmaWxsOiAjMzMzOyB9CgojZHdmaXRrZHZ0NGsgLnNlY3Rpb25UaXRsZSB7CiAgdGV4dC1hbmNob3I6IHN0YXJ0OwogIGZvbnQtc2l6ZTogMTFweDsKICB0ZXh0LWhlaWdodDogMTRweDsgfQoKCiNkd2ZpdGtkdnQ0ayAuZ3JpZCAudGljayB7CiAgc3Ryb2tlOiBsaWdodGdyZXk7CiAgb3BhY2l0eTogMC4zOwogIHNoYXBlLXJlbmRlcmluZzogY3Jpc3BFZGdlczsgfQoKI2R3Zml0a2R2dDRrIC5ncmlkIHBhdGggewogIHN0cm9rZS13aWR0aDogMDsgfQoKCiNkd2ZpdGtkdnQ0ayAudG9kYXkgewogIGZpbGw6IG5vbmU7CiAgc3Ryb2tlOiByZWQ7CiAgc3Ryb2tlLXdpZHRoOiAycHg7IH0KCgoKI2R3Zml0a2R2dDRrIC50YXNrIHsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkd2ZpdGtkdnQ0ayAudGFza1RleHQgewogIHRleHQtYW5jaG9yOiBtaWRkbGU7CiAgZm9udC1zaXplOiAxMXB4OyB9CgojZHdmaXRrZHZ0NGsgLnRhc2tUZXh0T3V0c2lkZVJpZ2h0IHsKICBmaWxsOiBibGFjazsKICB0ZXh0LWFuY2hvcjogc3RhcnQ7CiAgZm9udC1zaXplOiAxMXB4OyB9CgojZHdmaXRrZHZ0NGsgLnRhc2tUZXh0T3V0c2lkZUxlZnQgewogIGZpbGw6IGJsYWNrOwogIHRleHQtYW5jaG9yOiBlbmQ7CiAgZm9udC1zaXplOiAxMXB4OyB9CgoKI2R3Zml0a2R2dDRrIC50YXNrVGV4dDAsCiNkd2ZpdGtkdnQ0ayAudGFza1RleHQxLAojZHdmaXRrZHZ0NGsgLnRhc2tUZXh0MiwKI2R3Zml0a2R2dDRrIC50YXNrVGV4dDMgewogIGZpbGw6IHdoaXRlOyB9CgojZHdmaXRrZHZ0NGsgLnRhc2swLAojZHdmaXRrZHZ0NGsgLnRhc2sxLAojZHdmaXRrZHZ0NGsgLnRhc2syLAojZHdmaXRrZHZ0NGsgLnRhc2szIHsKICBmaWxsOiAjOGE5MGRkOwogIHN0cm9rZTogIzUzNGZiYzsgfQoKI2R3Zml0a2R2dDRrIC50YXNrVGV4dE91dHNpZGUwLAojZHdmaXRrZHZ0NGsgLnRhc2tUZXh0T3V0c2lkZTIgewogIGZpbGw6IGJsYWNrOyB9CgojZHdmaXRrZHZ0NGsgLnRhc2tUZXh0T3V0c2lkZTEsCiNkd2ZpdGtkdnQ0ayAudGFza1RleHRPdXRzaWRlMyB7CiAgZmlsbDogYmxhY2s7IH0KCgojZHdmaXRrZHZ0NGsgLmFjdGl2ZTAsCiNkd2ZpdGtkdnQ0ayAuYWN0aXZlMSwKI2R3Zml0a2R2dDRrIC5hY3RpdmUyLAojZHdmaXRrZHZ0NGsgLmFjdGl2ZTMgewogIGZpbGw6ICNiZmM3ZmY7CiAgc3Ryb2tlOiAjNTM0ZmJjOyB9CgojZHdmaXRrZHZ0NGsgLmFjdGl2ZVRleHQwLAojZHdmaXRrZHZ0NGsgLmFjdGl2ZVRleHQxLAojZHdmaXRrZHZ0NGsgLmFjdGl2ZVRleHQyLAojZHdmaXRrZHZ0NGsgLmFjdGl2ZVRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgoKI2R3Zml0a2R2dDRrIC5kb25lMCwKI2R3Zml0a2R2dDRrIC5kb25lMSwKI2R3Zml0a2R2dDRrIC5kb25lMiwKI2R3Zml0a2R2dDRrIC5kb25lMyB7CiAgc3Ryb2tlOiBncmV5OwogIGZpbGw6IGxpZ2h0Z3JleTsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkd2ZpdGtkdnQ0ayAuZG9uZVRleHQwLAojZHdmaXRrZHZ0NGsgLmRvbmVUZXh0MSwKI2R3Zml0a2R2dDRrIC5kb25lVGV4dDIsCiNkd2ZpdGtkdnQ0ayAuZG9uZVRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgoKI2R3Zml0a2R2dDRrIC5jcml0MCwKI2R3Zml0a2R2dDRrIC5jcml0MSwKI2R3Zml0a2R2dDRrIC5jcml0MiwKI2R3Zml0a2R2dDRrIC5jcml0MyB7CiAgc3Ryb2tlOiAjZmY4ODg4OwogIGZpbGw6IHJlZDsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNkd2ZpdGtkdnQ0ayAuYWN0aXZlQ3JpdDAsCiNkd2ZpdGtkdnQ0ayAuYWN0aXZlQ3JpdDEsCiNkd2ZpdGtkdnQ0ayAuYWN0aXZlQ3JpdDIsCiNkd2ZpdGtkdnQ0ayAuYWN0aXZlQ3JpdDMgewogIHN0cm9rZTogI2ZmODg4ODsKICBmaWxsOiAjYmZjN2ZmOwogIHN0cm9rZS13aWR0aDogMjsgfQoKI2R3Zml0a2R2dDRrIC5kb25lQ3JpdDAsCiNkd2ZpdGtkdnQ0ayAuZG9uZUNyaXQxLAojZHdmaXRrZHZ0NGsgLmRvbmVDcml0MiwKI2R3Zml0a2R2dDRrIC5kb25lQ3JpdDMgewogIHN0cm9rZTogI2ZmODg4ODsKICBmaWxsOiBsaWdodGdyZXk7CiAgc3Ryb2tlLXdpZHRoOiAyOwogIGN1cnNvcjogcG9pbnRlcjsKICBzaGFwZS1yZW5kZXJpbmc6IGNyaXNwRWRnZXM7IH0KCiNkd2ZpdGtkdnQ0ayAuZG9uZUNyaXRUZXh0MCwKI2R3Zml0a2R2dDRrIC5kb25lQ3JpdFRleHQxLAojZHdmaXRrZHZ0NGsgLmRvbmVDcml0VGV4dDIsCiNkd2ZpdGtkdnQ0ayAuZG9uZUNyaXRUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKI2R3Zml0a2R2dDRrIC5hY3RpdmVDcml0VGV4dDAsCiNkd2ZpdGtkdnQ0ayAuYWN0aXZlQ3JpdFRleHQxLAojZHdmaXRrZHZ0NGsgLmFjdGl2ZUNyaXRUZXh0MiwKI2R3Zml0a2R2dDRrIC5hY3RpdmVDcml0VGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCiNkd2ZpdGtkdnQ0ayAudGl0bGVUZXh0IHsKICB0ZXh0LWFuY2hvcjogbWlkZGxlOwogIGZvbnQtc2l6ZTogMThweDsKICBmaWxsOiBibGFjazsgfQoKI2R3Zml0a2R2dDRrIGcuY2xhc3NHcm91cCB0ZXh0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogbm9uZTsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGZvbnQtc2l6ZTogMTBweDsgfQoKI2R3Zml0a2R2dDRrIGcuY2xhc3NHcm91cCByZWN0IHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsgfQoKI2R3Zml0a2R2dDRrIGcuY2xhc3NHcm91cCBsaW5lIHsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZHdmaXRrZHZ0NGsgLmNsYXNzTGFiZWwgLmJveCB7CiAgc3Ryb2tlOiBub25lOwogIHN0cm9rZS13aWR0aDogMDsKICBmaWxsOiAjRUNFQ0ZGOwogIG9wYWNpdHk6IDAuNTsgfQoKI2R3Zml0a2R2dDRrIC5jbGFzc0xhYmVsIC5sYWJlbCB7CiAgZmlsbDogIzkzNzBEQjsKICBmb250LXNpemU6IDEwcHg7IH0KCiNkd2ZpdGtkdnQ0ayAucmVsYXRpb24gewogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7CiAgZmlsbDogbm9uZTsgfQoKI2R3Zml0a2R2dDRrICNjb21wb3NpdGlvblN0YXJ0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkd2ZpdGtkdnQ0ayAjY29tcG9zaXRpb25FbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R3Zml0a2R2dDRrICNhZ2dyZWdhdGlvblN0YXJ0IHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkd2ZpdGtkdnQ0ayAjYWdncmVnYXRpb25FbmQgewogIGZpbGw6ICNFQ0VDRkY7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R3Zml0a2R2dDRrICNkZXBlbmRlbmN5U3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R3Zml0a2R2dDRrICNkZXBlbmRlbmN5RW5kIHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNkd2ZpdGtkdnQ0ayAjZXh0ZW5zaW9uU3RhcnQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R3Zml0a2R2dDRrICNleHRlbnNpb25FbmQgewogIGZpbGw6ICM5MzcwREI7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2R3Zml0a2R2dDRrIC5jb21taXQtaWQsCiNkd2ZpdGtkdnQ0ayAuY29tbWl0LW1zZywKI2R3Zml0a2R2dDRrIC5icmFuY2gtbGFiZWwgewogIGZpbGw6IGxpZ2h0Z3JleTsKICBjb2xvcjogbGlnaHRncmV5OyB9CgoKCiNkd2ZpdGtkdnQ0ayAubGFiZWx7CiAgY29sb3I6IzE4QjE0RTsKfQojZHdmaXRrZHZ0NGsgLnRlLW1kLWNvbnRhaW5lci0tZGFyayAubm9kZSByZWN0IHsKICBmaWxsOiByZWQ7Cn0KCiNkd2ZpdGtkdnQ0ayAubm9kZSByZWN0LAojZHdmaXRrZHZ0NGsgLm5vZGUgY2lyY2xlLAojZHdmaXRrZHZ0NGsgLm5vZGUgZWxsaXBzZSwKI2R3Zml0a2R2dDRrIC5ub2RlIHBvbHlnb24gewogIGZpbGw6ICNGOUZGRkI7OwogIHN0cm9rZTogIzJEQkQ2MDsKICBzdHJva2Utd2lkdGg6IDEuNXB4Owp9CiNkd2ZpdGtkdnQ0ayAuYXJyb3doZWFkUGF0aHsKICBmaWxsOiAjMkRCRDYwOwp9CiNkd2ZpdGtkdnQ0ayAuZWRnZVBhdGggLnBhdGggewogIHN0cm9rZTogIzJEQkQ2MDsKICBzdHJva2Utd2lkdGg6IDFweDsKfQojZHdmaXRrZHZ0NGsgLmVkZ2VMYWJlbCB7CiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjsKfQojZHdmaXRrZHZ0NGsgLmNsdXN0ZXIgcmVjdCB7CiAgZmlsbDogI0Y5RkZGQiAhaW1wb3J0YW50OwogIHN0cm9rZTogIzJEQkQ2MCAhaW1wb3J0YW50OwogIHN0cm9rZS13aWR0aDogMXB4ICFpbXBvcnRhbnQ7Cn0KCiNkd2ZpdGtkdnQ0ayAuY2x1c3RlciB0ZXh0IHsKICBmaWxsOiAjRjlGRkZCOwp9CgojZHdmaXRrZHZ0NGsgZGl2Lm1lcm1haWRUb29sdGlwIHsKICBiYWNrZ3JvdW5kOiAjRjlGRkZCOwogIGJvcmRlcjogMXB4IHNvbGlkICMyREJENjA7Cn0KCgojZHdmaXRrZHZ0NGsgLmFjdG9yIHsKICBzdHJva2U6ICMyREJENjA7CiAgZmlsbDogI0Y5RkZGQjsKfQoKI2R3Zml0a2R2dDRrIHRleHQuYWN0b3IgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiBub25lOwp9CgojZHdmaXRrZHZ0NGsgLmFjdG9yLWxpbmUgewogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2R3Zml0a2R2dDRrIC5tZXNzYWdlTGluZTAgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIG1hcmtlci1lbmQ6ICd1cmwoI2Fycm93aGVhZCknOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2R3Zml0a2R2dDRrIC5tZXNzYWdlTGluZTEgewogIHN0cm9rZS13aWR0aDogMS41OwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2R3Zml0a2R2dDRrICNhcnJvd2hlYWQgewogIGZpbGw6ICMyREJENjA7Cn0KCiNkd2ZpdGtkdnQ0ayAjY3Jvc3NoZWFkIHBhdGggewogIGZpbGw6ICMyREJENjAgIWltcG9ydGFudDsKICBzdHJva2U6ICMyREJENjAgIWltcG9ydGFudDsKfQoKI2R3Zml0a2R2dDRrIC5tZXNzYWdlVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6IG5vbmU7Cn0KCiNkd2ZpdGtkdnQ0ayAubGFiZWxCb3ggewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZHdmaXRrZHZ0NGsgLmxhYmVsVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNkd2ZpdGtkdnQ0ayAubG9vcFRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHdmaXRrZHZ0NGsgLmxvb3BMaW5lIHsKICBzdHJva2Utd2lkdGg6IDI7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgbWFya2VyLWVuZDogJ3VybCgjYXJyb3doZWFkKSc7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZHdmaXRrZHZ0NGsgLm5vdGUgewogIHN0cm9rZTogIzJEQkQ2MDsKICBmaWxsOiAjRjlGRkZCOwp9CgojZHdmaXRrZHZ0NGsgLm5vdGVUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKCiNkd2ZpdGtkdnQ0ayAuc2VjdGlvbnsKICBvcGFjaXR5OjE7Cn0KI2R3Zml0a2R2dDRrIC5zZWN0aW9uMCwjZHdmaXRrZHZ0NGsgIC5zZWN0aW9uMiB7CiAgZmlsbDogI0VDRjdGMDsKfQoKI2R3Zml0a2R2dDRrIC5zZWN0aW9uMSwKI2R3Zml0a2R2dDRrIC5zZWN0aW9uMyB7CiAgZmlsbDogI0ZGRjsKfQojZHdmaXRrZHZ0NGsgLnRhc2tUZXh0MCwKI2R3Zml0a2R2dDRrIC50YXNrVGV4dDEsCiNkd2ZpdGtkdnQ0ayAudGFza1RleHQyLAojZHdmaXRrZHZ0NGsgLnRhc2tUZXh0MyB7CiAgZmlsbDogI2ZmZjsKfQoKI2R3Zml0a2R2dDRrIC50YXNrMCwKI2R3Zml0a2R2dDRrIC50YXNrMSwKI2R3Zml0a2R2dDRrIC50YXNrMiwKI2R3Zml0a2R2dDRrIC50YXNrMyB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMzNTlGNUE7Cn0KPC9zdHlsZT48c3R5bGU+I2R3Zml0a2R2dDRrIHsKICAgIGNvbG9yOiByZ2IoMjQ0LCAyNDQsIDI0NCk7CiAgICBmb250OiBub3JtYWwgbm9ybWFsIG5vcm1hbCBub3JtYWwgMTRweC8yMi4zOTk5OTk2MTg1MzAyNzNweCBtb25vc3BhY2U7CiAgfTwvc3R5bGU+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEyLCAtMTIpIj48ZyBjbGFzcz0ib3V0cHV0Ij48ZyBjbGFzcz0iY2x1c3RlcnMiPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGhzIj48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0xMzYuNTMxMjUsNTYuMjgxMjVMMTM2LjUzMTI1LDgxLjI4MTI1TDEzNi41MzEyNSwxMDYuMjgxMjUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkNTk1NykiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkNTk1NyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTEzNi41MzEyNSwxNDIuNTYyNUwxMzYuNTMxMjUsMTY3LjU2MjVMMTM2LjUzMTI1LDE5Mi41NjI1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDU5NTgpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDU5NTgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0xMzYuNTMxMjUsMjI4Ljg0Mzc1TDEzNi41MzEyNSwyNTMuODQzNzVMMTM2LjUzMTI1LDI3OC44NDM3NSIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ1OTU5KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ1OTU5IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWxzIj48ZyBjbGFzcz0iZWRnZUxhYmVsIiBzdHlsZT0ib3BhY2l0eTogMTsiIHRyYW5zZm9ybT0iIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiBzdHlsZT0ib3BhY2l0eTogMTsiIHRyYW5zZm9ybT0iIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiBzdHlsZT0ib3BhY2l0eTogMTsiIHRyYW5zZm9ybT0iIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGVzIj48ZyBjbGFzcz0ibm9kZSIgc3R5bGU9Im9wYWNpdHk6IDE7IiBpZD0iQSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTM2LjUzMTI1LDM4LjE0MDYyNSkiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTcwLjMxMjUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIxNDAuNjI1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNjAuMzEyNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+c2VsaW51eF9zb2NrZXRfYmluZDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBzdHlsZT0ib3BhY2l0eTogMTsiIGlkPSJCIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMzYuNTMxMjUsMTI0LjQyMTg3NSkiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTEwNC44ODI4MTI1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iMjA5Ljc2NTYyNSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTk0Ljg4MjgxMjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnNvY2tfaGFzX3Blcm0oU09DS0VUX19CSU5EKTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBzdHlsZT0ib3BhY2l0eTogMTsiIGlkPSJDIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMzYuNTMxMjUsMjEwLjcwMzEyNSkiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTExNi41MzEyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjIzMy4wNjI1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTA2LjUzMTI1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5nZXQgbm9kZWNvbiBzaWQgYnkgc2VsX25ldG5vZGVfc2lkPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIHN0eWxlPSJvcGFjaXR5OiAxOyIgaWQ9IkQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEzNi41MzEyNSwyOTYuOTg0Mzc1KSI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItNDkuNTM5MDYyNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9Ijk5LjA3ODEyNSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTM5LjUzOTA2MjUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPmF2X2hhc19wZXJtPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PC9nPjwvZz48L2c+PC9zdmc+
security_node_sid
会从policydb->ocontexts[OCON_NODE]
中搜索policydb中关于该IP地址的nodecon定义,如果找不着,说明此IP相关的nodecon无效(未定义),则会走默认的initial SID。
if (c) {
if (!c->sid[0]) {
rc = sidtab_context_to_sid(sidtab,
&c->context[0],
&c->sid[0]);
if (rc)
goto out;
}
*out_sid = c->sid[0];
} else {
*out_sid = SECINITSID_NODE; // <===== intial SID
}
其他SID
除了initial SID由内核直接加载生成,其他的SID则由对应的打标签流程生成。例如:文件的SID则由setfiles/restorecon工具打入文件系统的扩展属性上,socket则由socket系统调用创建时生成。
以socket bind为例,因为比较简单。当socket bind系统调用被执行时,一个socket object被绑定到一个node上。而此时该node的SID才被写入policydb中。
int sel_netnode_sid(void *addr, u16 family, u32 *sid)
{
struct sel_netnode *node;
rcu_read_lock();
node = sel_netnode_find(addr, family);
if (node != NULL) {
*sid = node->nsec.sid;
rcu_read_unlock();
return 0;
}
rcu_read_unlock();
return sel_netnode_sid_slow(addr, family, sid);
}
sel_netnode_sid_slow
调用security_node_sid
,并最终调用sidtab_context_to_sid
将相关的SID以及对应的context数据结构插入到表中。
PHN2ZyBpZD0iZGtkdGdndWVvN2MiIHdpZHRoPSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXgtd2lkdGg6IDQzMS4xMjVweDsiIHZpZXdCb3g9IjAgMCA0MzEuMTI1IDQ3MC4wNDY4NzUiPjxzdHlsZT4KCgojZGtkdGdndWVvN2MgLmxhYmVsIHsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGNvbG9yOiAjMzMzOyB9CgojZGtkdGdndWVvN2MgLm5vZGUgcmVjdCwKI2RrZHRnZ3VlbzdjIC5ub2RlIGNpcmNsZSwKI2RrZHRnZ3VlbzdjIC5ub2RlIGVsbGlwc2UsCiNka2R0Z2d1ZW83YyAubm9kZSBwb2x5Z29uIHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDFweDsgfQoKI2RrZHRnZ3VlbzdjIC5ub2RlLmNsaWNrYWJsZSB7CiAgY3Vyc29yOiBwb2ludGVyOyB9CgojZGtkdGdndWVvN2MgLmFycm93aGVhZFBhdGggewogIGZpbGw6ICMzMzMzMzM7IH0KCiNka2R0Z2d1ZW83YyAuZWRnZVBhdGggLnBhdGggewogIHN0cm9rZTogIzMzMzMzMzsKICBzdHJva2Utd2lkdGg6IDEuNXB4OyB9CgojZGtkdGdndWVvN2MgLmVkZ2VMYWJlbCB7CiAgYmFja2dyb3VuZC1jb2xvcjogI2U4ZThlODsgfQoKI2RrZHRnZ3VlbzdjIC5jbHVzdGVyIHJlY3QgewogIGZpbGw6ICNmZmZmZGUgIWltcG9ydGFudDsKICBzdHJva2U6ICNhYWFhMzMgIWltcG9ydGFudDsKICBzdHJva2Utd2lkdGg6IDFweCAhaW1wb3J0YW50OyB9CgojZGtkdGdndWVvN2MgLmNsdXN0ZXIgdGV4dCB7CiAgZmlsbDogIzMzMzsgfQoKI2RrZHRnZ3VlbzdjIGRpdi5tZXJtYWlkVG9vbHRpcCB7CiAgcG9zaXRpb246IGFic29sdXRlOwogIHRleHQtYWxpZ246IGNlbnRlcjsKICBtYXgtd2lkdGg6IDIwMHB4OwogIHBhZGRpbmc6IDJweDsKICBmb250LWZhbWlseTogJ3RyZWJ1Y2hldCBtcycsIHZlcmRhbmEsIGFyaWFsOwogIGZvbnQtc2l6ZTogMTJweDsKICBiYWNrZ3JvdW5kOiAjZmZmZmRlOwogIGJvcmRlcjogMXB4IHNvbGlkICNhYWFhMzM7CiAgYm9yZGVyLXJhZGl1czogMnB4OwogIHBvaW50ZXItZXZlbnRzOiBub25lOwogIHotaW5kZXg6IDEwMDsgfQoKI2RrZHRnZ3VlbzdjIC5hY3RvciB7CiAgc3Ryb2tlOiAjQ0NDQ0ZGOwogIGZpbGw6ICNFQ0VDRkY7IH0KCiNka2R0Z2d1ZW83YyB0ZXh0LmFjdG9yIHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7IH0KCiNka2R0Z2d1ZW83YyAuYWN0b3ItbGluZSB7CiAgc3Ryb2tlOiBncmV5OyB9CgojZGtkdGdndWVvN2MgLm1lc3NhZ2VMaW5lMCB7CiAgc3Ryb2tlLXdpZHRoOiAxLjU7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjMzMzOyB9CgojZGtkdGdndWVvN2MgLm1lc3NhZ2VMaW5lMSB7CiAgc3Ryb2tlLXdpZHRoOiAxLjU7CiAgc3Ryb2tlLWRhc2hhcnJheTogJzIgMic7CiAgc3Ryb2tlOiAjMzMzOyB9CgojZGtkdGdndWVvN2MgI2Fycm93aGVhZCB7CiAgZmlsbDogIzMzMzsgfQoKI2RrZHRnZ3VlbzdjICNjcm9zc2hlYWQgcGF0aCB7CiAgZmlsbDogIzMzMyAhaW1wb3J0YW50OwogIHN0cm9rZTogIzMzMyAhaW1wb3J0YW50OyB9CgojZGtkdGdndWVvN2MgLm1lc3NhZ2VUZXh0IHsKICBmaWxsOiAjMzMzOwogIHN0cm9rZTogbm9uZTsgfQoKI2RrZHRnZ3VlbzdjIC5sYWJlbEJveCB7CiAgc3Ryb2tlOiAjQ0NDQ0ZGOwogIGZpbGw6ICNFQ0VDRkY7IH0KCiNka2R0Z2d1ZW83YyAubGFiZWxUZXh0IHsKICBmaWxsOiBibGFjazsKICBzdHJva2U6IG5vbmU7IH0KCiNka2R0Z2d1ZW83YyAubG9vcFRleHQgewogIGZpbGw6IGJsYWNrOwogIHN0cm9rZTogbm9uZTsgfQoKI2RrZHRnZ3VlbzdjIC5sb29wTGluZSB7CiAgc3Ryb2tlLXdpZHRoOiAyOwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIHN0cm9rZTogI0NDQ0NGRjsgfQoKI2RrZHRnZ3VlbzdjIC5ub3RlIHsKICBzdHJva2U6ICNhYWFhMzM7CiAgZmlsbDogI2ZmZjVhZDsgfQoKI2RrZHRnZ3VlbzdjIC5ub3RlVGV4dCB7CiAgZmlsbDogYmxhY2s7CiAgc3Ryb2tlOiBub25lOwogIGZvbnQtZmFtaWx5OiAndHJlYnVjaGV0IG1zJywgdmVyZGFuYSwgYXJpYWw7CiAgZm9udC1zaXplOiAxNHB4OyB9CgojZGtkdGdndWVvN2MgLmFjdGl2YXRpb24wIHsKICBmaWxsOiAjZjRmNGY0OwogIHN0cm9rZTogIzY2NjsgfQoKI2RrZHRnZ3VlbzdjIC5hY3RpdmF0aW9uMSB7CiAgZmlsbDogI2Y0ZjRmNDsKICBzdHJva2U6ICM2NjY7IH0KCiNka2R0Z2d1ZW83YyAuYWN0aXZhdGlvbjIgewogIGZpbGw6ICNmNGY0ZjQ7CiAgc3Ryb2tlOiAjNjY2OyB9CgoKI2RrZHRnZ3VlbzdjIC5zZWN0aW9uIHsKICBzdHJva2U6IG5vbmU7CiAgb3BhY2l0eTogMC4yOyB9CgojZGtkdGdndWVvN2MgLnNlY3Rpb24wIHsKICBmaWxsOiByZ2JhKDEwMiwgMTAyLCAyNTUsIDAuNDkpOyB9CgojZGtkdGdndWVvN2MgLnNlY3Rpb24yIHsKICBmaWxsOiAjZmZmNDAwOyB9CgojZGtkdGdndWVvN2MgLnNlY3Rpb24xLAojZGtkdGdndWVvN2MgLnNlY3Rpb24zIHsKICBmaWxsOiB3aGl0ZTsKICBvcGFjaXR5OiAwLjI7IH0KCiNka2R0Z2d1ZW83YyAuc2VjdGlvblRpdGxlMCB7CiAgZmlsbDogIzMzMzsgfQoKI2RrZHRnZ3VlbzdjIC5zZWN0aW9uVGl0bGUxIHsKICBmaWxsOiAjMzMzOyB9CgojZGtkdGdndWVvN2MgLnNlY3Rpb25UaXRsZTIgewogIGZpbGw6ICMzMzM7IH0KCiNka2R0Z2d1ZW83YyAuc2VjdGlvblRpdGxlMyB7CiAgZmlsbDogIzMzMzsgfQoKI2RrZHRnZ3VlbzdjIC5zZWN0aW9uVGl0bGUgewogIHRleHQtYW5jaG9yOiBzdGFydDsKICBmb250LXNpemU6IDExcHg7CiAgdGV4dC1oZWlnaHQ6IDE0cHg7IH0KCgojZGtkdGdndWVvN2MgLmdyaWQgLnRpY2sgewogIHN0cm9rZTogbGlnaHRncmV5OwogIG9wYWNpdHk6IDAuMzsKICBzaGFwZS1yZW5kZXJpbmc6IGNyaXNwRWRnZXM7IH0KCiNka2R0Z2d1ZW83YyAuZ3JpZCBwYXRoIHsKICBzdHJva2Utd2lkdGg6IDA7IH0KCgojZGtkdGdndWVvN2MgLnRvZGF5IHsKICBmaWxsOiBub25lOwogIHN0cm9rZTogcmVkOwogIHN0cm9rZS13aWR0aDogMnB4OyB9CgoKCiNka2R0Z2d1ZW83YyAudGFzayB7CiAgc3Ryb2tlLXdpZHRoOiAyOyB9CgojZGtkdGdndWVvN2MgLnRhc2tUZXh0IHsKICB0ZXh0LWFuY2hvcjogbWlkZGxlOwogIGZvbnQtc2l6ZTogMTFweDsgfQoKI2RrZHRnZ3VlbzdjIC50YXNrVGV4dE91dHNpZGVSaWdodCB7CiAgZmlsbDogYmxhY2s7CiAgdGV4dC1hbmNob3I6IHN0YXJ0OwogIGZvbnQtc2l6ZTogMTFweDsgfQoKI2RrZHRnZ3VlbzdjIC50YXNrVGV4dE91dHNpZGVMZWZ0IHsKICBmaWxsOiBibGFjazsKICB0ZXh0LWFuY2hvcjogZW5kOwogIGZvbnQtc2l6ZTogMTFweDsgfQoKCiNka2R0Z2d1ZW83YyAudGFza1RleHQwLAojZGtkdGdndWVvN2MgLnRhc2tUZXh0MSwKI2RrZHRnZ3VlbzdjIC50YXNrVGV4dDIsCiNka2R0Z2d1ZW83YyAudGFza1RleHQzIHsKICBmaWxsOiB3aGl0ZTsgfQoKI2RrZHRnZ3VlbzdjIC50YXNrMCwKI2RrZHRnZ3VlbzdjIC50YXNrMSwKI2RrZHRnZ3VlbzdjIC50YXNrMiwKI2RrZHRnZ3VlbzdjIC50YXNrMyB7CiAgZmlsbDogIzhhOTBkZDsKICBzdHJva2U6ICM1MzRmYmM7IH0KCiNka2R0Z2d1ZW83YyAudGFza1RleHRPdXRzaWRlMCwKI2RrZHRnZ3VlbzdjIC50YXNrVGV4dE91dHNpZGUyIHsKICBmaWxsOiBibGFjazsgfQoKI2RrZHRnZ3VlbzdjIC50YXNrVGV4dE91dHNpZGUxLAojZGtkdGdndWVvN2MgLnRhc2tUZXh0T3V0c2lkZTMgewogIGZpbGw6IGJsYWNrOyB9CgoKI2RrZHRnZ3VlbzdjIC5hY3RpdmUwLAojZGtkdGdndWVvN2MgLmFjdGl2ZTEsCiNka2R0Z2d1ZW83YyAuYWN0aXZlMiwKI2RrZHRnZ3VlbzdjIC5hY3RpdmUzIHsKICBmaWxsOiAjYmZjN2ZmOwogIHN0cm9rZTogIzUzNGZiYzsgfQoKI2RrZHRnZ3VlbzdjIC5hY3RpdmVUZXh0MCwKI2RrZHRnZ3VlbzdjIC5hY3RpdmVUZXh0MSwKI2RrZHRnZ3VlbzdjIC5hY3RpdmVUZXh0MiwKI2RrZHRnZ3VlbzdjIC5hY3RpdmVUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKCiNka2R0Z2d1ZW83YyAuZG9uZTAsCiNka2R0Z2d1ZW83YyAuZG9uZTEsCiNka2R0Z2d1ZW83YyAuZG9uZTIsCiNka2R0Z2d1ZW83YyAuZG9uZTMgewogIHN0cm9rZTogZ3JleTsKICBmaWxsOiBsaWdodGdyZXk7CiAgc3Ryb2tlLXdpZHRoOiAyOyB9CgojZGtkdGdndWVvN2MgLmRvbmVUZXh0MCwKI2RrZHRnZ3VlbzdjIC5kb25lVGV4dDEsCiNka2R0Z2d1ZW83YyAuZG9uZVRleHQyLAojZGtkdGdndWVvN2MgLmRvbmVUZXh0MyB7CiAgZmlsbDogYmxhY2sgIWltcG9ydGFudDsgfQoKCiNka2R0Z2d1ZW83YyAuY3JpdDAsCiNka2R0Z2d1ZW83YyAuY3JpdDEsCiNka2R0Z2d1ZW83YyAuY3JpdDIsCiNka2R0Z2d1ZW83YyAuY3JpdDMgewogIHN0cm9rZTogI2ZmODg4ODsKICBmaWxsOiByZWQ7CiAgc3Ryb2tlLXdpZHRoOiAyOyB9CgojZGtkdGdndWVvN2MgLmFjdGl2ZUNyaXQwLAojZGtkdGdndWVvN2MgLmFjdGl2ZUNyaXQxLAojZGtkdGdndWVvN2MgLmFjdGl2ZUNyaXQyLAojZGtkdGdndWVvN2MgLmFjdGl2ZUNyaXQzIHsKICBzdHJva2U6ICNmZjg4ODg7CiAgZmlsbDogI2JmYzdmZjsKICBzdHJva2Utd2lkdGg6IDI7IH0KCiNka2R0Z2d1ZW83YyAuZG9uZUNyaXQwLAojZGtkdGdndWVvN2MgLmRvbmVDcml0MSwKI2RrZHRnZ3VlbzdjIC5kb25lQ3JpdDIsCiNka2R0Z2d1ZW83YyAuZG9uZUNyaXQzIHsKICBzdHJva2U6ICNmZjg4ODg7CiAgZmlsbDogbGlnaHRncmV5OwogIHN0cm9rZS13aWR0aDogMjsKICBjdXJzb3I6IHBvaW50ZXI7CiAgc2hhcGUtcmVuZGVyaW5nOiBjcmlzcEVkZ2VzOyB9CgojZGtkdGdndWVvN2MgLmRvbmVDcml0VGV4dDAsCiNka2R0Z2d1ZW83YyAuZG9uZUNyaXRUZXh0MSwKI2RrZHRnZ3VlbzdjIC5kb25lQ3JpdFRleHQyLAojZGtkdGdndWVvN2MgLmRvbmVDcml0VGV4dDMgewogIGZpbGw6IGJsYWNrICFpbXBvcnRhbnQ7IH0KCiNka2R0Z2d1ZW83YyAuYWN0aXZlQ3JpdFRleHQwLAojZGtkdGdndWVvN2MgLmFjdGl2ZUNyaXRUZXh0MSwKI2RrZHRnZ3VlbzdjIC5hY3RpdmVDcml0VGV4dDIsCiNka2R0Z2d1ZW83YyAuYWN0aXZlQ3JpdFRleHQzIHsKICBmaWxsOiBibGFjayAhaW1wb3J0YW50OyB9CgojZGtkdGdndWVvN2MgLnRpdGxlVGV4dCB7CiAgdGV4dC1hbmNob3I6IG1pZGRsZTsKICBmb250LXNpemU6IDE4cHg7CiAgZmlsbDogYmxhY2s7IH0KCiNka2R0Z2d1ZW83YyBnLmNsYXNzR3JvdXAgdGV4dCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6IG5vbmU7CiAgZm9udC1mYW1pbHk6ICd0cmVidWNoZXQgbXMnLCB2ZXJkYW5hLCBhcmlhbDsKICBmb250LXNpemU6IDEwcHg7IH0KCiNka2R0Z2d1ZW83YyBnLmNsYXNzR3JvdXAgcmVjdCB7CiAgZmlsbDogI0VDRUNGRjsKICBzdHJva2U6ICM5MzcwREI7IH0KCiNka2R0Z2d1ZW83YyBnLmNsYXNzR3JvdXAgbGluZSB7CiAgc3Ryb2tlOiAjOTM3MERCOwogIHN0cm9rZS13aWR0aDogMTsgfQoKI2RrZHRnZ3VlbzdjIC5jbGFzc0xhYmVsIC5ib3ggewogIHN0cm9rZTogbm9uZTsKICBzdHJva2Utd2lkdGg6IDA7CiAgZmlsbDogI0VDRUNGRjsKICBvcGFjaXR5OiAwLjU7IH0KCiNka2R0Z2d1ZW83YyAuY2xhc3NMYWJlbCAubGFiZWwgewogIGZpbGw6ICM5MzcwREI7CiAgZm9udC1zaXplOiAxMHB4OyB9CgojZGtkdGdndWVvN2MgLnJlbGF0aW9uIHsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOwogIGZpbGw6IG5vbmU7IH0KCiNka2R0Z2d1ZW83YyAjY29tcG9zaXRpb25TdGFydCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZGtkdGdndWVvN2MgI2NvbXBvc2l0aW9uRW5kIHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNka2R0Z2d1ZW83YyAjYWdncmVnYXRpb25TdGFydCB7CiAgZmlsbDogI0VDRUNGRjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZGtkdGdndWVvN2MgI2FnZ3JlZ2F0aW9uRW5kIHsKICBmaWxsOiAjRUNFQ0ZGOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNka2R0Z2d1ZW83YyAjZGVwZW5kZW5jeVN0YXJ0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNka2R0Z2d1ZW83YyAjZGVwZW5kZW5jeUVuZCB7CiAgZmlsbDogIzkzNzBEQjsKICBzdHJva2U6ICM5MzcwREI7CiAgc3Ryb2tlLXdpZHRoOiAxOyB9CgojZGtkdGdndWVvN2MgI2V4dGVuc2lvblN0YXJ0IHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNka2R0Z2d1ZW83YyAjZXh0ZW5zaW9uRW5kIHsKICBmaWxsOiAjOTM3MERCOwogIHN0cm9rZTogIzkzNzBEQjsKICBzdHJva2Utd2lkdGg6IDE7IH0KCiNka2R0Z2d1ZW83YyAuY29tbWl0LWlkLAojZGtkdGdndWVvN2MgLmNvbW1pdC1tc2csCiNka2R0Z2d1ZW83YyAuYnJhbmNoLWxhYmVsIHsKICBmaWxsOiBsaWdodGdyZXk7CiAgY29sb3I6IGxpZ2h0Z3JleTsgfQoKCgojZGtkdGdndWVvN2MgLmxhYmVsewogIGNvbG9yOiMxOEIxNEU7Cn0KI2RrZHRnZ3VlbzdjIC50ZS1tZC1jb250YWluZXItLWRhcmsgLm5vZGUgcmVjdCB7CiAgZmlsbDogcmVkOwp9CgojZGtkdGdndWVvN2MgLm5vZGUgcmVjdCwKI2RrZHRnZ3VlbzdjIC5ub2RlIGNpcmNsZSwKI2RrZHRnZ3VlbzdjIC5ub2RlIGVsbGlwc2UsCiNka2R0Z2d1ZW83YyAubm9kZSBwb2x5Z29uIHsKICBmaWxsOiAjRjlGRkZCOzsKICBzdHJva2U6ICMyREJENjA7CiAgc3Ryb2tlLXdpZHRoOiAxLjVweDsKfQojZGtkdGdndWVvN2MgLmFycm93aGVhZFBhdGh7CiAgZmlsbDogIzJEQkQ2MDsKfQojZGtkdGdndWVvN2MgLmVkZ2VQYXRoIC5wYXRoIHsKICBzdHJva2U6ICMyREJENjA7CiAgc3Ryb2tlLXdpZHRoOiAxcHg7Cn0KI2RrZHRnZ3VlbzdjIC5lZGdlTGFiZWwgewogIGJhY2tncm91bmQtY29sb3I6ICNmZmY7Cn0KI2RrZHRnZ3VlbzdjIC5jbHVzdGVyIHJlY3QgewogIGZpbGw6ICNGOUZGRkIgIWltcG9ydGFudDsKICBzdHJva2U6ICMyREJENjAgIWltcG9ydGFudDsKICBzdHJva2Utd2lkdGg6IDFweCAhaW1wb3J0YW50Owp9CgojZGtkdGdndWVvN2MgLmNsdXN0ZXIgdGV4dCB7CiAgZmlsbDogI0Y5RkZGQjsKfQoKI2RrZHRnZ3VlbzdjIGRpdi5tZXJtYWlkVG9vbHRpcCB7CiAgYmFja2dyb3VuZDogI0Y5RkZGQjsKICBib3JkZXI6IDFweCBzb2xpZCAjMkRCRDYwOwp9CgoKI2RrZHRnZ3VlbzdjIC5hY3RvciB7CiAgc3Ryb2tlOiAjMkRCRDYwOwogIGZpbGw6ICNGOUZGRkI7Cn0KCiNka2R0Z2d1ZW83YyB0ZXh0LmFjdG9yIHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogbm9uZTsKfQoKI2RrZHRnZ3VlbzdjIC5hY3Rvci1saW5lIHsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNka2R0Z2d1ZW83YyAubWVzc2FnZUxpbmUwIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBtYXJrZXItZW5kOiAndXJsKCNhcnJvd2hlYWQpJzsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNka2R0Z2d1ZW83YyAubWVzc2FnZUxpbmUxIHsKICBzdHJva2Utd2lkdGg6IDEuNTsKICBzdHJva2UtZGFzaGFycmF5OiAnMiAyJzsKICBzdHJva2U6ICMyREJENjA7Cn0KCiNka2R0Z2d1ZW83YyAjYXJyb3doZWFkIHsKICBmaWxsOiAjMkRCRDYwOwp9CgojZGtkdGdndWVvN2MgI2Nyb3NzaGVhZCBwYXRoIHsKICBmaWxsOiAjMkRCRDYwICFpbXBvcnRhbnQ7CiAgc3Ryb2tlOiAjMkRCRDYwICFpbXBvcnRhbnQ7Cn0KCiNka2R0Z2d1ZW83YyAubWVzc2FnZVRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiBub25lOwp9CgojZGtkdGdndWVvN2MgLmxhYmVsQm94IHsKICBzdHJva2U6ICMyREJENjA7CiAgZmlsbDogI0Y5RkZGQjsKfQoKI2RrZHRnZ3VlbzdjIC5sYWJlbFRleHQgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMkRCRDYwOwp9CgojZGtkdGdndWVvN2MgLmxvb3BUZXh0IHsKICBmaWxsOiAjMkRCRDYwOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RrZHRnZ3VlbzdjIC5sb29wTGluZSB7CiAgc3Ryb2tlLXdpZHRoOiAyOwogIHN0cm9rZS1kYXNoYXJyYXk6ICcyIDInOwogIG1hcmtlci1lbmQ6ICd1cmwoI2Fycm93aGVhZCknOwogIHN0cm9rZTogIzJEQkQ2MDsKfQoKI2RrZHRnZ3VlbzdjIC5ub3RlIHsKICBzdHJva2U6ICMyREJENjA7CiAgZmlsbDogI0Y5RkZGQjsKfQoKI2RrZHRnZ3VlbzdjIC5ub3RlVGV4dCB7CiAgZmlsbDogIzJEQkQ2MDsKICBzdHJva2U6ICMyREJENjA7Cn0KCgojZGtkdGdndWVvN2MgLnNlY3Rpb257CiAgb3BhY2l0eToxOwp9CiNka2R0Z2d1ZW83YyAuc2VjdGlvbjAsI2RrZHRnZ3VlbzdjICAuc2VjdGlvbjIgewogIGZpbGw6ICNFQ0Y3RjA7Cn0KCiNka2R0Z2d1ZW83YyAuc2VjdGlvbjEsCiNka2R0Z2d1ZW83YyAuc2VjdGlvbjMgewogIGZpbGw6ICNGRkY7Cn0KI2RrZHRnZ3VlbzdjIC50YXNrVGV4dDAsCiNka2R0Z2d1ZW83YyAudGFza1RleHQxLAojZGtkdGdndWVvN2MgLnRhc2tUZXh0MiwKI2RrZHRnZ3VlbzdjIC50YXNrVGV4dDMgewogIGZpbGw6ICNmZmY7Cn0KCiNka2R0Z2d1ZW83YyAudGFzazAsCiNka2R0Z2d1ZW83YyAudGFzazEsCiNka2R0Z2d1ZW83YyAudGFzazIsCiNka2R0Z2d1ZW83YyAudGFzazMgewogIGZpbGw6ICMyREJENjA7CiAgc3Ryb2tlOiAjMzU5RjVBOwp9Cjwvc3R5bGU+PHN0eWxlPiNka2R0Z2d1ZW83YyB7CiAgICBjb2xvcjogcmdiKDI0NCwgMjQ0LCAyNDQpOwogICAgZm9udDogbm9ybWFsIG5vcm1hbCBub3JtYWwgbm9ybWFsIDE0cHgvMjIuMzk5OTk5NjE4NTMwMjczcHggbW9ub3NwYWNlOwogIH08L3N0eWxlPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMiwgLTEyKSI+PGcgY2xhc3M9Im91dHB1dCI+PGcgY2xhc3M9ImNsdXN0ZXJzIj48L2c+PGcgY2xhc3M9ImVkZ2VQYXRocyI+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMjYwLjE5NTMxMjUsNTYuMjgxMjVMMjYwLjE5NTMxMjUsODEuMjgxMjVMMjYwLjE5NTMxMjUsMTA2LjI4MTI1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDU5ODgpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDU5ODgiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0yNTUuODY3NDMwMzAxNjQ1MzMsMTQyLjU2MjVMMjQ3Ljk2MDkzNzUsMTc1LjcwMzEyNUwyNTUuMTA0OTA2NjQ0NDYwMDIsMjE0LjkzNDE1NTg1NTUzOTk4IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDU5ODkpIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDU5ODkiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0yNjYuMjg1NzE4MzU1NTQsMjE0LjkzNDE1NTg1NTUzOTk4TDI3Mi40Mjk2ODc1LDE3NS43MDMxMjVMMjY0LjUyMzE5NDY5ODM1NDY0LDE0Mi41NjI1IiBtYXJrZXItZW5kPSJ1cmwoI2Fycm93aGVhZDU5OTApIiBzdHlsZT0ic3Ryb2tlOiAjMzMzOyBzdHJva2Utd2lkdGg6IDEuNXB4O2ZpbGw6bm9uZSI+PC9wYXRoPjxkZWZzPjxtYXJrZXIgaWQ9ImFycm93aGVhZDU5OTAiIHZpZXdCb3g9IjAgMCAxMCAxMCIgcmVmWD0iOSIgcmVmWT0iNSIgbWFya2VyVW5pdHM9InN0cm9rZVdpZHRoIiBtYXJrZXJXaWR0aD0iOCIgbWFya2VySGVpZ2h0PSI2IiBvcmllbnQ9ImF1dG8iPjxwYXRoIGQ9Ik0gMCAwIEwgMTAgNSBMIDAgMTAgeiIgY2xhc3M9ImFycm93aGVhZFBhdGgiIHN0eWxlPSJzdHJva2Utd2lkdGg6IDFweDsgc3Ryb2tlLWRhc2hhcnJheTogMXB4LCAwcHg7Ij48L3BhdGg+PC9tYXJrZXI+PC9kZWZzPjwvZz48ZyBjbGFzcz0iZWRnZVBhdGgiIHN0eWxlPSJvcGFjaXR5OiAxOyI+PHBhdGggY2xhc3M9InBhdGgiIGQ9Ik0yMzcuMDMwMzYxNDgzODgzNzIsMjYyLjAzODE3Mzk4Mzg4MzdMMTQzLjkxNDA2MjUsMzE4LjM0Mzc1TDE0My45MTQwNjI1LDM1MS40ODQzNzUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkNTk5MSkiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkNTk5MSIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTE0My45MTQwNjI1LDM4Ny43NjU2MjVMMTQzLjkxNDA2MjUsNDEyLjc2NTYyNUwyMzguOTQ1MzEyNSw0NDguMDIyNDQ4NjAyNTI2MiIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ1OTkyKSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ1OTkyIiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PGcgY2xhc3M9ImVkZ2VQYXRoIiBzdHlsZT0ib3BhY2l0eTogMTsiPjxwYXRoIGNsYXNzPSJwYXRoIiBkPSJNMjg0LjM2MDI2MzUxNjExNjMsMjYyLjAzODE3Mzk4Mzg4MzdMMzc2LjQ3NjU2MjUsMzE4LjM0Mzc1TDM3Ni40NzY1NjI1LDM1MS40ODQzNzUiIG1hcmtlci1lbmQ9InVybCgjYXJyb3doZWFkNTk5MykiIHN0eWxlPSJzdHJva2U6ICMzMzM7IHN0cm9rZS13aWR0aDogMS41cHg7ZmlsbDpub25lIj48L3BhdGg+PGRlZnM+PG1hcmtlciBpZD0iYXJyb3doZWFkNTk5MyIgdmlld0JveD0iMCAwIDEwIDEwIiByZWZYPSI5IiByZWZZPSI1IiBtYXJrZXJVbml0cz0ic3Ryb2tlV2lkdGgiIG1hcmtlcldpZHRoPSI4IiBtYXJrZXJIZWlnaHQ9IjYiIG9yaWVudD0iYXV0byI+PHBhdGggZD0iTSAwIDAgTCAxMCA1IEwgMCAxMCB6IiBjbGFzcz0iYXJyb3doZWFkUGF0aCIgc3R5bGU9InN0cm9rZS13aWR0aDogMXB4OyBzdHJva2UtZGFzaGFycmF5OiAxcHgsIDBweDsiPjwvcGF0aD48L21hcmtlcj48L2RlZnM+PC9nPjxnIGNsYXNzPSJlZGdlUGF0aCIgc3R5bGU9Im9wYWNpdHk6IDE7Ij48cGF0aCBjbGFzcz0icGF0aCIgZD0iTTM3Ni40NzY1NjI1LDM4Ny43NjU2MjVMMzc2LjQ3NjU2MjUsNDEyLjc2NTYyNUwyODEuNDQ1MzEyNSw0NDguMDIyNDQ4NjAyNTI2MiIgbWFya2VyLWVuZD0idXJsKCNhcnJvd2hlYWQ1OTk0KSIgc3R5bGU9InN0cm9rZTogIzMzMzsgc3Ryb2tlLXdpZHRoOiAxLjVweDtmaWxsOm5vbmUiPjwvcGF0aD48ZGVmcz48bWFya2VyIGlkPSJhcnJvd2hlYWQ1OTk0IiB2aWV3Qm94PSIwIDAgMTAgMTAiIHJlZlg9IjkiIHJlZlk9IjUiIG1hcmtlclVuaXRzPSJzdHJva2VXaWR0aCIgbWFya2VyV2lkdGg9IjgiIG1hcmtlckhlaWdodD0iNiIgb3JpZW50PSJhdXRvIj48cGF0aCBkPSJNIDAgMCBMIDEwIDUgTCAwIDEwIHoiIGNsYXNzPSJhcnJvd2hlYWRQYXRoIiBzdHlsZT0ic3Ryb2tlLXdpZHRoOiAxcHg7IHN0cm9rZS1kYXNoYXJyYXk6IDFweCwgMHB4OyI+PC9wYXRoPjwvbWFya2VyPjwvZGVmcz48L2c+PC9nPjxnIGNsYXNzPSJlZGdlTGFiZWxzIj48ZyBjbGFzcz0iZWRnZUxhYmVsIiBzdHlsZT0ib3BhY2l0eTogMTsiIHRyYW5zZm9ybT0iIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiBzdHlsZT0ib3BhY2l0eTogMTsiIHRyYW5zZm9ybT0iIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiBzdHlsZT0ib3BhY2l0eTogMTsiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI3Mi40Mjk2ODc1LDE3NS43MDMxMjUpIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNC4yMDMxMjUsLTguMDA3ODEyNSkiIGNsYXNzPSJsYWJlbCI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB3aWR0aD0iOC45Mzc1IiBoZWlnaHQ9IjE2LjI4MTI1IiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5OPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiBzdHlsZT0ib3BhY2l0eTogMTsiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE0My45MTQwNjI1LDMxOC4zNDM3NSkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00LjIwMzEyNSwtOC4wMDc4MTI1KSIgY2xhc3M9ImxhYmVsIj48cmVjdCByeD0iMCIgcnk9IjAiIHdpZHRoPSI4IiBoZWlnaHQ9IjE2LjI4MTI1IiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5ZPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiBzdHlsZT0ib3BhY2l0eTogMTsiIHRyYW5zZm9ybT0iIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiBzdHlsZT0ib3BhY2l0eTogMTsiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM3Ni40NzY1NjI1LDMxOC4zNDM3NSkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00MC42NjQwNjI1LC04LjAwNzgxMjUpIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjYyLjY1NjI1IiBoZWlnaHQ9IjE2LjI4MTI1IiBzdHlsZT0iZmlsbDojZThlOGU4OyI+PC9yZWN0Pjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5OZXZlciBmaW5kPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48ZyBjbGFzcz0iZWRnZUxhYmVsIiBzdHlsZT0ib3BhY2l0eTogMTsiIHRyYW5zZm9ybT0iIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIiBjbGFzcz0ibGFiZWwiPjxyZWN0IHJ4PSIwIiByeT0iMCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgc3R5bGU9ImZpbGw6I2U4ZThlODsiPjwvcmVjdD48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+PC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGVzIj48ZyBjbGFzcz0ibm9kZSIgc3R5bGU9Im9wYWNpdHk6IDE7IiBpZD0iQSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjYwLjE5NTMxMjUsMzguMTQwNjI1KSI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItNjMuODU5Mzc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iMTI3LjcxODc1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNTMuODU5Mzc1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5zZWN1cml0eV9ub2RlX3NpZDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBzdHlsZT0ib3BhY2l0eTogMTsiIGlkPSJCIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNjAuMTk1MzEyNSwxMjQuNDIxODc1KSI+PHJlY3Qgcng9IjAiIHJ5PSIwIiB4PSItMTM0LjM2NzE4NzUiIHk9Ii0xOC4xNDA2MjUiIHdpZHRoPSIyNjguNzM0Mzc1IiBoZWlnaHQ9IjM2LjI4MTI1Ij48L3JlY3Q+PGcgY2xhc3M9ImxhYmVsIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDApIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTI0LjM2NzE4NzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnNlYXJjaCBwb2xpY3lkYi0mZ3Q7b2NvbnRleHRzW09DT05fTk9ERV08L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgc3R5bGU9Im9wYWNpdHk6IDE7IiBpZD0iQyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjYwLjE5NTMxMjUsMjQ3LjAyMzQzNzUpIj48cG9seWdvbiBwb2ludHM9IjM4LjE3OTY4NzUsMCA3Ni4zNTkzNzUsLTM4LjE3OTY4NzUgMzguMTc5Njg3NSwtNzYuMzU5Mzc1IDAsLTM4LjE3OTY4NzUiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTM4LjE3OTY4NzUsMzguMTc5Njg3NSkiPjwvcG9seWdvbj48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNC4yODEyNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+ZmluZD88L3RzcGFuPjwvdGV4dD48L2c+PC9nPjwvZz48ZyBjbGFzcz0ibm9kZSIgc3R5bGU9Im9wYWNpdHk6IDE7IiBpZD0iRCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTQzLjkxNDA2MjUsMzY5LjYyNSkiPjxyZWN0IHJ4PSIwIiByeT0iMCIgeD0iLTEyMy45MTQwNjI1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iMjQ3LjgyODEyNSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTExMy45MTQwNjI1LC04LjE0MDYyNSkiPjx0ZXh0Pjx0c3BhbiB4bWw6c3BhY2U9InByZXNlcnZlIiBkeT0iMWVtIiB4PSIxIj5zaWR0YWJfY29udGV4dF90b19zaWQoY29udGV4dO+8jCZhbXA7c2lkKTwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjxnIGNsYXNzPSJub2RlIiBzdHlsZT0ib3BhY2l0eTogMTsiIGlkPSJFIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNjAuMTk1MzEyNSw0NTUuOTA2MjUpIj48cmVjdCByeD0iNSIgcnk9IjUiIHg9Ii0yMS4yNSIgeT0iLTE4LjE0MDYyNSIgd2lkdGg9IjQyLjUiIGhlaWdodD0iMzYuMjgxMjUiPjwvcmVjdD48ZyBjbGFzcz0ibGFiZWwiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMS4yNSwtOC4xNDA2MjUpIj48dGV4dD48dHNwYW4geG1sOnNwYWNlPSJwcmVzZXJ2ZSIgZHk9IjFlbSIgeD0iMSI+ZW5kPC90c3Bhbj48L3RleHQ+PC9nPjwvZz48L2c+PGcgY2xhc3M9Im5vZGUiIHN0eWxlPSJvcGFjaXR5OiAxOyIgaWQ9IkYiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM3Ni40NzY1NjI1LDM2OS42MjUpIj48cmVjdCByeD0iMCIgcnk9IjAiIHg9Ii01OC42NDg0Mzc1IiB5PSItMTguMTQwNjI1IiB3aWR0aD0iMTE3LjI5Njg3NSIgaGVpZ2h0PSIzNi4yODEyNSI+PC9yZWN0PjxnIGNsYXNzPSJsYWJlbCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwwKSI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTQ4LjY0ODQzNzUsLTguMTQwNjI1KSI+PHRleHQ+PHRzcGFuIHhtbDpzcGFjZT0icHJlc2VydmUiIGR5PSIxZW0iIHg9IjEiPnNldCBhbiBpbml0aWFsIFNJRDwvdHNwYW4+PC90ZXh0PjwvZz48L2c+PC9nPjwvZz48L2c+PC9nPjwvc3ZnPg==
security_node_sid
使用传入的IP地址在policydb中匹配查找context,如果找到则进行下一步,匹配或生成SID,找不到,则直接使用initial SID。sidtab_context_to_sid
将context写入sidtab,并获取返回的SID记入policydb中,后续通过context找SID,直接匹配policydb->ocontexts[OCON_NODE];
即可。对于SID本身的生成也很简单,就是一个单向增长的整形数字,在sidtab_context_to_sid
中。
sid = sidtab_search_context(s, context);
if (sid)
goto unlock_out;
...
sid = s->next_sid++;
..
ret = sidtab_insert(s, sid, context);
先尝试在sidtab中查找,如果找不到就加一条记录,并为sid赋值。
总结
SID在整个SELinux子系统中的作用就是提升匹配性能(从安全上下文的字符串匹配,降低到整数匹配),所以在整个SELinux子系统生命周期内,SID总是与安全上下文(context)一一对应的。在一次权限匹配过程中,SID的使用如下:
u32 sid;
struct context {
u32 user;
u32 role;
u32 type;
u32 len; /* length of string in bytes */
struct mls_range range;
char *str; /* string representation if context cannot be mapped. */
};
相关工具
没有一个专门的工具用来转换SID与context。但libselinux提供了相应的接口,参考sidget(3) - Linux man page。
int avc_context_to_sid(security_context_t ctx, security_id_t *sid);
int avc_sid_to_context(security_id_t sid, security_context_t *ctx);
seinfo
- 打印所有initial SID
[ben@localhost ~]$ seinfo --initialsid
Initial SIDs: 27
any_socket
devnull
file
file_labels
fs
icmp_socket
igmp_packet
init
kernel
...
- 打印selinuxfs context
[ben@localhost ~]$ seinfo --genfscon|grep selinux
genfscon selinuxfs / system_u:object_r:security_t:s0
initial_contexts
策略加载后,每个initial SID都有一个对应的context。这些context在各策略模块中定义。这些context在selinuxfs可以查看:
[ben@localhost ~]$ sudo cat /sys/fs/selinux/initial_contexts/kernel
system_u:system_r:kernel_t:s0
参考文献
- Fedora refpolicy
- Frank Mayer, Karl MacMillan, David Caplan, July 27, 2006- “SELinux by Example: Using Security Enhanced Linux”
- SELinux官方教材,"The SELinux Notebook" Volume II, Building The Sample Policy
- SELinux官方教材,"The SELinux Notebook 4th Edition"