From bc4fc0422cab06f9dd1295a632392c6677d08137 Mon Sep 17 00:00:00 2001 From: mgondan Date: Mon, 17 Jun 2024 22:13:07 +0200 Subject: [PATCH 01/16] Avoid UBSAN error index -1 out of bounds for type 'definition_ref[7]' --- src/pl-thread.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/pl-thread.c b/src/pl-thread.c index cd5d7e93e5..0142fd5d4e 100644 --- a/src/pl-thread.c +++ b/src/pl-thread.c @@ -8138,9 +8138,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 From c9ac0b42755685417760885c12f78c30de802978 Mon Sep 17 00:00:00 2001 From: mgondan Date: Mon, 17 Jun 2024 22:32:07 +0200 Subject: [PATCH 02/16] Avoid UBSAN error index -1 out of bounds for type 'definition_ref[7]' --- src/pl-thread.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/pl-thread.c b/src/pl-thread.c index 0142fd5d4e..0bb77820c8 100644 --- a/src/pl-thread.c +++ b/src/pl-thread.c @@ -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; } From f2b7ecf401118ee155a04f6963f0f81ae9d2585c Mon Sep 17 00:00:00 2001 From: mgondan Date: Mon, 17 Jun 2024 22:38:50 +0200 Subject: [PATCH 03/16] Avoid UBSAN in start + offset addition of unsigned offset to 0x7f6d6eb33000 overflowed to 0x7f6d6eb32fff --- src/pl-zip.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pl-zip.c b/src/pl-zip.c index 77739a7b50..24659b549e 100644 --- a/src/pl-zip.c +++ b/src/pl-zip.c @@ -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; From 3d0811a76b17aedb0c75e1633dd286475e87cbf9 Mon Sep 17 00:00:00 2001 From: mgondan Date: Mon, 17 Jun 2024 22:49:53 +0200 Subject: [PATCH 04/16] Avoid UBSAN error applying non-zero offset 64 to null pointer --- src/pl-incl.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pl-incl.h b/src/pl-incl.h index 227bb8c889..0b5615e917 100644 --- a/src/pl-incl.h +++ b/src/pl-incl.h @@ -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)) @@ -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)) From cb965ba34aa1ae7763c33558a807a26072be6c0b Mon Sep 17 00:00:00 2001 From: mgondan Date: Mon, 17 Jun 2024 23:03:05 +0200 Subject: [PATCH 05/16] Avoid UBSAN error applying non-zero offset 8864 to null pointer (from incrementing NULL with ++) --- src/pl-builtin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pl-builtin.h b/src/pl-builtin.h index e35dfae8a9..69a8fef8e3 100644 --- a/src/pl-builtin.h +++ b/src/pl-builtin.h @@ -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 From f92159914f6925119523baf68f4c84f4116a78b3 Mon Sep 17 00:00:00 2001 From: mgondan Date: Mon, 17 Jun 2024 23:23:39 +0200 Subject: [PATCH 06/16] Avoid UBSAN error index -1 out of bounds for type 'definition_ref[7]' --- src/pl-qlf.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/pl-qlf.c b/src/pl-qlf.c index c9a630b459..08596fa25e 100644 --- a/src/pl-qlf.c +++ b/src/pl-qlf.c @@ -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; From 77c5b3f6749736face3cdd78354ab47cb8575515 Mon Sep 17 00:00:00 2001 From: mgondan Date: Mon, 17 Jun 2024 23:55:51 +0200 Subject: [PATCH 07/16] Avoid UBSAN error member access within null pointer of type 'struct clause' --- src/pl-incl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pl-incl.h b/src/pl-incl.h index 0b5615e917..ecc3b13037 100644 --- a/src/pl-incl.h +++ b/src/pl-incl.h @@ -1407,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) ((char *)&((Clause)8)->codes[n] - (char *)((Clause)8)) struct clause { Definition predicate; /* Predicate I belong to */ From 0760e79cb7481425b063494dadfbb1ee448fab5e Mon Sep 17 00:00:00 2001 From: mgondan Date: Tue, 18 Jun 2024 00:01:05 +0200 Subject: [PATCH 08/16] Avoid UBSAN error applying non-zero offset 64 to null pointer --- src/pl-comp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pl-comp.c b/src/pl-comp.c index 51e0068a41..9d4e55dde6 100644 --- a/src/pl-comp.c +++ b/src/pl-comp.c @@ -2083,7 +2083,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) ) From 74e78d3066df529c1a7ae15c5ec8f522c36e1638 Mon Sep 17 00:00:00 2001 From: mgondan Date: Tue, 18 Jun 2024 00:09:46 +0200 Subject: [PATCH 09/16] Avoid UBSAN error (please check) member access within null pointer of type 'var_table' --- src/pl-comp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pl-comp.c b/src/pl-comp.c index 9d4e55dde6..de834b0201 100644 --- a/src/pl-comp.c +++ b/src/pl-comp.c @@ -366,7 +366,7 @@ typedef struct } var_table, *VarTable; #undef struct_offsetp -#define struct_offsetp(t, f) ((size_t)((t*)0)->f) +#define struct_offsetp(t, f) ((size_t)((t*)4)->f - (size_t)((t*)4)) #define sizeofVarTable(isize) (struct_offsetp(var_table, entry) + sizeof(int)*(isize)) #define mkCopiedVarTable(o) copyVarTable(alloca(sizeofVarTable(o->isize)), o) From 3c52f74f009d15fdf2560b79ef49aacd479af31e Mon Sep 17 00:00:00 2001 From: mgondan Date: Tue, 18 Jun 2024 00:17:22 +0200 Subject: [PATCH 10/16] Avoid UBSAN error (please check) member access within null pointer of type 'struct bit_vector' --- src/pl-inline.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pl-inline.h b/src/pl-inline.h index 6d3ac186ba..bdbc88c9f8 100644 --- a/src/pl-inline.h +++ b/src/pl-inline.h @@ -417,7 +417,7 @@ typedef struct bit_vector #define BITSPERE (sizeof(bitv_chunk)*8) #ifndef offset -#define offset(s, f) ((size_t)(&((struct s *)NULL)->f)) +#define offset(s, f) ((size_t)(&((struct s *)256)->f) - (size_t)((struct s *)256)) #endif static inline size_t From ff57794fd77200c4137aa936bb2afe6c1dffeb6c Mon Sep 17 00:00:00 2001 From: mgondan Date: Sun, 23 Jun 2024 16:09:23 +0200 Subject: [PATCH 11/16] Avoid UBSAN error If stack->top is NULL, switch to else branch --- src/pl-segstack.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pl-segstack.c b/src/pl-segstack.c index e0333a245b..0b683dc812 100644 --- a/src/pl-segstack.c +++ b/src/pl-segstack.c @@ -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 ) @@ -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); From 8981f38101b9b14013236d3549832a18a59a40b6 Mon Sep 17 00:00:00 2001 From: mgondan Date: Sun, 23 Jun 2024 16:10:56 +0200 Subject: [PATCH 12/16] Avoid UBSAN error (please check) If stack->top is NULL, switch to ":" branch --- src/pl-segstack.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pl-segstack.h b/src/pl-segstack.h index 50ebb34507..fb5c73ac92 100644 --- a/src/pl-segstack.h +++ b/src/pl-segstack.h @@ -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 \ @@ -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 \ From de534f6ffda3e1c4f8d8611f7afee1a7d7fe90fb Mon Sep 17 00:00:00 2001 From: mgondan Date: Tue, 9 Jul 2024 07:43:29 +0200 Subject: [PATCH 13/16] Update pl-comp.c (offsetof) I understand that offsetof is available since C99, so I don't check for it. --- src/pl-comp.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pl-comp.c b/src/pl-comp.c index de834b0201..a03f702543 100644 --- a/src/pl-comp.c +++ b/src/pl-comp.c @@ -365,9 +365,7 @@ typedef struct unsigned int entry[1]; } var_table, *VarTable; -#undef struct_offsetp -#define struct_offsetp(t, f) ((size_t)((t*)4)->f - (size_t)((t*)4)) -#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) From 667056762b8ebbc78658977b3c4dcd1ad41e6e80 Mon Sep 17 00:00:00 2001 From: mgondan Date: Tue, 9 Jul 2024 10:22:46 +0200 Subject: [PATCH 14/16] Update pl-incl.h (offsetof) --- src/pl-incl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pl-incl.h b/src/pl-incl.h index ecc3b13037..104f6e6657 100644 --- a/src/pl-incl.h +++ b/src/pl-incl.h @@ -1407,7 +1407,7 @@ behalf of I_USERCALL. This is verified in an assertion in checkCodeTable(). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#define sizeofClause(n) ((char *)&((Clause)8)->codes[n] - (char *)((Clause)8)) +#define sizeofClause(n) (offsetof(struct clause, codes[n])) struct clause { Definition predicate; /* Predicate I belong to */ From 5316379c223c405dc865a4dba57c94e687e8db3c Mon Sep 17 00:00:00 2001 From: mgondan Date: Tue, 9 Jul 2024 11:24:29 +0200 Subject: [PATCH 15/16] Update pl-inline.h (offsetof) --- src/pl-inline.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/pl-inline.h b/src/pl-inline.h index bdbc88c9f8..0e95b098c7 100644 --- a/src/pl-inline.h +++ b/src/pl-inline.h @@ -416,18 +416,14 @@ typedef struct bit_vector } bit_vector; #define BITSPERE (sizeof(bitv_chunk)*8) -#ifndef offset -#define offset(s, f) ((size_t)(&((struct s *)256)->f) - (size_t)((struct s *)256)) -#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; @@ -435,7 +431,7 @@ init_bitvector(bit_vector *v, size_t 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); @@ -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); } From b0dd5c1b972694c7a1c84c9d612423c863b47020 Mon Sep 17 00:00:00 2001 From: mgondan Date: Tue, 9 Jul 2024 11:28:32 +0200 Subject: [PATCH 16/16] Update pl-segstack.h (remove blank) --- src/pl-segstack.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pl-segstack.h b/src/pl-segstack.h index fb5c73ac92..1d4d75841f 100644 --- a/src/pl-segstack.h +++ b/src/pl-segstack.h @@ -86,7 +86,7 @@ emptySegStack(segstack *s) ) #define pushSegStack(stack, data, type) \ - ( ((stack)-> top && (stack)->top + sizeof(type) <= (stack)->max) \ + ( ((stack)->top && (stack)->top + sizeof(type) <= (stack)->max) \ ? ( *(type*)(stack)->top = data, \ (stack)->top += sizeof(type), \ TRUE \