Skip to content

Commit c102012

Browse files
committed
Backported CORE-6525: Segfaults in fbclient when receiving invalid / unexpected data from server
1 parent a830ea7 commit c102012

15 files changed

Lines changed: 372 additions & 422 deletions

File tree

builds/posix/prefix.linux_amd64

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
COMMON_FLAGS=-ggdb -DFB_SEND_FLAGS=MSG_NOSIGNAL -DLINUX -DAMD64 -pipe -MMD -fPIC -fmessage-length=0 -fno-delete-null-pointer-checks
2222
CXXFLAGS=-std=gnu++03
2323
OPTIMIZE_FLAGS=-O3 -fno-omit-frame-pointer
24-
WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable -Wno-invalid-offsetof -Wno-narrowing -Wno-unused-local-typedefs
24+
WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-variable -Wno-invalid-offsetof -Wno-narrowing -Wno-unused-local-typedefs -Wno-class-memaccess
2525

2626
PROD_FLAGS=$(COMMON_FLAGS) $(OPTIMIZE_FLAGS)
2727
#DEV_FLAGS=-DUSE_VALGRIND $(COMMON_FLAGS) $(WARN_FLAGS) -fmax-errors=8

src/burp/canonical.cpp

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,23 @@
4848
// conflicting blk_t definitions (we are gonna fix this, in due time).
4949

5050

51-
static bool_t burp_getbytes(XDR*, SCHAR *, unsigned);
52-
static bool_t burp_putbytes(XDR*, const SCHAR*, unsigned);
51+
struct BurpXdr : public xdr_t
52+
{
53+
virtual bool_t x_getbytes(SCHAR *, unsigned); // get some bytes from "
54+
virtual bool_t x_putbytes(const SCHAR*, unsigned); // put some bytes to "
55+
56+
BurpXdr()
57+
: x_public(NULL)
58+
{ }
59+
60+
lstring* x_public;
61+
};
62+
typedef struct BurpXdr XDR;
63+
5364
static bool_t expand_buffer(XDR*);
5465
static int xdr_init(XDR*, lstring*, enum xdr_op);
5566
static bool_t xdr_slice(XDR*, lstring*, /*USHORT,*/ const UCHAR*);
5667

57-
static xdr_t::xdr_ops burp_ops =
58-
{
59-
burp_getbytes,
60-
burp_putbytes
61-
};
62-
6368
const unsigned increment = 1024;
6469

6570

@@ -224,7 +229,7 @@ ULONG CAN_slice(lstring* buffer, lstring* slice, bool_t direction, /*USHORT sdl_
224229
}
225230

226231

227-
static bool_t burp_getbytes(XDR* xdrs, SCHAR* buff, unsigned bytecount)
232+
bool_t BurpXdr::x_getbytes(SCHAR* buff, unsigned bytecount)
228233
{
229234
/**************************************
230235
*
@@ -237,29 +242,29 @@ static bool_t burp_getbytes(XDR* xdrs, SCHAR* buff, unsigned bytecount)
237242
*
238243
**************************************/
239244

240-
if (bytecount && xdrs->x_handy >= bytecount)
245+
if (bytecount && x_handy >= bytecount)
241246
{
242-
memcpy(buff, xdrs->x_private, bytecount);
243-
xdrs->x_private += bytecount;
244-
xdrs->x_handy -= bytecount;
247+
memcpy(buff, x_private, bytecount);
248+
x_private += bytecount;
249+
x_handy -= bytecount;
245250

246251
return TRUE;
247252
}
248253

249254
while (bytecount--)
250255
{
251-
if (xdrs->x_handy == 0 && !expand_buffer(xdrs))
256+
if (x_handy == 0 && !expand_buffer(this))
252257
return FALSE;
253258

254-
*buff++ = *xdrs->x_private++;
255-
--xdrs->x_handy;
259+
*buff++ = *x_private++;
260+
--x_handy;
256261
}
257262

258263
return TRUE;
259264
}
260265

261266

262-
static bool_t burp_putbytes(XDR* xdrs, const SCHAR* buff, unsigned bytecount)
267+
bool_t BurpXdr::x_putbytes(const SCHAR* buff, unsigned bytecount)
263268
{
264269
/**************************************
265270
*
@@ -272,22 +277,22 @@ static bool_t burp_putbytes(XDR* xdrs, const SCHAR* buff, unsigned bytecount)
272277
*
273278
**************************************/
274279

275-
if (bytecount && xdrs->x_handy >= bytecount)
280+
if (bytecount && x_handy >= bytecount)
276281
{
277-
memcpy(xdrs->x_private, buff, bytecount);
278-
xdrs->x_private += bytecount;
279-
xdrs->x_handy -= bytecount;
282+
memcpy(x_private, buff, bytecount);
283+
x_private += bytecount;
284+
x_handy -= bytecount;
280285

281286
return TRUE;
282287
}
283288

284289
while (bytecount--)
285290
{
286-
if (xdrs->x_handy == 0 && !expand_buffer(xdrs))
291+
if (x_handy == 0 && !expand_buffer(this))
287292
return FALSE;
288293

289-
*xdrs->x_private++ = *buff++;
290-
--xdrs->x_handy;
294+
*x_private++ = *buff++;
295+
--x_handy;
291296
}
292297

293298
return TRUE;
@@ -308,7 +313,7 @@ static bool_t expand_buffer(XDR* xdrs)
308313
* old one.
309314
*
310315
**************************************/
311-
lstring* buffer = (lstring*) xdrs->x_public;
316+
lstring* buffer = xdrs->x_public;
312317
const unsigned usedLength = xdrs->x_private - xdrs->x_base;
313318
const unsigned length = usedLength + xdrs->x_handy + increment;
314319

@@ -341,11 +346,8 @@ static int xdr_init(XDR* xdrs, lstring* buffer, enum xdr_op x_op)
341346
*
342347
**************************************/
343348

344-
xdrs->x_public = (caddr_t) buffer;
345-
xdrs->x_base = xdrs->x_private = (caddr_t) buffer->lstr_address;
346-
xdrs->x_handy = buffer->lstr_length;
347-
xdrs->x_ops = &burp_ops;
348-
xdrs->x_op = x_op;
349+
xdrs->x_public = buffer;
350+
xdrs->create((caddr_t) buffer->lstr_address, buffer->lstr_length, x_op);
349351

350352
return TRUE;
351353
}

src/common/utils.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,8 +1550,7 @@ unsigned sqlTypeToDsc(unsigned runOffset, unsigned sqlType, unsigned sqlLength,
15501550

15511551
default:
15521552
fb_assert(false);
1553-
// keep old yvalve logic
1554-
dscType = sqlType;
1553+
Firebird::Arg::Gds(isc_dsql_datatype_err).raise();
15551554
break;
15561555
}
15571556

src/common/xdr.cpp

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#include "../yvalve/gds_proto.h"
3232
#include "../common/gdsassert.h"
3333

34+
typedef struct xdr_t XDR;
35+
3436
inline UCHAR* XDR_ALLOC(ULONG size)
3537
{
3638
return (UCHAR*) gds__alloc((SLONG) size);
@@ -66,24 +68,14 @@ inline void DEBUG_XDR_FREE(XDR*, const void*, const void*, ULONG)
6668
const unsigned MAXSTRING_FOR_WRAPSTRING = 65535;
6769

6870

69-
static bool_t mem_getbytes(XDR*, SCHAR*, unsigned);
70-
static bool_t mem_putbytes(XDR*, const SCHAR*, unsigned);
71-
72-
73-
static const XDR::xdr_ops mem_ops =
74-
{
75-
mem_getbytes,
76-
mem_putbytes
77-
};
78-
79-
#define GETBYTES (*xdrs->x_ops->x_getbytes)
80-
#define PUTBYTES (*xdrs->x_ops->x_putbytes)
71+
#define GETBYTES xdrs->x_getbytes
72+
#define PUTBYTES xdrs->x_putbytes
8173

8274
inline bool_t GETLONG(XDR* xdrs, SLONG* lp)
8375
{
8476
SLONG l;
8577

86-
if (!(*xdrs->x_ops->x_getbytes)(xdrs, reinterpret_cast<char*>(&l), 4))
78+
if (!xdrs->x_getbytes(reinterpret_cast<char*>(&l), 4))
8779
return FALSE;
8880

8981
*lp = xdrs->x_local ? l : ntohl(l);
@@ -94,7 +86,7 @@ inline bool_t GETLONG(XDR* xdrs, SLONG* lp)
9486
inline bool_t PUTLONG(XDR* xdrs, const SLONG* lp)
9587
{
9688
const SLONG l = xdrs->x_local ? *lp : htonl(*lp);
97-
return (*xdrs->x_ops->x_putbytes)(xdrs, reinterpret_cast<const char*>(&l), 4);
89+
return xdrs->x_putbytes(reinterpret_cast<const char*>(&l), 4);
9890
}
9991

10092
static SCHAR zeros[4] = { 0, 0, 0, 0 };
@@ -484,17 +476,17 @@ bool_t xdr_opaque(XDR* xdrs, SCHAR* p, unsigned len)
484476
switch (xdrs->x_op)
485477
{
486478
case XDR_ENCODE:
487-
if (!PUTBYTES(xdrs, p, len))
479+
if (!PUTBYTES(p, len))
488480
return FALSE;
489481
if (l)
490-
return PUTBYTES(xdrs, filler, l);
482+
return PUTBYTES(filler, l);
491483
return TRUE;
492484

493485
case XDR_DECODE:
494-
if (!GETBYTES(xdrs, p, len))
486+
if (!GETBYTES(p, len))
495487
return FALSE;
496488
if (l)
497-
return GETBYTES(xdrs, trash, l);
489+
return GETBYTES(trash, l);
498490
return TRUE;
499491

500492
case XDR_FREE:
@@ -601,12 +593,12 @@ bool_t xdr_string(XDR* xdrs, SCHAR** sp, unsigned maxlength)
601593
length = static_cast<ULONG>(strlen(*sp));
602594
if (length > maxlength ||
603595
!PUTLONG(xdrs, reinterpret_cast<SLONG*>(&length)) ||
604-
!PUTBYTES(xdrs, *sp, length))
596+
!PUTBYTES(*sp, length))
605597
{
606598
return FALSE;
607599
}
608600
if ((length = (4 - length) & 3) != 0)
609-
return PUTBYTES(xdrs, filler, length);
601+
return PUTBYTES(filler, length);
610602
return TRUE;
611603

612604
case XDR_DECODE:
@@ -619,13 +611,13 @@ bool_t xdr_string(XDR* xdrs, SCHAR** sp, unsigned maxlength)
619611
DEBUG_XDR_ALLOC(xdrs, sp, *sp, (maxlength + 1));
620612
}
621613
if (!GETLONG(xdrs, reinterpret_cast<SLONG*>(&length)) ||
622-
length > maxlength || !GETBYTES(xdrs, *sp, length))
614+
length > maxlength || !GETBYTES(*sp, length))
623615
{
624616
return FALSE;
625617
}
626618
(*sp)[length] = 0;
627619
if ((length = (4 - length) & 3) != 0)
628-
return GETBYTES(xdrs, trash, length);
620+
return GETBYTES(trash, length);
629621
return TRUE;
630622

631623
case XDR_FREE:
@@ -759,7 +751,7 @@ bool_t xdr_wrapstring(XDR* xdrs, SCHAR** strp)
759751
}
760752

761753

762-
int xdrmem_create( XDR* xdrs, SCHAR* addr, unsigned len, xdr_op x_op)
754+
int xdr_t::create(SCHAR* addr, unsigned len, xdr_op op)
763755
{
764756
/**************************************
765757
*
@@ -772,16 +764,14 @@ int xdrmem_create( XDR* xdrs, SCHAR* addr, unsigned len, xdr_op x_op)
772764
*
773765
**************************************/
774766

775-
xdrs->x_base = xdrs->x_private = addr;
776-
xdrs->x_handy = len;
777-
xdrs->x_ops = &mem_ops;
778-
xdrs->x_op = x_op;
767+
x_base = x_private = addr;
768+
x_handy = len;
769+
x_op = op;
779770

780771
return TRUE;
781772
}
782773

783-
784-
static bool_t mem_getbytes( XDR* xdrs, SCHAR* buff, unsigned bytecount)
774+
bool_t xdr_t::x_getbytes(SCHAR* buff, unsigned bytecount)
785775
{
786776
/**************************************
787777
*
@@ -793,14 +783,14 @@ static bool_t mem_getbytes( XDR* xdrs, SCHAR* buff, unsigned bytecount)
793783
* Get a bunch of bytes from a memory stream if it fits.
794784
*
795785
**************************************/
796-
if (xdrs->x_handy < bytecount)
786+
if (x_handy < bytecount)
797787
return FALSE;
798788

799789
if (bytecount)
800790
{
801-
memcpy(buff, xdrs->x_private, bytecount);
802-
xdrs->x_private += bytecount;
803-
xdrs->x_handy -= bytecount;
791+
memcpy(buff, x_private, bytecount);
792+
x_private += bytecount;
793+
x_handy -= bytecount;
804794
}
805795

806796
return TRUE;
@@ -828,7 +818,7 @@ SLONG xdr_peek_long(const XDR* xdrs, const void* data, size_t size)
828818
}
829819

830820

831-
static bool_t mem_putbytes(XDR* xdrs, const SCHAR* buff, unsigned bytecount)
821+
bool_t xdr_t::x_putbytes(const SCHAR* buff, unsigned bytecount)
832822
{
833823
/**************************************
834824
*
@@ -840,15 +830,19 @@ static bool_t mem_putbytes(XDR* xdrs, const SCHAR* buff, unsigned bytecount)
840830
* Put a bunch of bytes to a memory stream if it fits.
841831
*
842832
**************************************/
843-
if (xdrs->x_handy < bytecount)
833+
if (x_handy < bytecount)
844834
return FALSE;
845835

846836
if (bytecount)
847837
{
848-
memcpy(xdrs->x_private, buff, bytecount);
849-
xdrs->x_private += bytecount;
850-
xdrs->x_handy -= bytecount;
838+
memcpy(x_private, buff, bytecount);
839+
x_private += bytecount;
840+
x_handy -= bytecount;
851841
}
852842

853843
return TRUE;
854844
}
845+
846+
xdr_t::~xdr_t()
847+
{ }
848+

src/common/xdr.h

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
*
2727
*/
2828

29-
#ifndef REMOTE_XDR_H
30-
#define REMOTE_XDR_H
29+
#ifndef COMMON_XDR_H
30+
#define COMMON_XDR_H
3131

3232
#include <sys/types.h>
3333
#ifdef WIN_NT
@@ -49,32 +49,23 @@ typedef int bool_t;
4949

5050
enum xdr_op { XDR_ENCODE = 0, XDR_DECODE = 1, XDR_FREE = 2 };
5151

52-
typedef struct xdr_t
52+
struct xdr_t
5353
{
54-
xdr_op x_op; // operation; fast additional param
55-
struct xdr_ops
56-
{
57-
bool_t (*x_getbytes)(struct xdr_t*, SCHAR *, unsigned); // get some bytes from "
58-
bool_t (*x_putbytes)(struct xdr_t*, const SCHAR*, unsigned); // put some bytes to "
59-
} const *x_ops;
60-
caddr_t x_public; // Users' data
54+
virtual bool_t x_getbytes(SCHAR *, unsigned); // get some bytes from "
55+
virtual bool_t x_putbytes(const SCHAR*, unsigned); // put some bytes to "
56+
virtual ~xdr_t();
57+
58+
xdr_op x_op; // operation; fast additional param
6159
caddr_t x_private; // pointer to private data
6260
caddr_t x_base; // private used for position info
6361
unsigned x_handy; // extra private word
6462
bool x_local; // transmission is known to be local (bytes are in the host order)
65-
#ifdef DEV_BUILD
66-
bool x_client; // set this flag to true if this is client port
67-
#endif
6863

69-
public:
7064
xdr_t() :
71-
x_op(XDR_ENCODE), x_ops(0), x_public(0), x_private(0), x_base(0), x_handy(0),
72-
x_local(false)
73-
#ifdef DEV_BUILD
74-
, x_client(false)
75-
#endif
65+
x_op(XDR_ENCODE), x_private(0), x_base(0), x_handy(0), x_local(false)
7666
{ }
77-
} XDR;
7867

68+
int create(SCHAR* addr, unsigned len, xdr_op op);
69+
};
7970

80-
#endif // REMOTE_XDR_H
71+
#endif // COMMON_XDR_H

0 commit comments

Comments
 (0)