Re: [Bug] Double free vulnerability at define_genfs_context_helper
Stephen Smalley <[email protected]>
| Newsgroups | org.kernel.vger.selinux |
|---|---|
| Message-ID | <CAEjxPJ6rMJd--Tg5yzByzFRQ=irbE0f4fxik48FdaxsT=Qtfbg@mail.gmail.com> |
On Thu, Jul 9, 2026 at 4:11 PM COMS VLAB <[email protected]> wrote: > > 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. Thanks, unfortunately we need a Signed-off-by: line with an actual person's name and email address and your patch was whitespace-damaged by your mail client. Try using git send-email instead, see https://github.com/SELinuxProject/selinux-kernel/wiki/Getting-Started#submitting-patches for some tips. If that proves unworkable, we can always just fix it on our end especially since the fix is so trivial. > --- > 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?