Skip to content

Commit b0a8dc2

Browse files
committed
Disable UBSAN for alignment-sensitive functions when !CAREFUL_ALIGNMENT
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
1 parent 90df93e commit b0a8dc2

File tree

2 files changed

+29
-6
lines changed

2 files changed

+29
-6
lines changed

byteorder.h

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,34 @@ SIVAL64(char *buf, int pos, int64 val)
6868

6969
#else /* !CAREFUL_ALIGNMENT */
7070

71+
/* We don't want false positives about alignment from UBSAN, see:
72+
https://github.com/WayneD/rsync/issues/427#issuecomment-1375132291
73+
*/
74+
75+
/* From https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html */
76+
#ifndef GCC_VERSION
77+
#define GCC_VERSION (__GNUC__ * 10000 \
78+
+ __GNUC_MINOR__ * 100 \
79+
+ __GNUC_PATCHLEVEL__)
80+
#endif
81+
82+
#ifndef RSYNC_NO_UBSAN_ATTR
83+
# ifdef CAREFUL_ALIGNMENT
84+
# ifdef __clang__
85+
# define RSYNC_NO_UBSAN_ATTR __attribute__((no_sanitize("undefined")))
86+
# elif GCC_VERSION >= 409
87+
# define RSYNC_NO_UBSAN_ATTR __attribute__((no_sanitize_undefined))
88+
# endif
89+
# else
90+
# define RSYNC_NO_UBSAN_ATTR
91+
# endif
92+
#endif
93+
7194
/* This handles things for architectures like the 386 that can handle alignment errors.
7295
* WARNING: This section is dependent on the length of an int32 (and thus a uint32)
7396
* being correct (4 bytes)! Set CAREFUL_ALIGNMENT if it is not. */
7497

75-
static inline uint32
98+
RSYNC_NO_UBSAN_ATTR static inline uint32
7699
IVALu(const uchar *buf, int pos)
77100
{
78101
union {
@@ -83,7 +106,7 @@ IVALu(const uchar *buf, int pos)
83106
return *u.num;
84107
}
85108

86-
static inline void
109+
RSYNC_NO_UBSAN_ATTR static inline void
87110
SIVALu(uchar *buf, int pos, uint32 val)
88111
{
89112
union {
@@ -94,7 +117,7 @@ SIVALu(uchar *buf, int pos, uint32 val)
94117
*u.num = val;
95118
}
96119

97-
static inline int64
120+
RSYNC_NO_UBSAN_ATTR static inline int64
98121
IVAL64(const char *buf, int pos)
99122
{
100123
union {
@@ -105,7 +128,7 @@ IVAL64(const char *buf, int pos)
105128
return *u.num;
106129
}
107130

108-
static inline void
131+
RSYNC_NO_UBSAN_ATTR static inline void
109132
SIVAL64(char *buf, int pos, int64 val)
110133
{
111134
union {

io.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1791,7 +1791,7 @@ uint32 read_uint(int f)
17911791
return IVAL(b, 0);
17921792
}
17931793

1794-
int32 read_varint(int f)
1794+
RSYNC_NO_UBSAN_ATTR int32 read_varint(int f)
17951795
{
17961796
union {
17971797
char b[5];
@@ -1823,7 +1823,7 @@ int32 read_varint(int f)
18231823
return u.x;
18241824
}
18251825

1826-
int64 read_varlong(int f, uchar min_bytes)
1826+
RSYNC_NO_UBSAN_ATTR int64 read_varlong(int f, uchar min_bytes)
18271827
{
18281828
union {
18291829
char b[9];

0 commit comments

Comments
 (0)