Skip to content

Commit 28f2021

Browse files
committed
Fix Galois field operations and add reference counting for table initialization
This commit addresses two important improvements to the RS Vandermonde implementation: 1. Type safety fix in region_multiply(): - Cast from_buf[i] to unsigned char before passing to rs_galois_mult() - Ensures correct behavior when processing signed char values in Galois field arithmetic operations - Applied to both XOR and non-XOR code paths 2. Reference counting for Galois table initialization: - Add init_counter to track multiple initialization/deinitialization calls - Prevent double initialization of log_table and ilog_table - Implement proper reference counting in rs_galois_deinit_tables() to only free tables when all references are released - Set pointers to NULL after freeing to prevent use-after-free issues These changes improve robustness and prevent potential crashes from improper table lifecycle management.
1 parent f91c1b2 commit 28f2021

File tree

2 files changed

+26
-12
lines changed

2 files changed

+26
-12
lines changed

src/builtin/rs_vand/liberasurecode_rs_vand.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ void region_multiply(char *from_buf, char *to_buf, int mult, int xor, int blocks
370370

371371
if (trailing_bytes == 1) {
372372
i = blocksize - 1;
373-
to_buf[i] = to_buf[i] ^ (char)rs_galois_mult(from_buf[i], mult);
373+
to_buf[i] = to_buf[i] ^ (char)rs_galois_mult((unsigned char)from_buf[i], mult);
374374
}
375375
} else {
376376
for (i = 0; i < adj_blocksize; i++) {
@@ -379,7 +379,7 @@ void region_multiply(char *from_buf, char *to_buf, int mult, int xor, int blocks
379379

380380
if (trailing_bytes == 1) {
381381
i = blocksize - 1;
382-
to_buf[i] = (char)rs_galois_mult(from_buf[i], mult);
382+
to_buf[i] = (char)rs_galois_mult((unsigned char)from_buf[i], mult);
383383
}
384384
}
385385
}

src/builtin/rs_vand/rs_galois.c

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,31 +44,45 @@
4444
int *log_table = NULL;
4545
int *ilog_table = NULL;
4646
int *ilog_table_begin = NULL;
47+
static int init_counter = 0;
4748

48-
void rs_galois_init_tables()
49-
{
50-
log_table = (int*)malloc(sizeof(int)*FIELD_SIZE);
51-
ilog_table_begin = (int*)malloc(sizeof(int)*FIELD_SIZE*3);
49+
void rs_galois_init_tables() {
50+
if (init_counter++ > 0) {
51+
/* already initialized */
52+
return;
53+
}
54+
log_table = (int *)malloc(sizeof(int) * FIELD_SIZE);
55+
ilog_table_begin = (int *)malloc(sizeof(int) * FIELD_SIZE * 3);
5256
int i = 0;
5357
int x = 1;
5458

5559
for (i = 0; i < GROUP_SIZE; i++) {
5660
log_table[x] = i;
5761
ilog_table_begin[i] = x;
5862
ilog_table_begin[i + GROUP_SIZE] = x;
59-
ilog_table_begin[i + (GROUP_SIZE*2)] = x;
63+
ilog_table_begin[i + (GROUP_SIZE * 2)] = x;
6064
x = x << 1;
6165
if (x & FIELD_SIZE) {
62-
x ^= PRIM_POLY;
66+
x ^= PRIM_POLY;
6367
}
6468
}
6569
ilog_table = &ilog_table_begin[GROUP_SIZE];
6670
}
6771

68-
void rs_galois_deinit_tables()
69-
{
70-
free(log_table);
71-
free(ilog_table_begin);
72+
void rs_galois_deinit_tables() {
73+
init_counter--;
74+
if (init_counter < 0) {
75+
/* deinit when not initialized?? */
76+
init_counter = 0;
77+
} else if (init_counter > 0) {
78+
/* still at least one desc using it */
79+
return;
80+
} else {
81+
free(log_table);
82+
log_table = NULL;
83+
free(ilog_table_begin);
84+
ilog_table_begin = NULL;
85+
}
7286
}
7387

7488
int rs_galois_mult(int x, int y)

0 commit comments

Comments
 (0)