Skip to content

Commit a62e190

Browse files
committed
Fix DATA_FORMAT printf/scanf for 32-bit archs with 64-bit off_t off_t
On 32-bit architectures built with _FILE_OFFSET_BITS=64, off_t is 64-bit but size_t is 32-bit. Using %zu for an off_t field causes scanf to write only 4 bytes into an 8-byte off_t, corrupting the upper half. Switch to %llu with explicit casts throughout.
1 parent 6934d06 commit a62e190

9 files changed

Lines changed: 43 additions & 38 deletions

File tree

src/cli/fapolicyd-cli.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ static int do_dump_db(void)
249249
do {
250250
char *path = NULL, *data = NULL, sha[FILE_DIGEST_STRING_MAX];
251251
unsigned int tsource;
252-
size_t size;
252+
unsigned long long ull_size;
253253
const char *source;
254254

255255
path = malloc(key.mv_size + 1);
@@ -266,11 +266,11 @@ static int do_dump_db(void)
266266
memcpy(data, val.mv_data, val.mv_size);
267267
data[val.mv_size] = 0;
268268

269-
if (sscanf(data, DATA_FORMAT_IN, &tsource, &size, sha) != 3)
269+
if (sscanf(data, DATA_FORMAT_IN, &tsource, &ull_size, sha) != 3)
270270
goto next_record;
271271

272272
source = lookup_tsource(tsource);
273-
printf("%s %s %zu %s\n", source, path, size, sha);
273+
printf("%s %s %llu %s\n", source, path, ull_size, sha);
274274

275275
next_record:
276276
free(data);
@@ -826,6 +826,7 @@ static int check_trustdb(void)
826826
do {
827827
unsigned int tsource;
828828
off_t size;
829+
unsigned long long ull_size;
829830
char sha[FILE_DIGEST_STRING_MAX];
830831
char path[448];
831832
char data[TRUSTDB_DATA_BUFSZ];
@@ -836,10 +837,11 @@ static int check_trustdb(void)
836837
(char *) entry->path.mv_data);
837838
snprintf(data, sizeof(data), "%.*s", (int) entry->data.mv_size,
838839
(char *) entry->data.mv_data);
839-
if (sscanf(data, DATA_FORMAT_IN, &tsource, &size, sha) != 3) {
840+
if (sscanf(data, DATA_FORMAT_IN, &tsource, &ull_size, sha) != 3) {
840841
fprintf(stderr, "%s data entry is corrupted\n", path);
841842
continue;
842843
}
844+
size = (off_t)ull_size;
843845
if (verify_file(path, size, sha, tsource))
844846
found = 1;
845847
} while (walk_database_next());

src/library/database.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3250,13 +3250,13 @@ static int handle_record(const char * buffer)
32503250
{
32513251
char path[2048+1];
32523252
char hash[64+1];
3253-
size_t size;
3253+
unsigned long long ull_size;
32543254

32553255
if (stop)
32563256
return 1;
32573257

32583258
// validating input
3259-
int res = sscanf(buffer, "%2048s %zu %64s", path, &size, hash);
3259+
int res = sscanf(buffer, "%2048s %llu %64s", path, &ull_size, hash);
32603260
msg(LOG_DEBUG, "update_thread: Parsing input buffer: %s", buffer);
32613261
msg(LOG_DEBUG,
32623262
"update_thread: Parsing input words(expected 3): %d",
@@ -3269,7 +3269,7 @@ static int handle_record(const char * buffer)
32693269

32703270
char data[BUFFER_SIZE];
32713271
snprintf(data, BUFFER_SIZE, DATA_FORMAT, (unsigned int)SRC_UNKNOWN,
3272-
size, hash);
3272+
ull_size, hash);
32733273

32743274
msg(LOG_DEBUG, "update_thread: Saving %s %s", path, data);
32753275
lock_update_thread();

src/library/fapolicyd-backend.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ typedef enum { SRC_UNKNOWN, SRC_RPM, SRC_FILE_DB, SRC_DEB } trust_src_t;
3838
// bytes to write. helper: stringify macro value
3939
#define STR_IMPL(x) #x
4040
#define STR(x) STR_IMPL(x)
41-
#define DATA_FORMAT "%u %zu %s"
42-
#define DATA_FORMAT_IN "%u %zu %" STR(FILE_DIGEST_STRING_WIDTH) "s"
41+
#define DATA_FORMAT "%u %llu %s"
42+
#define DATA_FORMAT_IN "%u %llu %" STR(FILE_DIGEST_STRING_WIDTH) "s"
4343

4444
typedef struct _backend
4545
{

src/library/md5-backend.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ int add_file_to_backend_by_md5(const char *path, const char *expected_md5,
120120
}
121121

122122
char *data;
123-
if (asprintf(&data, DATA_FORMAT, trust_src, file_size, sha_digest) == -1) {
123+
if (asprintf(&data, DATA_FORMAT, trust_src,
124+
(unsigned long long)file_size, sha_digest) == -1) {
124125
data = NULL;
125126
}
126127
free(sha_digest);
@@ -153,4 +154,3 @@ int add_file_to_backend_by_md5(const char *path, const char *expected_md5,
153154
}
154155
return 1;
155156
}
156-

src/library/rpm-backend.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ int do_rpm_load_list(const conf_t *conf, int memfd)
391391
if (asprintf( &data,
392392
DATA_FORMAT,
393393
tsource,
394-
sz,
394+
(unsigned long long)sz,
395395
sha) == -1) {
396396
data = NULL;
397397
}

src/library/trust-file.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ static char *make_data_string(const char *path)
128128
* path is stored as lmdb index
129129
*/
130130
int count = asprintf(&line, DATA_FORMAT, 0,
131-
sb.st_size, hash);
131+
(unsigned long long)sb.st_size, hash);
132132

133133
free(hash);
134134

@@ -370,7 +370,8 @@ int trust_file_load(const char *fpath, list_t *list, int memfd)
370370
}
371371

372372
int len = snprintf(data_buf, sizeof(data_buf),
373-
DATA_FORMAT, tsource, sz, sha);
373+
DATA_FORMAT, tsource,
374+
(unsigned long long)sz, sha);
374375
if (len < 0 || len >= (int)sizeof(data_buf)) {
375376
msg(LOG_ERR, "Entry too large in %s", fpath);
376377
continue;

src/tests/event_test.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -593,10 +593,12 @@ struct lmdb_record {
593593
static int parse_record(const char *record, struct lmdb_record *parsed)
594594
{
595595
size_t expected_len;
596+
unsigned long long ull_size;
596597

597-
if (sscanf(record, DATA_FORMAT_IN, &parsed->tsource, &parsed->size,
598+
if (sscanf(record, DATA_FORMAT_IN, &parsed->tsource, &ull_size,
598599
parsed->digest) != 3)
599600
return 1;
601+
parsed->size = (off_t)ull_size;
600602

601603
parsed->digest_len = strlen(parsed->digest);
602604
parsed->alg = file_hash_alg(parsed->digest_len);
@@ -620,7 +622,7 @@ static int test_rpm_accepts_sha512(void)
620622
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
621623

622624
snprintf(record, sizeof(record), DATA_FORMAT, (unsigned int)SRC_RPM,
623-
(size_t)8192, sha512);
625+
8192ULL, sha512);
624626
CHECK(parse_record(record, &parsed) == 0, 40,
625627
"[ERROR:40] parse failed for RPM SHA512 digest");
626628
CHECK(parsed.alg == FILE_HASH_ALG_SHA512, 41,
@@ -639,7 +641,7 @@ static int test_filedb_rejects_sha512(void)
639641
"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";
640642

641643
snprintf(record, sizeof(record), DATA_FORMAT, (unsigned int)SRC_FILE_DB,
642-
(size_t)4096, sha512);
644+
4096ULL, sha512);
643645
CHECK(parse_record(record, &parsed) != 0, 50,
644646
"[ERROR:50] filedb SHA512 digest unexpectedly accepted");
645647
return 0;
@@ -653,7 +655,7 @@ static int test_filedb_accepts_sha256(void)
653655
"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
654656

655657
snprintf(record, sizeof(record), DATA_FORMAT, (unsigned int)SRC_FILE_DB,
656-
(size_t)1024, sha256);
658+
1024ULL, sha256);
657659
CHECK(parse_record(record, &parsed) == 0, 60,
658660
"[ERROR:60] filedb SHA256 digest rejected");
659661
CHECK(parsed.alg == FILE_HASH_ALG_SHA256, 61,

src/tests/trustdb_format_test.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
#include <stdio.h>
55
#include <string.h>
6-
#include <sys/types.h>
76
#include "fapolicyd-backend.h"
87

98
int main(void)
@@ -13,15 +12,15 @@ int main(void)
1312
char data[TRUSTDB_DATA_BUFSZ];
1413
char parsed_digest[FILE_DIGEST_STRING_MAX];
1514
unsigned int tsource;
16-
off_t size;
15+
unsigned long long ull_size;
1716
int written;
1817

19-
written = snprintf(data, sizeof(data), DATA_FORMAT, SRC_RPM, (off_t)9400,
20-
digest);
18+
written = snprintf(data, sizeof(data), DATA_FORMAT, SRC_RPM,
19+
9400ULL, digest);
2120
if (written < 0 || written >= (int)sizeof(data))
2221
return 1;
2322

24-
if (sscanf(data, DATA_FORMAT_IN, &tsource, &size, parsed_digest) != 3)
23+
if (sscanf(data, DATA_FORMAT_IN, &tsource, &ull_size, parsed_digest) != 3)
2524
return 1;
2625

2726
if (strcmp(digest, parsed_digest))

src/tests/trustdb_lmdb_test.c

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -192,15 +192,15 @@ static int test_data_format_round_trip(void)
192192
char data[TRUSTDB_DATA_BUFSZ];
193193
char parsed_digest[FILE_DIGEST_STRING_MAX];
194194
unsigned int tsource;
195-
off_t size;
195+
unsigned long long ull_size;
196196
int written;
197197

198198
written = snprintf(data, sizeof(data), DATA_FORMAT, SRC_RPM,
199-
(off_t)9400, digest);
199+
9400ULL, digest);
200200
CHECK(written >= 0 && written < (int)sizeof(data), 10,
201201
"[ERROR:10] DATA_FORMAT output truncated");
202202

203-
CHECK(sscanf(data, DATA_FORMAT_IN, &tsource, &size, parsed_digest) == 3,
203+
CHECK(sscanf(data, DATA_FORMAT_IN, &tsource, &ull_size, parsed_digest) == 3,
204204
11, "[ERROR:11] DATA_FORMAT_IN parse failed");
205205
CHECK(strcmp(digest, parsed_digest) == 0, 12,
206206
"[ERROR:12] digest mismatch after round trip");
@@ -222,7 +222,7 @@ static int test_lmdb_short_path_round_trip(void)
222222
CHECK(rc == 0, 20, "[ERROR:20] failed to open temporary LMDB");
223223

224224
snprintf(payload, sizeof(payload), "%s " DATA_FORMAT "\n", path,
225-
SRC_FILE_DB, (size_t)1234, digest);
225+
SRC_FILE_DB, 1234ULL, digest);
226226
rc = import_records(payload, &entries);
227227
CHECK(rc == 0 && entries == 1, 21,
228228
"[ERROR:21] short-path record import failed");
@@ -254,7 +254,7 @@ static int test_lmdb_long_path_round_trip(void)
254254
CHECK(rc == 0, 31, "[ERROR:31] failed to open temporary LMDB");
255255

256256
snprintf(payload, sizeof(payload), "%s " DATA_FORMAT "\n", path,
257-
SRC_FILE_DB, (size_t)2048, digest);
257+
SRC_FILE_DB, 2048ULL, digest);
258258
rc = import_records(payload, &entries);
259259
CHECK(rc == 0 && entries == 1, 32,
260260
"[ERROR:32] long-path record import failed");
@@ -300,8 +300,8 @@ static int test_lmdb_long_path_shared_prefix_no_collision(void)
300300
*/
301301
snprintf(payload, sizeof(payload), "%s " DATA_FORMAT "\n"
302302
"%s " DATA_FORMAT "\n",
303-
path_a, SRC_FILE_DB, (size_t)3000, digest_a,
304-
path_b, SRC_FILE_DB, (size_t)3001, digest_b);
303+
path_a, SRC_FILE_DB, 3000ULL, digest_a,
304+
path_b, SRC_FILE_DB, 3001ULL, digest_b);
305305
rc = import_records(payload, &entries);
306306
CHECK(rc == 0 && entries == 2, 42,
307307
"[ERROR:42] shared-prefix record import failed");
@@ -354,7 +354,7 @@ static int test_lmdb_readonly_probe_does_not_break_live_env(void)
354354
CHECK(rc == 0, 60, "[ERROR:60] failed to open temporary LMDB");
355355

356356
snprintf(payload, sizeof(payload), "%s " DATA_FORMAT "\n",
357-
"/usr/bin/probe-a", SRC_FILE_DB, (size_t)123, digest_a);
357+
"/usr/bin/probe-a", SRC_FILE_DB, 123ULL, digest_a);
358358
rc = import_records(payload, &entries);
359359
CHECK(rc == 0 && entries == 1, 61,
360360
"[ERROR:61] initial record import failed");
@@ -370,7 +370,7 @@ static int test_lmdb_readonly_probe_does_not_break_live_env(void)
370370

371371
entries = 0;
372372
snprintf(payload, sizeof(payload), "%s " DATA_FORMAT "\n",
373-
"/usr/bin/probe-b", SRC_FILE_DB, (size_t)456, digest_b);
373+
"/usr/bin/probe-b", SRC_FILE_DB, 456ULL, digest_b);
374374
rc = import_records(payload, &entries);
375375
CHECK(rc == 0 && entries == 1, 65,
376376
"[ERROR:65] live environment import failed after probe close");
@@ -407,10 +407,11 @@ static int test_lmdb_chunked_import(void)
407407
CHECK(stream != NULL, 91,
408408
"[ERROR:91] failed to allocate chunked payload");
409409

410-
for (unsigned int i = 0; i < record_count; i++) {
411-
fprintf(stream, "/usr/bin/chunked-%04u " DATA_FORMAT "\n",
412-
i, SRC_FILE_DB, (size_t)(9000 + i), digest);
413-
}
410+
for (unsigned int i = 0; i < record_count; i++) {
411+
fprintf(stream, "/usr/bin/chunked-%04u " DATA_FORMAT "\n",
412+
i, SRC_FILE_DB,
413+
(unsigned long long)(9000 + i), digest);
414+
}
414415
fclose(stream);
415416

416417
rc = import_records(payload, &entries);
@@ -452,7 +453,7 @@ static int test_lmdb_long_path_negative_lookup(void)
452453
CHECK(rc == 0, 51, "[ERROR:51] failed to open temporary LMDB");
453454

454455
snprintf(payload, sizeof(payload), "%s " DATA_FORMAT "\n", path_a,
455-
SRC_FILE_DB, (size_t)4100, digest);
456+
SRC_FILE_DB, 4100ULL, digest);
456457
rc = import_records(payload, &entries);
457458
CHECK(rc == 0 && entries == 1, 52,
458459
"[ERROR:52] negative-lookup record import failed");
@@ -497,7 +498,7 @@ static int test_lmdb_concurrent_read_handles(void)
497498
CHECK(rc == 0, 70, "[ERROR:70] failed to open temporary LMDB");
498499

499500
snprintf(payload, sizeof(payload), "%s " DATA_FORMAT "\n", path,
500-
SRC_FILE_DB, (size_t)555, digest);
501+
SRC_FILE_DB, 555ULL, digest);
501502
rc = import_records(payload, &entries);
502503
CHECK(rc == 0 && entries == 1, 71,
503504
"[ERROR:71] concurrent record import failed");

0 commit comments

Comments
 (0)