Fossil SCM
When the "http" command is run as root, automatically set up a chroot jail and drop root privileges prior to reading any input.
Commit
7ba10f1a6ae0d828af9250e257e162a6c5ffc4c4
Parent
96c1043c61aa577…
2 files changed
+22
+3
+22
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -27,10 +27,13 @@ | ||
| 27 | 27 | #include "config.h" |
| 28 | 28 | #include "main.h" |
| 29 | 29 | #include <string.h> |
| 30 | 30 | #include <time.h> |
| 31 | 31 | #include <fcntl.h> |
| 32 | +#include <sys/types.h> | |
| 33 | +#include <sys/stat.h> | |
| 34 | + | |
| 32 | 35 | |
| 33 | 36 | #if INTERFACE |
| 34 | 37 | |
| 35 | 38 | /* |
| 36 | 39 | ** Number of elements in an array |
| @@ -680,10 +683,29 @@ | ||
| 680 | 683 | void cmd_http(void){ |
| 681 | 684 | const char *zIpAddr; |
| 682 | 685 | if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){ |
| 683 | 686 | cgi_panic("no repository specified"); |
| 684 | 687 | } |
| 688 | +#if !defined(__MINGW32__) | |
| 689 | + if( g.argc==3 && getuid()==0 ){ | |
| 690 | + int i; | |
| 691 | + char *zRepo = g.argv[2]; | |
| 692 | + struct stat sStat; | |
| 693 | + for(i=strlen(zRepo)-1; i>0 && zRepo[i]!='/'; i--){} | |
| 694 | + if( zRepo[i]=='/' ){ | |
| 695 | + zRepo[i] = 0; | |
| 696 | + chdir(g.argv[2]); | |
| 697 | + chroot(g.argv[2]); | |
| 698 | + g.argv[2] = &zRepo[i+1]; | |
| 699 | + } | |
| 700 | + if( stat(g.argv[2], &sStat)!=0 ){ | |
| 701 | + fossil_fatal("cannot stat() repository: %s", g.argv[2]); | |
| 702 | + } | |
| 703 | + setgid(sStat.st_gid); | |
| 704 | + setuid(sStat.st_uid); | |
| 705 | + } | |
| 706 | +#endif | |
| 685 | 707 | g.cgiPanic = 1; |
| 686 | 708 | g.fullHttpReply = 1; |
| 687 | 709 | if( g.argc==6 ){ |
| 688 | 710 | g.httpIn = fopen(g.argv[3], "rb"); |
| 689 | 711 | g.httpOut = fopen(g.argv[4], "wb"); |
| 690 | 712 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -27,10 +27,13 @@ | |
| 27 | #include "config.h" |
| 28 | #include "main.h" |
| 29 | #include <string.h> |
| 30 | #include <time.h> |
| 31 | #include <fcntl.h> |
| 32 | |
| 33 | #if INTERFACE |
| 34 | |
| 35 | /* |
| 36 | ** Number of elements in an array |
| @@ -680,10 +683,29 @@ | |
| 680 | void cmd_http(void){ |
| 681 | const char *zIpAddr; |
| 682 | if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){ |
| 683 | cgi_panic("no repository specified"); |
| 684 | } |
| 685 | g.cgiPanic = 1; |
| 686 | g.fullHttpReply = 1; |
| 687 | if( g.argc==6 ){ |
| 688 | g.httpIn = fopen(g.argv[3], "rb"); |
| 689 | g.httpOut = fopen(g.argv[4], "wb"); |
| 690 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -27,10 +27,13 @@ | |
| 27 | #include "config.h" |
| 28 | #include "main.h" |
| 29 | #include <string.h> |
| 30 | #include <time.h> |
| 31 | #include <fcntl.h> |
| 32 | #include <sys/types.h> |
| 33 | #include <sys/stat.h> |
| 34 | |
| 35 | |
| 36 | #if INTERFACE |
| 37 | |
| 38 | /* |
| 39 | ** Number of elements in an array |
| @@ -680,10 +683,29 @@ | |
| 683 | void cmd_http(void){ |
| 684 | const char *zIpAddr; |
| 685 | if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){ |
| 686 | cgi_panic("no repository specified"); |
| 687 | } |
| 688 | #if !defined(__MINGW32__) |
| 689 | if( g.argc==3 && getuid()==0 ){ |
| 690 | int i; |
| 691 | char *zRepo = g.argv[2]; |
| 692 | struct stat sStat; |
| 693 | for(i=strlen(zRepo)-1; i>0 && zRepo[i]!='/'; i--){} |
| 694 | if( zRepo[i]=='/' ){ |
| 695 | zRepo[i] = 0; |
| 696 | chdir(g.argv[2]); |
| 697 | chroot(g.argv[2]); |
| 698 | g.argv[2] = &zRepo[i+1]; |
| 699 | } |
| 700 | if( stat(g.argv[2], &sStat)!=0 ){ |
| 701 | fossil_fatal("cannot stat() repository: %s", g.argv[2]); |
| 702 | } |
| 703 | setgid(sStat.st_gid); |
| 704 | setuid(sStat.st_uid); |
| 705 | } |
| 706 | #endif |
| 707 | g.cgiPanic = 1; |
| 708 | g.fullHttpReply = 1; |
| 709 | if( g.argc==6 ){ |
| 710 | g.httpIn = fopen(g.argv[3], "rb"); |
| 711 | g.httpOut = fopen(g.argv[4], "wb"); |
| 712 |
+3
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -410,10 +410,13 @@ | ||
| 410 | 410 | /* |
| 411 | 411 | ** WEBPAGE: test_env |
| 412 | 412 | */ |
| 413 | 413 | void page_test_env(void){ |
| 414 | 414 | style_header("Environment Test"); |
| 415 | +#if !defined(__MINGW32__) | |
| 416 | + @ uid=%d(getuid()), gid=%d(getgid())<br> | |
| 417 | +#endif | |
| 415 | 418 | @ g.zBaseURL = %h(g.zBaseURL)<br> |
| 416 | 419 | @ g.zTop = %h(g.zTop)<br> |
| 417 | 420 | cgi_print_all(); |
| 418 | 421 | style_footer(); |
| 419 | 422 | } |
| 420 | 423 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -410,10 +410,13 @@ | |
| 410 | /* |
| 411 | ** WEBPAGE: test_env |
| 412 | */ |
| 413 | void page_test_env(void){ |
| 414 | style_header("Environment Test"); |
| 415 | @ g.zBaseURL = %h(g.zBaseURL)<br> |
| 416 | @ g.zTop = %h(g.zTop)<br> |
| 417 | cgi_print_all(); |
| 418 | style_footer(); |
| 419 | } |
| 420 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -410,10 +410,13 @@ | |
| 410 | /* |
| 411 | ** WEBPAGE: test_env |
| 412 | */ |
| 413 | void page_test_env(void){ |
| 414 | style_header("Environment Test"); |
| 415 | #if !defined(__MINGW32__) |
| 416 | @ uid=%d(getuid()), gid=%d(getgid())<br> |
| 417 | #endif |
| 418 | @ g.zBaseURL = %h(g.zBaseURL)<br> |
| 419 | @ g.zTop = %h(g.zTop)<br> |
| 420 | cgi_print_all(); |
| 421 | style_footer(); |
| 422 | } |
| 423 |