OpenAFS Master Repository branch, master, updated. openafs-devel-1_9_2-502-g8a43e43

Gerrit Code Review gerrit@openafs.org
Mon, 8 Jun 2026 10:41:46 -0400


The following commit has been merged in the master branch:
commit 8a43e43db789215830bd1a3dda7796037be163ee
Author: Andrew Deason <adeason@sinenomine.net>
Date:   Thu May 9 15:13:07 2024 -0500

    rx: Force signed cast in xdr_char()
    
    When encoding with xdr_char(), we cast the given char to an afs_int32
    to write it to the xdr stream. If the given char is negative, the
    resulting afs_int32 would also be negative and encoded as 0xFFFFFFFF.
    
    However, the type 'char' may be signed or unsigned, depending on the
    platform and compiler flags (this can be controlled in gcc with
    -funsigned-char and -fsigned-char). If 'char' is unsigned, a value of
    -1 given to xdr_char() will be interpreted as 255, and will be encoded
    as 0x000000FF.
    
    Whether xdr_char() encodes -1 as 0xFFFFFFFF or 0x000000FF usually does
    not matter, since xdr_char() will decode either as -1. However, some
    callers use an xdr-encoded stream for other purposes than just
    xdr-decoding it. For example, rxgk uses an xdr-encoded blob (including
    xdr_char()) as part of deriving keys during the AFSCombineTokens
    operation, and so will yield different results if any part of the
    xdr-encoded stream differs.
    
    This can cause issues when communicating between different platforms,
    but also even on the same platform just when different compiler flags
    are used. Notably, the Linux kernel uses -funsigned-char starting in
    v6.2 (commit 3bc753c06dd02a3517c9b498e3846ebfc94ac3ee), and so our
    kernel module yields different results from userspace code, even on
    the same platform.
    
    This can be seen with test failures in rx/xdr-t, but only when built
    on an unsigned-char platform, or when building with
    CFLAGS=-funsigned-char. For example:
    
        $ ./configure CFLAGS=-funsigned-char && make check TESTS='-o rx/xdr'
        [...]
        ok 462 - xdr_char(255) == 1 (encode)
        # left:
        #  4:000000ff
        # right:
        #  4:ffffffff
        not ok 463 - ... encoded buffer matches
        [...]
    
    To make it so we always encode negative char's the same way, change
    xdr_char() to force a cast to a signed char before casting to
    afs_int32, so the value is always interpreted as a signed value and -1
    gets encoded as 0xFFFFFFFF. We could force a cast to an unsigned char
    instead, but xdr_char() is clearly intended to be for signed values,
    following the pattern of our other xdr primitives and the existence of
    xdr_u_char().
    
    Rely on casting to fix this, instead of changing the actual argument
    of xdr_char(), to avoid changing a public interface and to avoid
    possibly causing other unintended changes.
    
    Add a comment with a brief explanation, to try to make sure this cast
    doesn't get removed as redundant/unnecessary.
    
    Change-Id: I87aa7e1a1047e9513f85fd54269e81c3689c5307
    Reviewed-on: https://gerrit.openafs.org/15749
    Reviewed-by: Cheyenne Wills <cwills@sinenomine.net>
    Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
    Tested-by: BuildBot <buildbot@rampaginggeek.com>
    Reviewed-by: Marcio Brito Barbosa <mbarbosa@sinenomine.net>
    Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>

 src/rx/xdr.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

-- 
OpenAFS Master Repository