Fossil SCM

ASAN caught a misuse of memcmp when matching the subcommand for "fossil uv". Changed it to strncmp, as used in several other Fossil CLI subcommand matching bits. Since the left-side arg is user-supplied text and we were using its strlen() for the third argument to memcmp(), it allowed arbitrary amounts of overrun.

wyoung 2023-12-12 22:12 trunk
Commit 182cfa1b1d62b80f5a2b036356aaab84635b8a781712db0a681e66c313bbf07f
1 file changed +11 -11
+11 -11
--- src/unversioned.c
+++ src/unversioned.c
@@ -308,11 +308,11 @@
308308
mtime = time(0);
309309
}else{
310310
mtime = db_int(0, "SELECT strftime('%%s',%Q)", zMtime);
311311
if( mtime<=0 ) fossil_fatal("bad timestamp: %Q", zMtime);
312312
}
313
- if( memcmp(zCmd, "add", nCmd)==0 ){
313
+ if( strncmp(zCmd, "add", nCmd)==0 ){
314314
const char *zError = 0;
315315
const char *zIn;
316316
const char *zAs;
317317
Blob file;
318318
int i;
@@ -340,11 +340,11 @@
340340
blob_read_from_file(&file, g.argv[i], ExtFILE);
341341
unversioned_write(zIn, &file, mtime);
342342
blob_reset(&file);
343343
}
344344
db_end_transaction(0);
345
- }else if( memcmp(zCmd, "cat", nCmd)==0 ){
345
+ }else if( strncmp(zCmd, "cat", nCmd)==0 ){
346346
int i;
347347
verify_all_options();
348348
db_begin_transaction();
349349
for(i=3; i<g.argc; i++){
350350
Blob content;
@@ -352,11 +352,11 @@
352352
blob_write_to_file(&content, "-");
353353
}
354354
blob_reset(&content);
355355
}
356356
db_end_transaction(0);
357
- }else if( memcmp(zCmd, "edit", nCmd)==0 ){
357
+ }else if( strncmp(zCmd, "edit", nCmd)==0 ){
358358
const char *zEditor; /* Name of the text-editor command */
359359
const char *zTFile; /* Temporary file */
360360
const char *zUVFile; /* Name of the unversioned file */
361361
char *zCmd; /* Command to run the text editor */
362362
Blob content; /* Content of the unversioned file */
@@ -395,24 +395,24 @@
395395
file_delete(zTFile);
396396
if( zMtime==0 ) mtime = time(0);
397397
unversioned_write(zUVFile, &content, mtime);
398398
db_end_transaction(0);
399399
blob_reset(&content);
400
- }else if( memcmp(zCmd, "export", nCmd)==0 ){
400
+ }else if( strncmp(zCmd, "export", nCmd)==0 ){
401401
Blob content;
402402
verify_all_options();
403403
if( g.argc!=5 ) usage("export UVFILE OUTPUT");
404404
if( unversioned_content(g.argv[3], &content)==0 ){
405405
fossil_fatal("no such uv-file: %Q", g.argv[3]);
406406
}
407407
blob_write_to_file(&content, g.argv[4]);
408408
blob_reset(&content);
409
- }else if( memcmp(zCmd, "hash", nCmd)==0 ){ /* undocumented */
409
+ }else if( strncmp(zCmd, "hash", nCmd)==0 ){ /* undocumented */
410410
/* Show the hash value used during uv sync */
411411
int debugFlag = find_option("debug",0,0)!=0;
412412
fossil_print("%s\n", unversioned_content_hash(debugFlag));
413
- }else if( memcmp(zCmd, "list", nCmd)==0 || memcmp(zCmd, "ls", nCmd)==0 ){
413
+ }else if( strncmp(zCmd, "list", nCmd)==0 || strncmp(zCmd, "ls", nCmd)==0 ){
414414
Stmt q;
415415
int allFlag = find_option("all","a",0)!=0;
416416
int longFlag = find_option("l",0,0)!=0 || (nCmd>1 && zCmd[1]=='i');
417417
char *zPattern = sqlite3_mprintf("true");
418418
const char *zGlob;
@@ -464,18 +464,18 @@
464464
);
465465
}
466466
}
467467
db_finalize(&q);
468468
sqlite3_free(zPattern);
469
- }else if( memcmp(zCmd, "revert", nCmd)==0 ){
469
+ }else if( strncmp(zCmd, "revert", nCmd)==0 ){
470470
unsigned syncFlags =
471471
unversioned_sync_flags(SYNC_UNVERSIONED|SYNC_UV_REVERT);
472472
g.argv[1] = "sync";
473473
g.argv[2] = "--uv-noop";
474474
sync_unversioned(syncFlags);
475
- }else if( memcmp(zCmd, "remove", nCmd)==0 || memcmp(zCmd, "rm", nCmd)==0
476
- || memcmp(zCmd, "delete", nCmd)==0 ){
475
+ }else if( strncmp(zCmd, "remove", nCmd)==0 || strncmp(zCmd, "rm", nCmd)==0
476
+ || strncmp(zCmd, "delete", nCmd)==0 ){
477477
int i;
478478
const char *zGlob;
479479
db_begin_transaction();
480480
while( (zGlob = find_option("glob",0,1))!=0 ){
481481
db_multi_exec(
@@ -499,16 +499,16 @@
499499
mtime, g.argv[i]
500500
);
501501
}
502502
db_unset("uv-hash", 0);
503503
db_end_transaction(0);
504
- }else if( memcmp(zCmd,"sync",nCmd)==0 ){
504
+ }else if( strncmp(zCmd,"sync",nCmd)==0 ){
505505
unsigned syncFlags = unversioned_sync_flags(SYNC_UNVERSIONED);
506506
g.argv[1] = "sync";
507507
g.argv[2] = "--uv-noop";
508508
sync_unversioned(syncFlags);
509
- }else if( memcmp(zCmd, "touch", nCmd)==0 ){
509
+ }else if( strncmp(zCmd, "touch", nCmd)==0 ){
510510
int i;
511511
verify_all_options();
512512
db_begin_transaction();
513513
for(i=3; i<g.argc; i++){
514514
db_multi_exec(
515515
--- src/unversioned.c
+++ src/unversioned.c
@@ -308,11 +308,11 @@
308 mtime = time(0);
309 }else{
310 mtime = db_int(0, "SELECT strftime('%%s',%Q)", zMtime);
311 if( mtime<=0 ) fossil_fatal("bad timestamp: %Q", zMtime);
312 }
313 if( memcmp(zCmd, "add", nCmd)==0 ){
314 const char *zError = 0;
315 const char *zIn;
316 const char *zAs;
317 Blob file;
318 int i;
@@ -340,11 +340,11 @@
340 blob_read_from_file(&file, g.argv[i], ExtFILE);
341 unversioned_write(zIn, &file, mtime);
342 blob_reset(&file);
343 }
344 db_end_transaction(0);
345 }else if( memcmp(zCmd, "cat", nCmd)==0 ){
346 int i;
347 verify_all_options();
348 db_begin_transaction();
349 for(i=3; i<g.argc; i++){
350 Blob content;
@@ -352,11 +352,11 @@
352 blob_write_to_file(&content, "-");
353 }
354 blob_reset(&content);
355 }
356 db_end_transaction(0);
357 }else if( memcmp(zCmd, "edit", nCmd)==0 ){
358 const char *zEditor; /* Name of the text-editor command */
359 const char *zTFile; /* Temporary file */
360 const char *zUVFile; /* Name of the unversioned file */
361 char *zCmd; /* Command to run the text editor */
362 Blob content; /* Content of the unversioned file */
@@ -395,24 +395,24 @@
395 file_delete(zTFile);
396 if( zMtime==0 ) mtime = time(0);
397 unversioned_write(zUVFile, &content, mtime);
398 db_end_transaction(0);
399 blob_reset(&content);
400 }else if( memcmp(zCmd, "export", nCmd)==0 ){
401 Blob content;
402 verify_all_options();
403 if( g.argc!=5 ) usage("export UVFILE OUTPUT");
404 if( unversioned_content(g.argv[3], &content)==0 ){
405 fossil_fatal("no such uv-file: %Q", g.argv[3]);
406 }
407 blob_write_to_file(&content, g.argv[4]);
408 blob_reset(&content);
409 }else if( memcmp(zCmd, "hash", nCmd)==0 ){ /* undocumented */
410 /* Show the hash value used during uv sync */
411 int debugFlag = find_option("debug",0,0)!=0;
412 fossil_print("%s\n", unversioned_content_hash(debugFlag));
413 }else if( memcmp(zCmd, "list", nCmd)==0 || memcmp(zCmd, "ls", nCmd)==0 ){
414 Stmt q;
415 int allFlag = find_option("all","a",0)!=0;
416 int longFlag = find_option("l",0,0)!=0 || (nCmd>1 && zCmd[1]=='i');
417 char *zPattern = sqlite3_mprintf("true");
418 const char *zGlob;
@@ -464,18 +464,18 @@
464 );
465 }
466 }
467 db_finalize(&q);
468 sqlite3_free(zPattern);
469 }else if( memcmp(zCmd, "revert", nCmd)==0 ){
470 unsigned syncFlags =
471 unversioned_sync_flags(SYNC_UNVERSIONED|SYNC_UV_REVERT);
472 g.argv[1] = "sync";
473 g.argv[2] = "--uv-noop";
474 sync_unversioned(syncFlags);
475 }else if( memcmp(zCmd, "remove", nCmd)==0 || memcmp(zCmd, "rm", nCmd)==0
476 || memcmp(zCmd, "delete", nCmd)==0 ){
477 int i;
478 const char *zGlob;
479 db_begin_transaction();
480 while( (zGlob = find_option("glob",0,1))!=0 ){
481 db_multi_exec(
@@ -499,16 +499,16 @@
499 mtime, g.argv[i]
500 );
501 }
502 db_unset("uv-hash", 0);
503 db_end_transaction(0);
504 }else if( memcmp(zCmd,"sync",nCmd)==0 ){
505 unsigned syncFlags = unversioned_sync_flags(SYNC_UNVERSIONED);
506 g.argv[1] = "sync";
507 g.argv[2] = "--uv-noop";
508 sync_unversioned(syncFlags);
509 }else if( memcmp(zCmd, "touch", nCmd)==0 ){
510 int i;
511 verify_all_options();
512 db_begin_transaction();
513 for(i=3; i<g.argc; i++){
514 db_multi_exec(
515
--- src/unversioned.c
+++ src/unversioned.c
@@ -308,11 +308,11 @@
308 mtime = time(0);
309 }else{
310 mtime = db_int(0, "SELECT strftime('%%s',%Q)", zMtime);
311 if( mtime<=0 ) fossil_fatal("bad timestamp: %Q", zMtime);
312 }
313 if( strncmp(zCmd, "add", nCmd)==0 ){
314 const char *zError = 0;
315 const char *zIn;
316 const char *zAs;
317 Blob file;
318 int i;
@@ -340,11 +340,11 @@
340 blob_read_from_file(&file, g.argv[i], ExtFILE);
341 unversioned_write(zIn, &file, mtime);
342 blob_reset(&file);
343 }
344 db_end_transaction(0);
345 }else if( strncmp(zCmd, "cat", nCmd)==0 ){
346 int i;
347 verify_all_options();
348 db_begin_transaction();
349 for(i=3; i<g.argc; i++){
350 Blob content;
@@ -352,11 +352,11 @@
352 blob_write_to_file(&content, "-");
353 }
354 blob_reset(&content);
355 }
356 db_end_transaction(0);
357 }else if( strncmp(zCmd, "edit", nCmd)==0 ){
358 const char *zEditor; /* Name of the text-editor command */
359 const char *zTFile; /* Temporary file */
360 const char *zUVFile; /* Name of the unversioned file */
361 char *zCmd; /* Command to run the text editor */
362 Blob content; /* Content of the unversioned file */
@@ -395,24 +395,24 @@
395 file_delete(zTFile);
396 if( zMtime==0 ) mtime = time(0);
397 unversioned_write(zUVFile, &content, mtime);
398 db_end_transaction(0);
399 blob_reset(&content);
400 }else if( strncmp(zCmd, "export", nCmd)==0 ){
401 Blob content;
402 verify_all_options();
403 if( g.argc!=5 ) usage("export UVFILE OUTPUT");
404 if( unversioned_content(g.argv[3], &content)==0 ){
405 fossil_fatal("no such uv-file: %Q", g.argv[3]);
406 }
407 blob_write_to_file(&content, g.argv[4]);
408 blob_reset(&content);
409 }else if( strncmp(zCmd, "hash", nCmd)==0 ){ /* undocumented */
410 /* Show the hash value used during uv sync */
411 int debugFlag = find_option("debug",0,0)!=0;
412 fossil_print("%s\n", unversioned_content_hash(debugFlag));
413 }else if( strncmp(zCmd, "list", nCmd)==0 || strncmp(zCmd, "ls", nCmd)==0 ){
414 Stmt q;
415 int allFlag = find_option("all","a",0)!=0;
416 int longFlag = find_option("l",0,0)!=0 || (nCmd>1 && zCmd[1]=='i');
417 char *zPattern = sqlite3_mprintf("true");
418 const char *zGlob;
@@ -464,18 +464,18 @@
464 );
465 }
466 }
467 db_finalize(&q);
468 sqlite3_free(zPattern);
469 }else if( strncmp(zCmd, "revert", nCmd)==0 ){
470 unsigned syncFlags =
471 unversioned_sync_flags(SYNC_UNVERSIONED|SYNC_UV_REVERT);
472 g.argv[1] = "sync";
473 g.argv[2] = "--uv-noop";
474 sync_unversioned(syncFlags);
475 }else if( strncmp(zCmd, "remove", nCmd)==0 || strncmp(zCmd, "rm", nCmd)==0
476 || strncmp(zCmd, "delete", nCmd)==0 ){
477 int i;
478 const char *zGlob;
479 db_begin_transaction();
480 while( (zGlob = find_option("glob",0,1))!=0 ){
481 db_multi_exec(
@@ -499,16 +499,16 @@
499 mtime, g.argv[i]
500 );
501 }
502 db_unset("uv-hash", 0);
503 db_end_transaction(0);
504 }else if( strncmp(zCmd,"sync",nCmd)==0 ){
505 unsigned syncFlags = unversioned_sync_flags(SYNC_UNVERSIONED);
506 g.argv[1] = "sync";
507 g.argv[2] = "--uv-noop";
508 sync_unversioned(syncFlags);
509 }else if( strncmp(zCmd, "touch", nCmd)==0 ){
510 int i;
511 verify_all_options();
512 db_begin_transaction();
513 for(i=3; i<g.argc; i++){
514 db_multi_exec(
515

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button