All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Mathieu Dubois-Briand" <mathieu.dubois-briand@bootlin.com>
To: <yocto-patches@lists.yoctoproject.org>
Cc: <seebs@seebs.net>, <mark.hatle@kernel.crashing.org>
Subject: Re: [yocto-patches] [pseudo] [PATCH] pseudo_client: Fix xattr/rename handling with empty paths
Date: Thu, 15 Oct 2026 17:43:17 +0200	[thread overview]
Message-ID: <DM5IZI5V42H3.27O69TM6XIPKC@bootlin.com> (raw)
In-Reply-To: <20a05c7e247e12bbf0d2adfb3286f0438ae8ac5f.camel@linuxfoundation.org>

On Thu Oct 15, 2026 at 4:25 PM CEST, Richard Purdie via lists.yoctoproject.org wrote:
> On Thu, 2026-10-15 at 15:38 +0200, Mathieu Dubois-Briand via lists.yoctoproject.org wrote:
>> On Wed Oct 14, 2026 at 9:38 PM CEST, Richard Purdie via lists.yoctoproject.org wrote:
>> > On Fedora45, we can end up in a situation where path_extra_1 (for xattr/rename ops)
>> > but path is of zero length. The path_extra_1 codepath does not handle this well and
>> > corrupts memory.
>> > 
>> > The issue is "partial_len = pathlen - 1 - strip_slash" when pathlen is 0 (and
>> > hence strip_slash is also 0). This leads to invalid memory writes and if those
>> > happen to access off the end of a mapped segment, the program segfaults.
>> > 
>> > Fix the code to handle the pathlen=0 case.
>> > 
>> > Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
>> > ---
>> >  pseudo_client.c | 17 +++++++++++------
>> >  1 file changed, 11 insertions(+), 6 deletions(-)
>> > 
>> > diff --git a/pseudo_client.c b/pseudo_client.c
>> > index 23d7b0f..002de30 100644
>> > --- a/pseudo_client.c
>> > +++ b/pseudo_client.c
>> > @@ -1789,7 +1789,7 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
>> >  	 */
>> >  	if (path_extra_1) {
>> >  		size_t full_len = path_extra_1len + 1 + pathlen - strip_slash;
>> > -		size_t partial_len = pathlen - 1 - strip_slash;
>> > +		size_t partial_len = pathlen - strip_slash;
>> >  		if (path_extra_2) {
>> >  			full_len += path_extra_2len + 1;
>> >  		}
>> > @@ -1804,12 +1804,17 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
>> >  				return 0;
>> >  			}
>> >  		}
>> > -		memcpy(alloced_path, path, partial_len);
>> > -		alloced_path[partial_len] = '\0';
>> > -		memcpy(alloced_path + partial_len + 1, path_extra_1, path_extra_1len);
>> > -		alloced_path[partial_len + path_extra_1len + 1] = '\0';
>> > +		if (pathlen) {
>> > +			memcpy(alloced_path, path, partial_len - 1);
>> > +			alloced_path[partial_len - 1] = '\0';
>> > +		} else {
>> > +			alloced_path[0] = '\0';
>> > +			partial_len = 1;
>> 
>> Err, I have a doubt here.
>> 
>> Setting partial_len to 1 looks correct, but it was previously used to
>> compute full_len, that is used to check the if buffer is big enough
>> (full_len > alloced_len).
>> 
>> So if pathlen is 0, the buffer can be 1 byte too short, right? Just
>> incrementing partial_len a bit before should fix that.
>
> I can't see where partial_len is used in the computation for full_len ?
>
> 		size_t full_len = path_extra_1len + 1 + pathlen - strip_slash;
> 		size_t partial_len = pathlen - strip_slash;
> 		if (path_extra_2) {
> 			full_len += path_extra_2len + 1;
> 		}
> 		if (full_len > alloced_len) {
>                     <realloc code>
> 		}
>
> Cheers,
>
> Richard
>
Yes, sorry, my previous mail does not make any sense. Let's try that
again.

So my point is, if pathlen is 0, we have:

>		size_t full_len = path_extra_1len + 1 + pathlen - strip_slash;

So full_len is going to be:
path_extra_1len + 1 + 0 (pathlen) - strip_slash
So it will be at most:
path_extra_1len + 1

>		size_t partial_len = pathlen - strip_slash;
>		if (path_extra_2) {
>			full_len += path_extra_2len + 1;
>		}
>		if (full_len > alloced_len) {
>			free(alloced_path);
>			alloced_path = malloc(full_len);
>			alloced_len = full_len;
>			if (!alloced_path) {
>				pseudo_diag("Can't allocate space for paths for a rename operation.  Sorry.\n");
>				alloced_len = 0;
>				pseudo_magic();
>				return 0;
>			}

So buffer size is at most `path_extra_1len + 1`

>		}
>		if (pathlen) {
>			memcpy(alloced_path, path, partial_len - 1);
>			alloced_path[partial_len - 1] = '\0';
>		} else {
>			alloced_path[0] = '\0';
>			partial_len = 1;

OK, partial_len is 1

>		}
>		memcpy(alloced_path + partial_len, path_extra_1, path_extra_1len);
>		alloced_path[partial_len + path_extra_1len] = '\0';

Then here we write at offset `1 + path_extra_1len`.
So buffer size should be at least `1 + path_extra_1len + 1`

>		if (path_extra_2) {
>			memcpy(alloced_path + partial_len + path_extra_1len + 1, path_extra_2, path_extra_2len);
>		}
>		alloced_path[full_len - 1] = '\0';
>		path = alloced_path;
>		pathlen = full_len;
>		pseudo_debug_call(PDBGF_IPC | PDBGF_VERBOSE, pseudo_dump_data, "combined path buffer", path, pathlen);

Hopefully this makes a bit more sense now :)

Thanks,
Mathieu

-- 
Mathieu Dubois-Briand, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



  reply	other threads:[~2026-10-15 15:43 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-14 19:38 [pseudo] [PATCH] pseudo_client: Fix xattr/rename handling with empty paths Richard Purdie
2026-10-15 13:38 ` [yocto-patches] " Mathieu Dubois-Briand
2026-10-15 14:25   ` Richard Purdie
2026-10-15 15:43     ` Mathieu Dubois-Briand [this message]
2026-10-15 21:54       ` Richard Purdie
     [not found] <18DE7C971DAD1AD4.2478941@lists.yoctoproject.org>
2026-10-15 11:44 ` Richard Purdie

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=DM5IZI5V42H3.27O69TM6XIPKC@bootlin.com \
    --to=mathieu.dubois-briand@bootlin.com \
    --cc=mark.hatle@kernel.crashing.org \
    --cc=seebs@seebs.net \
    --cc=yocto-patches@lists.yoctoproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.