Re: [Bug] Double free vulnerability at define_genfs_context_helper

COMS VLAB <[email protected]>
Newsgroups org.kernel.vger.selinux
Message-ID <CA+jXL7m20TzvdCuuz0d_bgAvf+GV5dFmKJb9gFEYjf+OYUYuZQ@mail.gmail.com>
Hi Stephen,

Yes, patch below. Please attribute the report to "Reported-by: UCSB VLab <
[email protected]>".

The fix clears the local `fstype` after it's handed to `newgenfs`, so the
`fail:` cleanup no longer frees it and the genfs list becomes its sole
owner (freed once by `policydb_destroy()`), mirroring the `else` branch.
Verified with ASan: pre-fix double-free, post-fix clean.
---
 checkpolicy/policy_define.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
index b73de45..f8c4d28 100644
--- a/checkpolicy/policy_define.c
+++ b/checkpolicy/policy_define.c
@@ -6050,6 +6050,8 @@ static int define_genfs_context_helper(char *fstype,
int has_type)
  }
  memset(newgenfs, 0, sizeof(struct genfs));
  newgenfs->fstype = fstype;
+ /* ownership transferred into the genfs list; do not free on error */
+ fstype = NULL;
  newgenfs->next = genfs;
  if (genfs_p)
  genfs_p->next = newgenfs;
--

I added the patch file. Let us know if you need anything more.

Thanks,
UCSB VLab

On Thu, Jul 9, 2026 at 12:05 PM Stephen Smalley <
[email protected]> wrote:

> On Thu, Jul 9, 2026 at 2:57 PM COMS VLAB <[email protected]> wrote:
> >
> > Summary
> >
> > A double-free vulnerability exists in the checkpolicy source policy
> compiler's handling of genfscon statements. When parsing a new (previously
> unseen) filesystem type string, define_genfs_context_helper() transfers
> ownership of the fstype pointer into a genfs struct that is linked into the
> policydb's live genfs list, but fails to clear the local fstype variable
> afterward. If any subsequent parsing step in the same function fails,
> execution jumps to a shared fail: cleanup block. This cleanup block frees
> fstype, which leaves a dangling pointer in the genfs list. When the
> policydb is later destroyed via policydb_destroy(), it frees that same
> pointer again, causing the double-free.
> >
> >
> >
> > Version
> >
> > 06159ee35d6b4c968c1f942c9361c111644de826 - current version
> >
> >
> >
> > PoC: Please see attachment
> >
> >
> >
> > ASAN Report
> >
> > ==2502==ERROR: AddressSanitizer: attempting double-free on
> 0xfc1f82fe1330 in thread T0:
> >
> >     #0 0xaaaac9f6d518 in free (/selinux/repro+0xed518) (BuildId:
> ea3a1d5343a0633f08393e738125b8f44be83f66)
> >
> >     #1 0xaaaac9ffd49c in policydb_destroy
> selinux/libsepol/src/policydb.c:1596:3
> >
> >     #2 0xaaaac9faf758 in main selinux/../repro.c:11:5
> >
> >     #3 0xffff83c62f18  (/usr/lib/aarch64-linux-gnu/libc.so.6+0x22f18)
> (BuildId: b50ceafbd17dc6bceee344a66671c7eaa152bef4)
> >
> >     #4 0xffff83c63058 in __libc_start_main
> (/usr/lib/aarch64-linux-gnu/libc.so.6+0x23058) (BuildId:
> b50ceafbd17dc6bceee344a66671c7eaa152bef4)
> >
> >     #5 0xaaaac9ec7c6c in _start (selinux/repro+0x47c6c) (BuildId:
> ea3a1d5343a0633f08393e738125b8f44be83f66)
> >
> > 0xfc1f82fe1330 is located 0 bytes inside of 2-byte region
> [0xfc1f82fe1330,0xfc1f82fe1332)
> >
> > freed by thread T0 here:
> >
> >     #0 0xaaaac9f6d518 in free (/selinux/repro+0xed518) (BuildId:
> ea3a1d5343a0633f08393e738125b8f44be83f66)
> >
> >     #1 0xaaaac9fc8a60 in define_genfs_context_helper
> /selinux/checkpolicy/policy_define.c:6163:2
> >
> >     #2 0xaaaac9fc8a60 in define_genfs_context
> /selinux/checkpolicy/policy_define.c:6171:9
> >
> >     #3 0xaaaac9fcbc1c in yyparse
> /selinux/checkpolicy/policy_parse.y:787:30
> >
> >     #4 0xaaaac9fb95b4 in read_source_policy
> /selinux/checkpolicy/parse_util.c:70:6
> >
> >     #5 0xaaaac9faf750 in main /selinux/../repro.c:10:5
> >
> >     #6 0xffff83c62f18  (/usr/lib/aarch64-linux-gnu/libc.so.6+0x22f18)
> (BuildId: b50ceafbd17dc6bceee344a66671c7eaa152bef4)
> >
> >     #7 0xffff83c63058 in __libc_start_main
> (/usr/lib/aarch64-linux-gnu/libc.so.6+0x23058) (BuildId:
> b50ceafbd17dc6bceee344a66671c7eaa152bef4)
> >
> >     #8 0xaaaac9ec7c6c in _start (/selinux/repro+0x47c6c) (BuildId:
> ea3a1d5343a0633f08393e738125b8f44be83f66)
> >
> > previously allocated by thread T0 here:
> >
> >     #0 0xaaaac9f53a4c in strdup (/selinux/repro+0xd3a4c) (BuildId:
> ea3a1d5343a0633f08393e738125b8f44be83f66)
> >
> >     #1 0xaaaac9fb9aa0 in insert_id
> /selinux/checkpolicy/policy_define.c:131:10
> >
> >     #2 0xaaaac9fcc744 in yyparse /selinux/checkpolicy/policy_parse.y
> >
> >     #3 0xaaaac9fb95b4 in read_source_policy
> /selinux/checkpolicy/parse_util.c:70:6
> >
> >     #4 0xaaaac9faf750 in main /selinux/../repro.c:10:5
> >
> >     #5 0xffff83c62f18  (/usr/lib/aarch64-linux-gnu/libc.so.6+0x22f18)
> (BuildId: b50ceafbd17dc6bceee344a66671c7eaa152bef4)
> >
> >     #6 0xffff83c63058 in __libc_start_main
> (/usr/lib/aarch64-linux-gnu/libc.so.6+0x23058) (BuildId:
> b50ceafbd17dc6bceee344a66671c7eaa152bef4)
> >
> >     #7 0xaaaac9ec7c6c in _start (/selinux/repro+0x47c6c) (BuildId:
> ea3a1d5343a0633f08393e738125b8f44be83f66)
> >
> > SUMMARY: AddressSanitizer: double-free (/selinux/repro+0xed518)
> (BuildId: ea3a1d5343a0633f08393e738125b8f44be83f66) in free
> >
> > ==2502==ABORTING
>
> Thanks for the report. Are you planning on submitting a patch for it?
> How did you want us to attribute the report regardless?
>
0001-checkpolicy-fix-double-free-of-fstype-in-define_genfs_context_helper.patch (text/x-patch, 1.2 KB)
From 9c0b1c9501b563831c46b47fb5f4f3d182dbe789 Mon Sep 17 00:00:00 2001
From: UCSB VLab <[email protected]>
Date: Thu, 9 Jul 2026 12:00:00 -0700
Subject: [PATCH] checkpolicy: fix double free of fstype in
 define_genfs_context_helper

When parsing a new filesystem type, define_genfs_context_helper() transfers
ownership of fstype into a genfs struct linked into the policydb's genfs
list, but does not clear the local fstype. A later goto fail then frees it,
leaving a dangling pointer that policydb_destroy() frees again.

Clear fstype after the ownership transfer, mirroring the else branch.

Reported-by: UCSB VLab <[email protected]>
---
 checkpolicy/policy_define.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
index b73de45..f8c4d28 100644
--- a/checkpolicy/policy_define.c
+++ b/checkpolicy/policy_define.c
@@ -6050,6 +6050,8 @@ static int define_genfs_context_helper(char *fstype, int has_type)
 		}
 		memset(newgenfs, 0, sizeof(struct genfs));
 		newgenfs->fstype = fstype;
+		/* ownership transferred into the genfs list; do not free on error */
+		fstype = NULL;
 		newgenfs->next = genfs;
 		if (genfs_p)
 			genfs_p->next = newgenfs;
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.