Fossil SCM
Increase the stack size limit to 8MB. Disable stack and heap size limits prior to invoking subprocesses.
Commit
3f193ba61011737fecfa67b038579a24870ef5b8031853ebf992709082c90a20
Parent
42d151cc64f1a2f…
2 files changed
+1
-9
+24
-8
+1
-9
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -554,19 +554,11 @@ | ||
| 554 | 554 | { |
| 555 | 555 | const char *zCmdName = "unknown"; |
| 556 | 556 | const CmdOrPage *pCmd = 0; |
| 557 | 557 | int rc; |
| 558 | 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 | - | |
| 559 | + fossil_limit_memory(1); | |
| 568 | 560 | if( sqlite3_libversion_number()<3014000 ){ |
| 569 | 561 | fossil_fatal("Unsuitable SQLite version %s, must be at least 3.14.0", |
| 570 | 562 | sqlite3_libversion()); |
| 571 | 563 | } |
| 572 | 564 | sqlite3_config(SQLITE_CONFIG_MULTITHREAD); |
| 573 | 565 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -554,19 +554,11 @@ | |
| 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 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -554,19 +554,11 @@ | |
| 554 | { |
| 555 | const char *zCmdName = "unknown"; |
| 556 | const CmdOrPage *pCmd = 0; |
| 557 | int rc; |
| 558 | |
| 559 | fossil_limit_memory(1); |
| 560 | if( sqlite3_libversion_number()<3014000 ){ |
| 561 | fossil_fatal("Unsuitable SQLite version %s, must be at least 3.14.0", |
| 562 | sqlite3_libversion()); |
| 563 | } |
| 564 | sqlite3_config(SQLITE_CONFIG_MULTITHREAD); |
| 565 |
+24
-8
| --- src/util.c | ||
| +++ src/util.c | ||
| @@ -144,11 +144,13 @@ | ||
| 144 | 144 | ** to the ShellShock or BashDoor bug. |
| 145 | 145 | */ |
| 146 | 146 | assert( g.cgiOutput==0 ); |
| 147 | 147 | |
| 148 | 148 | /* The regular system() call works to get a shell on unix */ |
| 149 | + fossil_limit_memory(0); | |
| 149 | 150 | rc = system(zOrigCmd); |
| 151 | + fossil_limit_memory(1); | |
| 150 | 152 | #endif |
| 151 | 153 | return rc; |
| 152 | 154 | } |
| 153 | 155 | |
| 154 | 156 | /* |
| @@ -449,29 +451,43 @@ | ||
| 449 | 451 | if( g.db==0 ) sqlite3_close(db); |
| 450 | 452 | return zTFile; |
| 451 | 453 | } |
| 452 | 454 | |
| 453 | 455 | /* |
| 454 | -** Limit the total amount of memory available to Fossil | |
| 456 | +** Turn memory limits for stack and heap on and off. The argument | |
| 457 | +** is true to turn memory limits on and false to turn them off. | |
| 458 | +** | |
| 459 | +** Memory limits should be enabled at startup, but then turned off | |
| 460 | +** before starting subprocesses. | |
| 455 | 461 | */ |
| 456 | -void fossil_limit_memory(sqlite3_int64 nHeap, sqlite3_int64 nStack){ | |
| 462 | +void fossil_limit_memory(int onOff){ | |
| 457 | 463 | #if defined(__unix__) |
| 464 | + static sqlite3_int64 origHeap = 10000000000; /* 10GB */ | |
| 465 | + static sqlite3_int64 origStack = 8000000; /* 8MB */ | |
| 458 | 466 | struct rlimit x; |
| 459 | 467 | |
| 460 | 468 | #if defined(RLIMIT_DATA) |
| 461 | 469 | getrlimit(RLIMIT_DATA, &x); |
| 462 | - if( sizeof(x.rlim_cur)<8 && nHeap>0x7fffffff ){ | |
| 463 | - nHeap = 0x7fffffff; | |
| 470 | + if( onOff ){ | |
| 471 | + origHeap = x.rlim_cur; | |
| 472 | + if( sizeof(void*)<8 || sizeof(x.rlim_cur)<8 ){ | |
| 473 | + x.rlim_cur = 1000000000; /* 1GB on 32-bit systems */ | |
| 474 | + }else{ | |
| 475 | + x.rlim_cur = 10000000000; /* 10GB on 64-bit systems */ | |
| 476 | + } | |
| 477 | + }else{ | |
| 478 | + x.rlim_cur = origHeap; | |
| 464 | 479 | } |
| 465 | - x.rlim_cur = (rlim_t)nHeap; | |
| 466 | 480 | setrlimit(RLIMIT_DATA, &x); |
| 467 | 481 | #endif /* defined(RLIMIT_DATA) */ |
| 468 | 482 | #if defined(RLIMIT_STACK) |
| 469 | 483 | getrlimit(RLIMIT_STACK, &x); |
| 470 | - if( sizeof(x.rlim_cur)<8 && nStack>0x7fffffff ){ | |
| 471 | - nStack = 0x7fffffff; | |
| 484 | + if( onOff ){ | |
| 485 | + origStack = x.rlim_cur; | |
| 486 | + x.rlim_cur = 8000000; /* 8MB */ | |
| 487 | + }else{ | |
| 488 | + x.rlim_cur = origStack; | |
| 472 | 489 | } |
| 473 | - x.rlim_cur = (rlim_t)nStack; | |
| 474 | 490 | setrlimit(RLIMIT_STACK, &x); |
| 475 | 491 | #endif /* defined(RLIMIT_STACK) */ |
| 476 | 492 | #endif /* defined(__unix__) */ |
| 477 | 493 | } |
| 478 | 494 |
| --- src/util.c | |
| +++ src/util.c | |
| @@ -144,11 +144,13 @@ | |
| 144 | ** to the ShellShock or BashDoor bug. |
| 145 | */ |
| 146 | assert( g.cgiOutput==0 ); |
| 147 | |
| 148 | /* The regular system() call works to get a shell on unix */ |
| 149 | rc = system(zOrigCmd); |
| 150 | #endif |
| 151 | return rc; |
| 152 | } |
| 153 | |
| 154 | /* |
| @@ -449,29 +451,43 @@ | |
| 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 |
| --- src/util.c | |
| +++ src/util.c | |
| @@ -144,11 +144,13 @@ | |
| 144 | ** to the ShellShock or BashDoor bug. |
| 145 | */ |
| 146 | assert( g.cgiOutput==0 ); |
| 147 | |
| 148 | /* The regular system() call works to get a shell on unix */ |
| 149 | fossil_limit_memory(0); |
| 150 | rc = system(zOrigCmd); |
| 151 | fossil_limit_memory(1); |
| 152 | #endif |
| 153 | return rc; |
| 154 | } |
| 155 | |
| 156 | /* |
| @@ -449,29 +451,43 @@ | |
| 451 | if( g.db==0 ) sqlite3_close(db); |
| 452 | return zTFile; |
| 453 | } |
| 454 | |
| 455 | /* |
| 456 | ** Turn memory limits for stack and heap on and off. The argument |
| 457 | ** is true to turn memory limits on and false to turn them off. |
| 458 | ** |
| 459 | ** Memory limits should be enabled at startup, but then turned off |
| 460 | ** before starting subprocesses. |
| 461 | */ |
| 462 | void fossil_limit_memory(int onOff){ |
| 463 | #if defined(__unix__) |
| 464 | static sqlite3_int64 origHeap = 10000000000; /* 10GB */ |
| 465 | static sqlite3_int64 origStack = 8000000; /* 8MB */ |
| 466 | struct rlimit x; |
| 467 | |
| 468 | #if defined(RLIMIT_DATA) |
| 469 | getrlimit(RLIMIT_DATA, &x); |
| 470 | if( onOff ){ |
| 471 | origHeap = x.rlim_cur; |
| 472 | if( sizeof(void*)<8 || sizeof(x.rlim_cur)<8 ){ |
| 473 | x.rlim_cur = 1000000000; /* 1GB on 32-bit systems */ |
| 474 | }else{ |
| 475 | x.rlim_cur = 10000000000; /* 10GB on 64-bit systems */ |
| 476 | } |
| 477 | }else{ |
| 478 | x.rlim_cur = origHeap; |
| 479 | } |
| 480 | setrlimit(RLIMIT_DATA, &x); |
| 481 | #endif /* defined(RLIMIT_DATA) */ |
| 482 | #if defined(RLIMIT_STACK) |
| 483 | getrlimit(RLIMIT_STACK, &x); |
| 484 | if( onOff ){ |
| 485 | origStack = x.rlim_cur; |
| 486 | x.rlim_cur = 8000000; /* 8MB */ |
| 487 | }else{ |
| 488 | x.rlim_cur = origStack; |
| 489 | } |
| 490 | setrlimit(RLIMIT_STACK, &x); |
| 491 | #endif /* defined(RLIMIT_STACK) */ |
| 492 | #endif /* defined(__unix__) */ |
| 493 | } |
| 494 |