Fossil SCM
On unix, use setrlimit() to limit total heap space usage to 1GB on 32-bit systems and 10GB on 64-bit systems, and total stack space to 2MB, as a proactive defense again the "stack clash" vulnerability found on many unix-like OSes. I do not yet know if these limits are reasonable.
Commit
6e6e4b1d26e187ed5e2bd2aae0c62bf70c587ef8a2fc01dc8563296326621c13
Parent
a49ef3786563a0c…
2 files changed
+10
+26
+10
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -553,10 +553,20 @@ | ||
| 553 | 553 | #endif |
| 554 | 554 | { |
| 555 | 555 | const char *zCmdName = "unknown"; |
| 556 | 556 | const CmdOrPage *pCmd = 0; |
| 557 | 557 | int rc; |
| 558 | + | |
| 559 | + /* Limit the total amount of heap and stack space available to | |
| 560 | + ** Fossil as a defense against "stack clash" attacks. 64-bit systems | |
| 561 | + ** have much larger limits than 32-bit systems. */ | |
| 562 | + if( sizeof(pCmd)==4 ){ | |
| 563 | + fossil_limit_memory( 1000000000, 2000000); /* 32-bit systems */ | |
| 564 | + }else{ | |
| 565 | + fossil_limit_memory(10000000000, 2000000); /* 64-bit systems */ | |
| 566 | + } | |
| 567 | + | |
| 558 | 568 | if( sqlite3_libversion_number()<3014000 ){ |
| 559 | 569 | fossil_fatal("Unsuitable SQLite version %s, must be at least 3.14.0", |
| 560 | 570 | sqlite3_libversion()); |
| 561 | 571 | } |
| 562 | 572 | sqlite3_config(SQLITE_CONFIG_MULTITHREAD); |
| 563 | 573 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -553,10 +553,20 @@ | |
| 553 | #endif |
| 554 | { |
| 555 | const char *zCmdName = "unknown"; |
| 556 | const CmdOrPage *pCmd = 0; |
| 557 | int rc; |
| 558 | if( sqlite3_libversion_number()<3014000 ){ |
| 559 | fossil_fatal("Unsuitable SQLite version %s, must be at least 3.14.0", |
| 560 | sqlite3_libversion()); |
| 561 | } |
| 562 | sqlite3_config(SQLITE_CONFIG_MULTITHREAD); |
| 563 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -553,10 +553,20 @@ | |
| 553 | #endif |
| 554 | { |
| 555 | const char *zCmdName = "unknown"; |
| 556 | const CmdOrPage *pCmd = 0; |
| 557 | int rc; |
| 558 | |
| 559 | /* Limit the total amount of heap and stack space available to |
| 560 | ** Fossil as a defense against "stack clash" attacks. 64-bit systems |
| 561 | ** have much larger limits than 32-bit systems. */ |
| 562 | if( sizeof(pCmd)==4 ){ |
| 563 | fossil_limit_memory( 1000000000, 2000000); /* 32-bit systems */ |
| 564 | }else{ |
| 565 | fossil_limit_memory(10000000000, 2000000); /* 64-bit systems */ |
| 566 | } |
| 567 | |
| 568 | if( sqlite3_libversion_number()<3014000 ){ |
| 569 | fossil_fatal("Unsuitable SQLite version %s, must be at least 3.14.0", |
| 570 | sqlite3_libversion()); |
| 571 | } |
| 572 | sqlite3_config(SQLITE_CONFIG_MULTITHREAD); |
| 573 |
+26
| --- src/util.c | ||
| +++ src/util.c | ||
| @@ -447,5 +447,31 @@ | ||
| 447 | 447 | } |
| 448 | 448 | sqlite3_file_control(db, 0, SQLITE_FCNTL_TEMPFILENAME, (void*)&zTFile); |
| 449 | 449 | if( g.db==0 ) sqlite3_close(db); |
| 450 | 450 | return zTFile; |
| 451 | 451 | } |
| 452 | + | |
| 453 | +/* | |
| 454 | +** Limit the total amount of memory available to Fossil | |
| 455 | +*/ | |
| 456 | +void fossil_limit_memory(sqlite3_int64 nHeap, sqlite3_int64 nStack){ | |
| 457 | +#if defined(__unix__) | |
| 458 | + struct rlimit x; | |
| 459 | + | |
| 460 | +#if defined(RLIMIT_DATA) | |
| 461 | + getrlimit(RLIMIT_DATA, &x); | |
| 462 | + if( sizeof(x.rlim_cur)<8 && nHeap>0x7fffffff ){ | |
| 463 | + nHeap = 0x7fffffff; | |
| 464 | + } | |
| 465 | + x.rlim_cur = (rlim_t)nHeap; | |
| 466 | + setrlimit(RLIMIT_DATA, &x); | |
| 467 | +#endif /* defined(RLIMIT_DATA) */ | |
| 468 | +#if defined(RLIMIT_STACK) | |
| 469 | + getrlimit(RLIMIT_STACK, &x); | |
| 470 | + if( sizeof(x.rlim_cur)<8 && nStack>0x7fffffff ){ | |
| 471 | + nStack = 0x7fffffff; | |
| 472 | + } | |
| 473 | + x.rlim_cur = (rlim_t)nStack; | |
| 474 | + setrlimit(RLIMIT_STACK, &x); | |
| 475 | +#endif /* defined(RLIMIT_STACK) */ | |
| 476 | +#endif /* defined(__unix__) */ | |
| 477 | +} | |
| 452 | 478 |
| --- src/util.c | |
| +++ src/util.c | |
| @@ -447,5 +447,31 @@ | |
| 447 | } |
| 448 | sqlite3_file_control(db, 0, SQLITE_FCNTL_TEMPFILENAME, (void*)&zTFile); |
| 449 | if( g.db==0 ) sqlite3_close(db); |
| 450 | return zTFile; |
| 451 | } |
| 452 |
| --- src/util.c | |
| +++ src/util.c | |
| @@ -447,5 +447,31 @@ | |
| 447 | } |
| 448 | sqlite3_file_control(db, 0, SQLITE_FCNTL_TEMPFILENAME, (void*)&zTFile); |
| 449 | if( g.db==0 ) sqlite3_close(db); |
| 450 | return zTFile; |
| 451 | } |
| 452 | |
| 453 | /* |
| 454 | ** Limit the total amount of memory available to Fossil |
| 455 | */ |
| 456 | void fossil_limit_memory(sqlite3_int64 nHeap, sqlite3_int64 nStack){ |
| 457 | #if defined(__unix__) |
| 458 | struct rlimit x; |
| 459 | |
| 460 | #if defined(RLIMIT_DATA) |
| 461 | getrlimit(RLIMIT_DATA, &x); |
| 462 | if( sizeof(x.rlim_cur)<8 && nHeap>0x7fffffff ){ |
| 463 | nHeap = 0x7fffffff; |
| 464 | } |
| 465 | x.rlim_cur = (rlim_t)nHeap; |
| 466 | setrlimit(RLIMIT_DATA, &x); |
| 467 | #endif /* defined(RLIMIT_DATA) */ |
| 468 | #if defined(RLIMIT_STACK) |
| 469 | getrlimit(RLIMIT_STACK, &x); |
| 470 | if( sizeof(x.rlim_cur)<8 && nStack>0x7fffffff ){ |
| 471 | nStack = 0x7fffffff; |
| 472 | } |
| 473 | x.rlim_cur = (rlim_t)nStack; |
| 474 | setrlimit(RLIMIT_STACK, &x); |
| 475 | #endif /* defined(RLIMIT_STACK) */ |
| 476 | #endif /* defined(__unix__) */ |
| 477 | } |
| 478 |