[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v1 1/1] arm64: Fix strrchr() matching of null terminator


  • To: Jan Beulich <jbeulich@xxxxxxxx>
  • From: "Edgar E. Iglesias" <edgar.iglesias@xxxxxxx>
  • Date: Tue, 19 May 2026 17:24:24 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=L2FPL1DcUqrpzDA09JXWsJT5W314n+sIwMchd5dgiPQ=; b=b/UULwZl0m1cvTxsU5zf2/v0uWBAxDe3tM3PtmMJoaDqZPQx8QZYjc0z0GNVWqbgx16EEV9YuEkM09kQvTrAVTtXCz2qPBAna9UXbhsT74yBpgmY2fPia9ah0wqA+H+I+Kw8D8DB+Yd2i6Z/fs4ItapfUehm+7m9ne0qvsTBz/HbEHlYeVtDRN4yBmSt74JdMNHVNgeMzj6ExS7oc7cQLTwKtUqEYxq4pZvrKnemQ9+oCh9D0Tvl4x9Hfl2B/3ZsuNQielb2cXX0fwpLb2Jedj9/QhsNr8m8EQyplUt7RXTq2MjCscKlyZ2UoAU63zGxPdA9FeBszxfa5IgJ/+08+w==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=dKZLqP/6Sc8wWaTL6rYRBOgY8ifiprFYvEp3rzTLaF7hlqXu1LJWhUji1ANn3LH0CQ07MW6msSUAtBa5V5WTADtzxrBAM+6mM+6g9mxWkUSPR4lBQRIpFBuscW+9wyqHQAR/+U4nJpf/mjVcopi18uIn5o5RiDDooOf/EEmlAOm252+ISwhjFSizngReKcMYVZZ9LMaDCAYtBwD2CcMgAvhj7zUS5TEK+2P7m6xNfCGaEC5UMaFIoES4LEDgxiFCvOLYiMHAtgiyySmuEXUrEQxZKBghjFROIp8nGc5v3KTHvwfHC6bcCzaN0XpARUOB7IVS5WvCoXhWY3rUgeqb2g==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=amd.com header.i="@amd.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=amd.com;
  • Cc: sstabellini@xxxxxxxxxx, julien@xxxxxxx, bertrand.marquis@xxxxxxx, michal.orzel@xxxxxxx, Volodymyr_Babchuk@xxxxxxxx, xen-devel@xxxxxxxxxxxxxxxxxxxx
  • Delivery-date: Tue, 19 May 2026 15:24:45 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On Tue, May 19, 2026 at 08:40:54AM +0200, Jan Beulich wrote:
> On 19.05.2026 01:43, Edgar E. Iglesias wrote:
> > The generic Xen strrchr() implementation returns a pointer to the string
> > terminator when searching for '\0', matching the standard C semantics.
> > 
> > The ARM64 assembly version stopped as soon as it loaded the terminator and
> > returned the previous match pointer instead.  This made strrchr("", '\0')
> > return NULL.
> 
> I wonder though: Why would one pass '\0' to strrchr()? If you want to find
> the end of a string, more efficient (at least in the general case) options
> exist (strchr(), memchr(), strlen()).

Right, this came from a fuzzer checking standard strrchr() behavior, not
from an explicit end-of-string use case.

I agree strlen() or strchr(s, '\0') would be better for that, but
strrchr(s, '\0') is valid input, so we should handle it to avoid
surprises for existing or future callers.


> 
> > Compare the loaded byte against the requested character before deciding
> > whether to stop at the terminator, so the terminator itself can be returned
> > when it is the requested character.
> 
> Nit: "..., so a pointer to the terminator ...".

Updated, thanks.


> 
> > Fixes: 42c4eb6a83 ("xen: arm64: assembly optimised mem* and str*")
> > Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xxxxxxx>
> 
> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
> 
> However, the function having come from Linux, imo the patch wants to go to
> Linux (ideally first, but at the very least also).

Yes, sounds good.


> 
> Additionally, looking at strchr() - couldn't the code here be written in a
> similar way, allowing to get away with just a single branch? (Arm32's pair
> of functions is also pretty similar in this regard.)

Hm, good point. I had a closer look and came up with a couple of options
that look better. This one is not quite the same shape as strchr(), but it
eliminates one branch and shortens the inner loop from 5 to 4 insns...

FUNC(strrchr)
        mov     x3, #0          /* Last match, or NULL */
        sub     x0, x0, #1      /* For the pre-indexed load */
        and     w1, w1, #0xff
1:      ldrb    w2, [x0, #1]!   /* Load next byte */
        cmp     w2, w1
        csel    x3, x0, x3, eq  /* Remember match */
        cbnz    w2, 1b          /* Keep going until NUL */
        mov     x0, x3
        ret
END(strrchr)

Cheers,
Edgar

> 
> Jan
> 
> > --- a/xen/arch/arm/arm64/lib/strrchr.S
> > +++ b/xen/arch/arm/arm64/lib/strrchr.S
> > @@ -30,11 +30,10 @@ FUNC(strrchr)
> >     mov     x3, #0
> >     and     w1, w1, #0xff
> >  1: ldrb    w2, [x0], #1
> > -   cbz     w2, 2f
> >     cmp     w2, w1
> > -   b.ne    1b
> > +   b.ne    2f
> >     sub     x3, x0, #1
> > -   b       1b
> > -2: mov     x0, x3
> > +2: cbnz    w2, 1b
> > +   mov     x0, x3
> >     ret
> >  END(strrchr)
> 



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.