From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mta1.formilux.org (mta1.formilux.org [51.159.59.229]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6500A31AAA8; Thu, 15 Jan 2026 20:19:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=51.159.59.229 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768508351; cv=none; b=qQKnjhAZKx5kiFJYR36Q+e6xfndIHIMQTXFMy6R3QqVmKTY13dA7QSY0v3gfiB7c2s5WjxDhx2dwV/mrqmhoSQLGXfvHRoCss+gFP5x9AUffSI/9Il2cxSc/yybH9TBTh/p5qi9x0ETO89lyfXPbORDaocgT8CUs9G73s6ZOupA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768508351; c=relaxed/simple; bh=PkWMJbgG30qvn/kk4nfhRoFjfQKxSR345VAokulLNlw=; h=Date:From:To:Cc:Subject:Message-ID:MIME-Version:Content-Type: Content-Disposition; b=H4aPUzwbJpqtRYn1Em0M5kBepj+Jw3axeMrezYw2AtLZ34LHcflUPFy5kUWzAibg7S9FLvYZyNJCVrSU6ADMfCQ4DMrw/hlhAx4/sMchdQEqPccwsESFWjAk4RP+gNKleKmiBHXoXCvxqDqndD67fDVXVJNRoNVtEiLZf97+htg= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=1wt.eu; spf=pass smtp.mailfrom=1wt.eu; dkim=pass (1024-bit key) header.d=1wt.eu header.i=@1wt.eu header.b=HFrMaR8K; arc=none smtp.client-ip=51.159.59.229 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=1wt.eu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=1wt.eu Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=1wt.eu header.i=@1wt.eu header.b="HFrMaR8K" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1wt.eu; s=mail; t=1768508340; bh=ZDQuS3dK1IrlbWJs15I7fbnuinR386XZYn/sxeLVbEw=; h=From:Message-ID:From; b=HFrMaR8K27qmeGF5yBl9IW9np+7mFz1vjQRC9Re8o64ZwX5wrP5njbHeOaBfgcLck X5oLRDTggQfWyVIiS/tQ803XxF59biElRqCWSyLbW/iSYpTMpRxf0XTgCBCyRU/Ru+ Mtx+kDQL7gBRydJlQlnXVq5tEADKi13fsv5DyUrs= Received: from 1wt.eu (ded1.1wt.eu [163.172.96.212]) by mta1.formilux.org (Postfix) with ESMTP id 12F78C0BB3; Thu, 15 Jan 2026 21:19:00 +0100 (CET) Date: Thu, 15 Jan 2026 21:18:59 +0100 From: Willy Tarreau To: Paul Moore , Stephen Smalley Cc: security@kernel.org, selinux@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Suspected off-by-one in context_struct_to_string() Message-ID: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hello, we've received a suspected vulnerability report on the kernel security list, that was clearly generated by AI and really not clear at all on the root causes nor impacts. We first dismissed it and it kept coming back a few times. I'm not pasting it because it's more confusing than interesting, though I can pass it to the maintainers if desired. I'm also purposely *not* CCing the reporter, as the address changed a few times, and once you respond you receive a new copy of the same report. Clearly this bot deserves a bit more tuning. The report claimed that the call to mls_compute_context_len() didn't properly reflect the size needed by mls_sid_to_context() due to an off-by-one that would result in the trailing zero being written too far. Initially we thought that was wrong since there are +1 everywhere in all lengths calculation in the function. But revisiting it today made us realize that this indeed seems to be true: the +1 that are everywhere are in fact due to the surrounding delimiters, and the first one that appeared to be the one accounting for the trailing zero was in fact for the starting colon. In context_struct_to_string(), we have this: *scontext_len += strlen(sym_name(p, SYM_USERS, context->user - 1)) + 1; *scontext_len += strlen(sym_name(p, SYM_ROLES, context->role - 1)) + 1; *scontext_len += strlen(sym_name(p, SYM_TYPES, context->type - 1)) + 1; *scontext_len += mls_compute_context_len(p, context); *scontext_len is initialized to zero, is increased by the length of each appended string + delimiter, and used as-is in kmalloc() a few lines later: scontextp = kmalloc(*scontext_len, GFP_ATOMIC); then filled by sprintf() then mls_sid_to_context(): scontextp += sprintf(scontextp, "%s:%s:%s", sym_name(p, SYM_USERS, context->user - 1), sym_name(p, SYM_ROLES, context->role - 1), sym_name(p, SYM_TYPES, context->type - 1)); mls_sid_to_context(p, context, &scontextp); And finally the trailing zero is appended: *scontextp = 0; Thus unless I'm missing something, that trailing zero is indeed written past the end of the allocated area. The impact looks fairly limited though given that root is required to reach that code. Given the semantics of *scontext_len that claims to contain the string length, my feeling is that we should add one to the kmalloc() call: - scontextp = kmalloc(*scontext_len, GFP_ATOMIC); + scontextp = kmalloc(*scontext_len + 1, GFP_ATOMIC); I must confess we got confused a bit when trying to follow this code, because the called functions do not indicate the expected output format nor whether or not the trailing zero is counted, so it's easy to think that a +1 stands for the trailing zero instead of an unclear delimiter. Also, it looks like the sole purpose of mls_compute_context_len() is to compute the length that will be needed to store the result of mls_sid_to_context(), and results in an almost copy-paste of one into the other, making it harder to check if they match (we had to read them due to the report pointing at that first one for being wrong, which is not the case depending on what we consider as a string length). I think that instead a change consisting in calling mls_sid_to_context() with a NULL destination buffer to avoid emitting bytes, and making it return the length could make the whole design more robust by doing a first call to compute the length and a second one to perform the copy. Let us know if you need more info, if all of this is wrong, if you want a copy of the original report or even the reporter's address if you want to attempt to communicate with them (we don't even know if there's a human or only a bot there). Thanks, Willy