Skip to content

Commit

Permalink
Disable UBSAN for alignment-sensitive functions when !CAREFUL_ALIGNMENT
Browse files Browse the repository at this point in the history
rsync sets CAREFUL_ALIGNMENT for architectures which do not support
unaligned access. Disable UBSAN for functions which may use unaligned
accesses when CAREFUL_ALIGNMENT is set.

Bug: #427
Signed-off-by: Sam James <[email protected]>
  • Loading branch information
thesamesam committed Jan 9, 2023
1 parent 90df93e commit d520c80
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
31 changes: 31 additions & 0 deletions byteorder.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,26 @@ SIVAL64(char *buf, int pos, int64 val)

#else /* !CAREFUL_ALIGNMENT */

/* We don't want false positives about alignment from UBSAN, see:
https://github.com/WayneD/rsync/issues/427#issuecomment-1375132291
*/

/* From https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html */
#ifndef GCC_VERSION
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
#endif

/* This handles things for architectures like the 386 that can handle alignment errors.
* WARNING: This section is dependent on the length of an int32 (and thus a uint32)
* being correct (4 bytes)! Set CAREFUL_ALIGNMENT if it is not. */

#ifdef __clang__
__attribute__((no_sanitize("undefined")))
#elif GCC_VERSION >= 409
__attribute__((no_sanitize_undefined))
#endif
static inline uint32
IVALu(const uchar *buf, int pos)
{
Expand All @@ -83,6 +99,11 @@ IVALu(const uchar *buf, int pos)
return *u.num;
}

#ifdef __clang__
__attribute__((no_sanitize("undefined")))
#elif GCC_VERSION >= 409
__attribute__((no_sanitize_undefined))
#endif
static inline void
SIVALu(uchar *buf, int pos, uint32 val)
{
Expand All @@ -94,6 +115,11 @@ SIVALu(uchar *buf, int pos, uint32 val)
*u.num = val;
}

#ifdef __clang__
__attribute__((no_sanitize("undefined")))
#elif GCC_VERSION >= 409
__attribute__((no_sanitize_undefined))
#endif
static inline int64
IVAL64(const char *buf, int pos)
{
Expand All @@ -105,6 +131,11 @@ IVAL64(const char *buf, int pos)
return *u.num;
}

#ifdef __clang__
__attribute__((no_sanitize("undefined")))
#elif GCC_VERSION >= 409
__attribute__((no_sanitize_undefined))
#endif
static inline void
SIVAL64(char *buf, int pos, int64 val)
{
Expand Down
10 changes: 10 additions & 0 deletions io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1791,6 +1791,11 @@ uint32 read_uint(int f)
return IVAL(b, 0);
}

#ifdef __clang__
__attribute__((no_sanitize("undefined")))
#elif GCC_VERSION >= 409
__attribute__((no_sanitize_undefined))
#endif
int32 read_varint(int f)
{
union {
Expand Down Expand Up @@ -1823,6 +1828,11 @@ int32 read_varint(int f)
return u.x;
}

#ifdef __clang__
__attribute__((no_sanitize("undefined")))
#elif GCC_VERSION >= 409
__attribute__((no_sanitize_undefined))
#endif
int64 read_varlong(int f, uchar min_bytes)
{
union {
Expand Down

0 comments on commit d520c80

Please sign in to comment.