fix secilc-fuzzer issues

This commit is contained in:
panxiaohe 2021-12-10 11:52:40 +08:00
parent ecad49765b
commit c17db78b5b
9 changed files with 517 additions and 1 deletions

View File

@ -0,0 +1,75 @@
From 22fb6f477bf10e834ece9eff84438fcaebf7d2ec Mon Sep 17 00:00:00 2001
From: James Carter <jwcart2@gmail.com>
Date: Thu, 8 Apr 2021 13:32:14 -0400
Subject: [PATCH] libsepol/cil: Allow permission expressions when using map
classes
The following policy will cause a segfault:
(class CLASS (PERM))
(class C (P1 P2 P3))
(classorder (CLASS C))
(sid SID)
(sidorder (SID))
(user USER)
(role ROLE)
(type TYPE)
(category CAT)
(categoryorder (CAT))
(sensitivity SENS)
(sensitivityorder (SENS))
(sensitivitycategory SENS (CAT))
(allow TYPE self (CLASS (PERM)))
(roletype ROLE TYPE)
(userrole USER ROLE)
(userlevel USER (SENS))
(userrange USER ((SENS)(SENS (CAT))))
(sidcontext SID (USER ROLE TYPE ((SENS)(SENS))))
(classmap CM (PM1 PM2 PM3))
(classmapping CM PM1 (C (P1)))
(classmapping CM PM2 (C (P2)))
(classmapping CM PM3 (C (P3)))
(allow TYPE self (CM (and (all) (not PM2))))
The problem is that, while permission expressions are allowed for
normal classes, map classes are expected to only have permission
lists and no check is done to verify that only a permission list
is being used.
When the above policy is parsed, the "and" and "all" are seen as
expression operators, but when the map permissions are converted to
normal class and permissions, the permission expression is assumed
to be a list of datums and since the operators are not datums a
segfault is the result.
There is no reason to limit map classes to only using a list of
permissions and, in fact, it would be better to be able to use them
in the same way normal classes are used.
Allow permissions expressions to be used for map classes by first
evaluating the permission expression and then converting the
resulting list to normal classes and permissions.
Signed-off-by: James Carter <jwcart2@gmail.com>
---
libsepol/cil/src/cil_post.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
index fd4758d..05842b6 100644
--- a/libsepol/cil/src/cil_post.c
+++ b/libsepol/cil/src/cil_post.c
@@ -2137,6 +2137,10 @@ static int __evaluate_classperms_list(struct cil_list *classperms, struct cil_db
}
} else { /* MAP */
struct cil_list_item *i = NULL;
+ rc = __evaluate_classperms(cp, db);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
cil_list_for_each(i, cp->perms) {
struct cil_perm *cmp = i->data;
rc = __evaluate_classperms_list(cmp->classperms, db);
--
1.8.3.1

View File

@ -0,0 +1,52 @@
From 974da80e08d24e92e5409bb040f95d06a47776a2 Mon Sep 17 00:00:00 2001
From: James Carter <jwcart2@gmail.com>
Date: Fri, 8 Oct 2021 10:27:49 -0400
Subject: [PATCH] libsepol/cil: Fix potential undefined shifts
An expression of the form "1 << x" is undefined if x == 31 because
the "1" is an int and cannot be left shifted by 31.
Instead, use "UINT32_C(1) << x" which will be an unsigned int of
at least 32 bits.
This bug was found by the secilc-fuzzer.
Signed-off-by: James Carter <jwcart2@gmail.com>
---
libsepol/cil/src/cil_binary.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
index ec5f01e..d8aa495 100644
--- a/libsepol/cil/src/cil_binary.c
+++ b/libsepol/cil/src/cil_binary.c
@@ -1225,7 +1225,7 @@ int __perm_str_to_datum(char *perm_str, class_datum_t *sepol_class, uint32_t *da
goto exit;
}
}
- *datum |= 1 << (sepol_perm->s.value - 1);
+ *datum |= UINT32_C(1) << (sepol_perm->s.value - 1);
return SEPOL_OK;
@@ -1523,7 +1523,7 @@ int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_
/* index of the u32 containing the permission */
#define XPERM_IDX(x) (x >> 5)
/* set bits 0 through x-1 within the u32 */
-#define XPERM_SETBITS(x) ((1U << (x & 0x1f)) - 1)
+#define XPERM_SETBITS(x) ((UINT32_C(1) << (x & 0x1f)) - 1)
/* low value for this u32 */
#define XPERM_LOW(x) (x << 5)
/* high value for this u32 */
@@ -4760,7 +4760,7 @@ static struct cil_list *cil_classperms_from_sepol(policydb_t *pdb, uint16_t clas
cil_list_init(&cp->perms, CIL_PERM);
for (i = 0; i < sepol_class->permissions.nprim; i++) {
struct cil_perm *perm;
- if ((data & (1 << i)) == 0) continue;
+ if ((data & (UINT32_C(1) << i)) == 0) continue;
perm = perm_value_to_cil[class][i+1];
if (!perm) goto exit;
cil_list_append(cp->perms, CIL_PERM, perm);
--
1.8.3.1

View File

@ -0,0 +1,95 @@
From 18f8747b28f1620903c7a3aa8a6616c199c173a6 Mon Sep 17 00:00:00 2001
From: James Carter <jwcart2@gmail.com>
Date: Thu, 16 Sep 2021 16:29:00 -0400
Subject: [PATCH] libsepol/cil: Handle operations in a class mapping when
verifying
When checking for circular class permission declarations and a class
mapping is encountered, the class permissions for each map permission
must be checked. An assumption was made that there were no operators
in the class permissions. An operator in the class permissions would
cause a segfault.
Example causing segault:
(classmap cm1 (mp1))
(classmapping cm1 mp1 (CLASS (PERM)))
(classpermission cp1)
(classpermissionset cp1 (cm1 (all)))
For map class permissions, check each item in the permission list to
see if it is an operator. If it is not, then verify the class
permissions associated with the map permission. If it is an operator
and the operator is "all", then create a list of all permissions for
that map class and verify the class permissions associated with each
map permission. If it is a different operator, then it can be skipped.
This bug was found by the secilc-fuzzer.
Signed-off-by: James Carter <jwcart2@gmail.com>
---
libsepol/cil/src/cil_verify.c | 40 +++++++++++++++++++++++++++++++++++-----
1 file changed, 35 insertions(+), 5 deletions(-)
diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
index 5502c4d..dc29ea6 100644
--- a/libsepol/cil/src/cil_verify.c
+++ b/libsepol/cil/src/cil_verify.c
@@ -1689,6 +1689,15 @@ exit:
return rc;
}
+static int __add_perm_to_list(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
+{
+ struct cil_list *perm_list = (struct cil_list *)args;
+
+ cil_list_append(perm_list, CIL_DATUM, d);
+
+ return SEPOL_OK;
+}
+
static int __cil_verify_classperms(struct cil_list *classperms,
struct cil_symtab_datum *orig,
struct cil_symtab_datum *parent,
@@ -1730,13 +1739,34 @@ static int __cil_verify_classperms(struct cil_list *classperms,
if (FLAVOR(cp->class) != CIL_CLASS) { /* MAP */
struct cil_list_item *i = NULL;
cil_list_for_each(i, cp->perms) {
- struct cil_perm *cmp = i->data;
- rc = __cil_verify_classperms(cmp->classperms, orig, &cp->class->datum, &cmp->datum, CIL_MAP_PERM, steps, limit);
- if (rc != SEPOL_OK) {
- goto exit;
+ if (i->flavor != CIL_OP) {
+ struct cil_perm *cmp = i->data;
+ rc = __cil_verify_classperms(cmp->classperms, orig, &cp->class->datum, &cmp->datum, CIL_MAP_PERM, steps, limit);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ } else {
+ enum cil_flavor op = (enum cil_flavor)i->data;
+ if (op == CIL_ALL) {
+ struct cil_class *mc = cp->class;
+ struct cil_list *perm_list;
+ struct cil_list_item *j = NULL;
+
+ cil_list_init(&perm_list, CIL_MAP_PERM);
+ cil_symtab_map(&mc->perms, __add_perm_to_list, perm_list);
+ cil_list_for_each(j, perm_list) {
+ struct cil_perm *cmp = j->data;
+ rc = __cil_verify_classperms(cmp->classperms, orig, &cp->class->datum, &cmp->datum, CIL_MAP_PERM, steps, limit);
+ if (rc != SEPOL_OK) {
+ cil_list_destroy(&perm_list, CIL_FALSE);
+ goto exit;
+ }
+ }
+ cil_list_destroy(&perm_list, CIL_FALSE);
+ }
}
}
- }
+ }
} else { /* SET */
struct cil_classperms_set *cp_set = curr->data;
struct cil_classpermission *cp = cp_set->set;
--
1.8.3.1

View File

@ -0,0 +1,39 @@
From 05d1c66aaae2b1ce3eaac7d241f24be121fddb39 Mon Sep 17 00:00:00 2001
From: James Carter <jwcart2@gmail.com>
Date: Fri, 27 Aug 2021 10:12:42 -0400
Subject: [PATCH] libsepol/cil: Properly check for parameter when inserting
name
File names for typetransition rules are stored in their own datums.
This allows them to be passed as a parameter, but there needs to be
a check in __cil_insert_name() so that parameter names are not
mistaken for file name strings. This check did not verify that a
matching parameter name had the flavor of CIL_NAME.
Check that the parameter flavor is CIL_NAME and that the paramter
name matches the file name to be stored in the datum.
This bug was found by the secilc-fuzzer.
Signed-off-by: James Carter <jwcart2@gmail.com>
---
libsepol/cil/src/cil_resolve_ast.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
index 1800732..a4de1c7 100644
--- a/libsepol/cil/src/cil_resolve_ast.c
+++ b/libsepol/cil/src/cil_resolve_ast.c
@@ -87,7 +87,8 @@ static struct cil_name * __cil_insert_name(struct cil_db *db, hashtab_key_t key,
if (macro != NULL && macro->params != NULL) {
struct cil_list_item *item;
cil_list_for_each(item, macro->params) {
- if (((struct cil_param*)item->data)->str == key) {
+ struct cil_param *param = item->data;
+ if (param->flavor == CIL_NAME && param->str == key) {
return NULL;
}
}
--
1.8.3.1

View File

@ -0,0 +1,57 @@
From b57535318af6f3f5e79c90caed06423b1f50abb1 Mon Sep 17 00:00:00 2001
From: James Carter <jwcart2@gmail.com>
Date: Fri, 27 Aug 2021 10:11:19 -0400
Subject: [PATCH] libsepol/cil: Reset expandtypeattribute rules when resetting
AST
A list is created to store type attribute datums when resolving an
expandtypeattribute rule and that list needs to be destroyed if the
AST is reset or a memory leak will occur.
Destroy the list storing type attributes datums when resetting
expandtypeattribute rules.
This bug was found by the secilc-fuzzer.
Signed-off-by: James Carter <jwcart2@gmail.com>
---
libsepol/cil/src/cil_reset_ast.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c
index 6d1d2da..0ba075c 100644
--- a/libsepol/cil/src/cil_reset_ast.c
+++ b/libsepol/cil/src/cil_reset_ast.c
@@ -208,6 +208,11 @@ static void cil_reset_typeattributeset(struct cil_typeattributeset *tas)
cil_list_destroy(&tas->datum_expr, CIL_FALSE);
}
+static void cil_reset_expandtypeattribute(struct cil_expandtypeattribute *expandattr)
+{
+ cil_list_destroy(&expandattr->attr_datums, CIL_FALSE);
+}
+
static void cil_reset_avrule(struct cil_avrule *rule)
{
cil_reset_classperms_list(rule->perms.classperms);
@@ -531,6 +536,9 @@ int __cil_reset_node(struct cil_tree_node *node, __attribute__((unused)) uint32
case CIL_TYPEATTRIBUTESET:
cil_reset_typeattributeset(node->data);
break;
+ case CIL_EXPANDTYPEATTRIBUTE:
+ cil_reset_expandtypeattribute(node->data);
+ break;
case CIL_RANGETRANSITION:
cil_reset_rangetransition(node->data);
break;
@@ -630,7 +638,6 @@ int __cil_reset_node(struct cil_tree_node *node, __attribute__((unused)) uint32
case CIL_CLASSORDER:
case CIL_CATORDER:
case CIL_SENSITIVITYORDER:
- case CIL_EXPANDTYPEATTRIBUTE:
break; /* Nothing to reset */
default:
break;
--
1.8.3.1

View File

@ -0,0 +1,53 @@
From 4662bdc11c8f505716f8da361a07ad13083b0618 Mon Sep 17 00:00:00 2001
From: Nicolas Iooss <nicolas.iooss@m4x.org>
Date: Fri, 5 Feb 2021 10:45:38 +0100
Subject: [PATCH] libsepol/cil: be more robust when encountering <src_info>
OSS-Fuzz found a Null-dereference READ in the CIL compiler when trying
to compile the following policy:
(<src_info>)
In cil_gen_src_info(), parse_current->next is NULL even though the code
expects that both parse_current->next and parse_current->next->next
exists.
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28457
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
---
libsepol/cil/src/cil_build_ast.c | 5 +++++
libsepol/cil/src/cil_tree.c | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
index 5094d62..726f46c 100644
--- a/libsepol/cil/src/cil_build_ast.c
+++ b/libsepol/cil/src/cil_build_ast.c
@@ -6070,6 +6070,11 @@ int cil_gen_src_info(struct cil_tree_node *parse_current, struct cil_tree_node *
/* No need to check syntax, because this is auto generated */
struct cil_src_info *info = NULL;
+ if (parse_current->next == NULL || parse_current->next->next == NULL) {
+ cil_tree_log(parse_current, CIL_ERR, "Bad <src_info>");
+ return SEPOL_ERR;
+ }
+
cil_src_info_init(&info);
info->is_cil = (parse_current->next->data == CIL_KEY_SRC_CIL) ? CIL_TRUE : CIL_FALSE;
diff --git a/libsepol/cil/src/cil_tree.c b/libsepol/cil/src/cil_tree.c
index 886412d..3da972e 100644
--- a/libsepol/cil/src/cil_tree.c
+++ b/libsepol/cil/src/cil_tree.c
@@ -69,7 +69,7 @@ struct cil_tree_node *cil_tree_get_next_path(struct cil_tree_node *node, char **
while (node) {
if (node->flavor == CIL_NODE && node->data == NULL) {
- if (node->cl_head->data == CIL_KEY_SRC_INFO) {
+ if (node->cl_head->data == CIL_KEY_SRC_INFO && node->cl_head->next != NULL && node->cl_head->next->next != NULL) {
/* Parse Tree */
*path = node->cl_head->next->next->data;
*is_cil = (node->cl_head->next->data == CIL_KEY_SRC_CIL);
--
1.8.3.1

View File

@ -0,0 +1,42 @@
From c5e6153720e713e72a65614f625a51ad44d1fc07 Mon Sep 17 00:00:00 2001
From: Nicolas Iooss <nicolas.iooss@m4x.org>
Date: Sun, 14 Mar 2021 19:25:58 +0100
Subject: [PATCH] libsepol/cil: fix NULL pointer dereference in
__cil_insert_name
OSS-Fuzz found a Null-dereference in __cil_insert_name when trying to
compile the following policy:
(macro MACRO ()
(classmap CLASS (PERM))
(type TYPE)
(typetransition TYPE TYPE CLASS "name" TYPE)
)
(call MACRO)
When using a macro with no argument, macro->params is NULL and
cil_list_for_each(item, macro->params) dereferenced a NULL pointer.
Fix this by checking that macro->params is not NULL before using it.
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28565
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
---
libsepol/cil/src/cil_resolve_ast.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
index 2ea106d..63beed9 100644
--- a/libsepol/cil/src/cil_resolve_ast.c
+++ b/libsepol/cil/src/cil_resolve_ast.c
@@ -82,7 +82,7 @@ static struct cil_name * __cil_insert_name(struct cil_db *db, hashtab_key_t key,
} else if (parent->flavor == CIL_MACRO) {
macro = parent->data;
}
- if (macro != NULL) {
+ if (macro != NULL && macro->params != NULL) {
struct cil_list_item *item;
cil_list_for_each(item, macro->params) {
if (((struct cil_param*)item->data)->str == key) {
--
1.8.3.1

View File

@ -0,0 +1,92 @@
From 521e6a2f478a4c7a7c198c017d4d12e8667d89e7 Mon Sep 17 00:00:00 2001
From: Nicolas Iooss <nicolas.iooss@m4x.org>
Date: Sat, 3 Oct 2020 15:19:08 +0200
Subject: [PATCH] libsepol/cil: fix signed overflow caused by using (1 << 31) -
1
When compiling SELinux userspace tools with -ftrapv (this option
generates traps for signed overflow on addition, subtraction,
multiplication operations, instead of silently wrapping around),
semodule crashes when running the tests from
scripts/ci/fedora-test-runner.sh in a Fedora 32 virtual machine:
[root@localhost selinux-testsuite]# make test
make -C policy load
make[1]: Entering directory '/root/selinux-testsuite/policy'
# Test for "expand-check = 0" in /etc/selinux/semanage.conf
# General policy build
make[2]: Entering directory '/root/selinux-testsuite/policy/test_policy'
Compiling targeted test_policy module
Creating targeted test_policy.pp policy package
rm tmp/test_policy.mod.fc
make[2]: Leaving directory '/root/selinux-testsuite/policy/test_policy'
# General policy load
domain_fd_use --> off
/usr/sbin/semodule -i test_policy/test_policy.pp test_mlsconstrain.cil test_overlay_defaultrange.cil test_add_levels.cil test_glblub.cil
make[1]: *** [Makefile:174: load] Aborted (core dumped)
Using "coredumpctl gdb" leads to the following strack trace:
(gdb) bt
#0 0x00007f608fe4fa25 in raise () from /lib64/libc.so.6
#1 0x00007f608fe38895 in abort () from /lib64/libc.so.6
#2 0x00007f6090028aca in __addvsi3.cold () from /lib64/libsepol.so.1
#3 0x00007f6090096f59 in __avrule_xperm_setrangebits (low=30, high=30, xperms=0x8b9eea0)
at ../cil/src/cil_binary.c:1551
#4 0x00007f60900970dd in __cil_permx_bitmap_to_sepol_xperms_list (xperms=0xb650a30, xperms_list=0x7ffce2653b18)
at ../cil/src/cil_binary.c:1596
#5 0x00007f6090097286 in __cil_avrulex_ioctl_to_policydb (k=0xb8ec200 "@\023\214\022\006", datum=0xb650a30,
args=0x239a640) at ../cil/src/cil_binary.c:1649
#6 0x00007f609003f1e5 in hashtab_map (h=0x41f8710, apply=0x7f60900971da <__cil_avrulex_ioctl_to_policydb>,
args=0x239a640) at hashtab.c:234
#7 0x00007f609009ea19 in cil_binary_create_allocated_pdb (db=0x2394f10, policydb=0x239a640)
at ../cil/src/cil_binary.c:4969
#8 0x00007f609009d19d in cil_binary_create (db=0x2394f10, policydb=0x7ffce2653d30) at ../cil/src/cil_binary.c:4329
#9 0x00007f609008ec23 in cil_build_policydb_create_pdb (db=0x2394f10, sepol_db=0x7ffce2653d30)
at ../cil/src/cil.c:631
#10 0x00007f608fff4bf3 in semanage_direct_commit () from /lib64/libsemanage.so.1
#11 0x00007f608fff9fae in semanage_commit () from /lib64/libsemanage.so.1
#12 0x0000000000403e2b in main (argc=7, argv=0x7ffce2655058) at semodule.c:753
(gdb) f 3
#3 0x00007f6090096f59 in __avrule_xperm_setrangebits (low=30, high=30, xperms=0x8b9eea0)
at ../cil/src/cil_binary.c:1551
1551 xperms->perms[i] |= XPERM_SETBITS(h) - XPERM_SETBITS(low);
A signed integer overflow therefore occurs in XPERM_SETBITS(h):
#define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1)
This macro is expanded with h=31, so "(1 << 31) - 1" is computed:
* (1 << 31) = -0x80000000 is the lowest signed 32-bit integer value
* (1 << 31) - 1 overflows the capacity of a signed 32-bit integer and
results in 0x7fffffff (which is unsigned)
Using unsigned integers (with "1U") fixes the crash, as
(1U << 31) = 0x80000000U has no overflowing issues.
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Acked-by: Petr Lautrbach <plautrba@redhat.com>
Conflict:remove contents of checkpolicy/policy_define.c
---
libsepol/cil/src/cil_binary.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
index 36720ed..e417c5c 100644
--- a/libsepol/cil/src/cil_binary.c
+++ b/libsepol/cil/src/cil_binary.c
@@ -1526,7 +1526,7 @@ int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_
/* index of the u32 containing the permission */
#define XPERM_IDX(x) (x >> 5)
/* set bits 0 through x-1 within the u32 */
-#define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1)
+#define XPERM_SETBITS(x) ((1U << (x & 0x1f)) - 1)
/* low value for this u32 */
#define XPERM_LOW(x) (x << 5)
/* high value for this u32 */
--
1.8.3.1

View File

@ -1,6 +1,6 @@
Name: libsepol
Version: 3.1
Release: 5
Release: 6
Summary: SELinux binary policy manipulation library
License: LGPLv2+
URL: https://github.com/SELinuxProject/selinux/wiki/Releases
@ -38,6 +38,14 @@ Patch28: backport-libsepol-cil-Fix-instances-where-an-error-returns-SE.pa
Patch29: backport-libsepol-cil-Limit-the-number-of-open-parenthesis-al.patch
Patch30: backport-libsepol-cil-Fix-syntax-checking-of-defaultrange-rul.patch
Patch31: backport-libsepol-cil-Allow-some-duplicate-macro-and-block-de.patch
Patch32: backport-libsepol-cil-fix-signed-overflow-caused-by-using-1-3.patch
Patch33: backport-libsepol-cil-Fix-potential-undefined-shifts.patch
Patch34: backport-libsepol-cil-be-more-robust-when-encountering-src_in.patch
Patch35: backport-libsepol-cil-Handle-operations-in-a-class-mapping-wh.patch
Patch36: backport-libsepol-cil-Allow-permission-expressions-when-using.patch
Patch37: backport-libsepol-cil-fix-NULL-pointer-dereference-in-__cil_i.patch
Patch38: backport-libsepol-cil-Properly-check-for-parameter-when-inser.patch
Patch39: backport-libsepol-cil-Reset-expandtypeattribute-rules-when-re.patch
BuildRequires: gcc flex
@ -97,6 +105,9 @@ make DESTDIR="%{buildroot}" LIBDIR="%{_libdir}" SHLIBDIR="%{_libdir}" install
%{_mandir}/man3/*
%changelog
* Fri Dec 10 2021 panxiaohe <panxiaohe@huawei.com> - 3.1-6
- fix secilc-fuzzer issues
* Fri Sep 10 2021 panxiaohe <panxiaohe@huawei.com> - 3.1-5
- fix secilc-fuzzer issues