Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENHANCE: Avoid UBSAN errors #1289

Closed
wants to merge 16 commits into from
2 changes: 1 addition & 1 deletion src/pl-builtin.h
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ extern PL_local_data_t* no_local_ld(void);
#define WITH_LD(ld) \
for (PL_local_data_t *__PL_ld = (ld), *__loopctr = NULL; \
!__loopctr; \
__loopctr++)
__loopctr = (PL_local_data_t*) 1)
/* Passing an alternate LD to a called function. This uses the same mechanism
* as DECL_LD, but takes it one step further. _VE_PASSLD below is a macro that
* does not exist, but when DECL_LDFUNC() pastes __VOID_EMPTY_ to the beginning
Expand Down
6 changes: 2 additions & 4 deletions src/pl-comp.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,7 @@ typedef struct
unsigned int entry[1];
} var_table, *VarTable;

#undef struct_offsetp
#define struct_offsetp(t, f) ((size_t)((t*)0)->f)
#define sizeofVarTable(isize) (struct_offsetp(var_table, entry) + sizeof(int)*(isize))
#define sizeofVarTable(isize) (offsetof(var_table, entry) + sizeof(int)*(isize))

#define mkCopiedVarTable(o) copyVarTable(alloca(sizeofVarTable(o->isize)), o)
#define BITSPERINT (int)(sizeof(int)*8)
Expand Down Expand Up @@ -2083,7 +2081,7 @@ Finish up the clause.
sizeofClause(clause.code_size) +
SIZEOF_CREF_CLAUSE +
sizeof(uintptr_t)*2 + /* possible alignment */
(size_t)argFrameP((LocalFrame)NULL, MAXARITY) +
(size_t)argFrameP0(LocalFrame, MAXARITY) +
sizeof(struct choice)
);
if ( !hasLocalSpace(space) )
Expand Down
5 changes: 3 additions & 2 deletions src/pl-incl.h
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ them. Descriptions:
#define SMALLSTACK 32 * 1024 /* GC policy */
#define MAX_PORTRAY_NESTING 100 /* Max recursion in portray */

#define LOCAL_MARGIN ((size_t)argFrameP((LocalFrame)NULL, MAXARITY) + \
#define LOCAL_MARGIN ((size_t)argFrameP0(LocalFrame, MAXARITY) + \
sizeof(struct choice))

#define WORDBITSIZE (8 * sizeof(word))
Expand Down Expand Up @@ -1148,6 +1148,7 @@ Macros for environment frames (local stack frames)

#define setLevelFrame(fr, l) do { (fr)->level = (l); } while(0)
#define levelFrame(fr) ((fr)->level)
#define argFrameP0(t, n) ((Word)((t)1) + (n))
#define argFrameP(f, n) ((Word)((f)+1) + (n))
#define argFrame(f, n) (*argFrameP((f), (n)) )
#define varFrameP(f, n) ((Word)(f) + (n))
Expand Down Expand Up @@ -1406,7 +1407,7 @@ behalf of I_USERCALL. This is verified in an assertion in
checkCodeTable().
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#define sizeofClause(n) ((char *)&((Clause)NULL)->codes[n] - (char *)NULL)
#define sizeofClause(n) (offsetof(struct clause, codes[n]))

struct clause
{ Definition predicate; /* Predicate I belong to */
Expand Down
12 changes: 4 additions & 8 deletions src/pl-inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,26 +416,22 @@ typedef struct bit_vector
} bit_vector;
#define BITSPERE (sizeof(bitv_chunk)*8)

#ifndef offset
#define offset(s, f) ((size_t)(&((struct s *)NULL)->f))
#endif

static inline size_t
sizeof_bitvector(size_t bits)
{ return offset(bit_vector, chunk[(bits+BITSPERE-1)/BITSPERE]);
{ return offsetof(struct bit_vector, chunk[(bits+BITSPERE-1)/BITSPERE]);
}

static inline void
init_bitvector(bit_vector *v, size_t bits)
{ size_t bytes = offset(bit_vector, chunk[(bits+BITSPERE-1)/BITSPERE]);
{ size_t bytes = offsetof(struct bit_vector, chunk[(bits+BITSPERE-1)/BITSPERE]);

memset(v, 0, bytes);
v->size = bits;
}

static inline bit_vector *
new_bitvector(size_t size)
{ size_t bytes = offset(bit_vector, chunk[(size+BITSPERE-1)/BITSPERE]);
{ size_t bytes = offsetof(struct bit_vector, chunk[(size+BITSPERE-1)/BITSPERE]);
bit_vector *v = allocHeapOrHalt(bytes);

memset(v, 0, bytes);
Expand All @@ -445,7 +441,7 @@ new_bitvector(size_t size)

static inline void
free_bitvector(bit_vector *v)
{ size_t bytes = offset(bit_vector, chunk[(v->size+BITSPERE-1)/BITSPERE]);
{ size_t bytes = offsetof(struct bit_vector, chunk[(v->size+BITSPERE-1)/BITSPERE]);

freeHeap(v, bytes);
}
Expand Down
11 changes: 8 additions & 3 deletions src/pl-qlf.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,14 @@ pushXrIdTable(wic_state *state)

memset(t, 0, sizeof(*t));
t->id = 0;
t->blocks[0] = t->preallocated - 1;
t->blocks[1] = t->preallocated - 1;
t->blocks[2] = t->preallocated - 1;
t->blocks[0] = t->preallocated;
t->blocks[1] = t->preallocated;
t->blocks[2] = t->preallocated;

/* avoid UBSAN error */
t->blocks[0]--;
t->blocks[1]--;
t->blocks[2]--;

t->previous = state->XR;
state->XR = t;
Expand Down
4 changes: 2 additions & 2 deletions src/pl-segstack.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ next_chunk_size(segstack *stack)

void *
pushSegStack_(segstack *stack, void *data)
{ if ( stack->top + stack->unit_size <= stack->max )
{ if ( stack->top && stack->top + stack->unit_size <= stack->max )
{ char *ptr = stack->top;

if ( data )
Expand Down Expand Up @@ -134,7 +134,7 @@ int
popSegStack_(segstack *stack, void *data)
{ again:

if ( stack->top >= stack->base + stack->unit_size )
if ( stack->top && stack->top >= stack->base + stack->unit_size )
{ stack->top -= stack->unit_size;
if ( data )
memcpy(data, stack->top, stack->unit_size);
Expand Down
4 changes: 2 additions & 2 deletions src/pl-segstack.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ emptySegStack(segstack *s)


#define popSegStack(stack, to, type) \
( ((stack)->top >= (stack)->base + sizeof(type)) \
( ((stack)->top && (stack)->top >= (stack)->base + sizeof(type)) \
? ( (stack)->top -= sizeof(type), \
*to = *(type*)(stack)->top, \
TRUE \
Expand All @@ -86,7 +86,7 @@ emptySegStack(segstack *s)
)

#define pushSegStack(stack, data, type) \
( ((stack)->top + sizeof(type) <= (stack)->max) \
( ((stack)->top && (stack)->top + sizeof(type) <= (stack)->max) \
? ( *(type*)(stack)->top = data, \
(stack)->top += sizeof(type), \
TRUE \
Expand Down
21 changes: 14 additions & 7 deletions src/pl-thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -7591,10 +7591,12 @@ new_ldef_vector(void)
{ LocalDefinitions f = allocHeapOrHalt(sizeof(*f));

memset(f, 0, sizeof(*f));
f->blocks[0] = f->preallocated - 1;
f->blocks[1] = f->preallocated - 1;
f->blocks[2] = f->preallocated - 1;

f->blocks[0] = f->preallocated;
f->blocks[1] = f->preallocated;
f->blocks[2] = f->preallocated;
f->blocks[0]--;
f->blocks[1]--;
f->blocks[2]--;
return f;
}

Expand Down Expand Up @@ -8138,9 +8140,14 @@ init_predicate_references(PL_local_data_t *ld)
{ definition_refs *refs = &ld->predicate_references;

memset(refs, 0, sizeof(*refs));
refs->blocks[0] = refs->preallocated - 1;
refs->blocks[1] = refs->preallocated - 1;
refs->blocks[2] = refs->preallocated - 1;
refs->blocks[0] = refs->preallocated;
refs->blocks[1] = refs->preallocated;
refs->blocks[2] = refs->preallocated;

/* subtract later to avoid UBSAN error */
refs->blocks[0]--;
refs->blocks[1]--;
refs->blocks[2]--;
}

void
Expand Down
6 changes: 6 additions & 0 deletions src/pl-zip.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,12 @@ zseek64_mem(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
{ mem_stream *mem = stream;
const char *p;

/* Avoid UBSAN in start + offset */
if ( origin == SEEK_SET && offset == (ZPOS64_T)(-1) )
{ errno = EINVAL;
return -1;
}

switch(origin)
{ case SEEK_SET: p = mem->start + offset; break;
case SEEK_CUR: p = mem->here + offset; break;
Expand Down