Fossil SCM

Fixed the --chroot flag to "fossil server" and "fossil http" to allow it to work in conjunction with the single-repository case. Before, it blindly assumed --repolist mode.

wyoung 2022-08-13 21:21 UTC trunk
Commit 6f92ad99d992f61c0dee9b3f67422f877ae5917e1fac601714a16e172d4d37ac
1 file changed +24 -15
+24 -15
--- src/main.c
+++ src/main.c
@@ -1471,21 +1471,24 @@
14711471
/*
14721472
** If running as root, chroot to the directory containing the
14731473
** repository zRepo and then drop root privileges. Return the
14741474
** new repository name.
14751475
**
1476
-** zRepo might be a directory itself. In that case chroot into
1477
-** the directory zRepo.
1476
+** zRepo can be a directory. If so and if the repo name was saved
1477
+** to g.zRepositoryName before we were called, we canonicalize the
1478
+** two paths and check that one is the prefix of the other, else you
1479
+** won't be able to open the repo inside the jail. If it all works
1480
+** out, we return the "jailed" version of the repo name.
14781481
**
14791482
** Assume the user-id and group-id of the repository, or if zRepo
14801483
** is a directory, of that directory.
14811484
**
14821485
** The noJail flag means that the chroot jail is not entered. But
14831486
** privileges are still lowered to that of the user-id and group-id
14841487
** of the repository file.
14851488
*/
1486
-char *enter_chroot_jail(char *zRepo, int noJail){
1489
+static char *enter_chroot_jail(const char *zRepo, int noJail){
14871490
#if !defined(_WIN32)
14881491
if( getuid()==0 ){
14891492
int i;
14901493
struct stat sStat;
14911494
Blob dir;
@@ -1500,11 +1503,23 @@
15001503
if( file_isdir(zDir, ExtFILE)==1 ){
15011504
if( file_chdir(zDir, 1) ){
15021505
fossil_panic("unable to chroot into %s", zDir);
15031506
}
15041507
g.fJail = 1;
1505
- zRepo = "/";
1508
+ if( g.zRepositoryName ){
1509
+ size_t n = strlen(zDir);
1510
+ Blob repo;
1511
+ file_canonical_name(g.zRepositoryName, &repo, 0);
1512
+ zRepo = blob_str(&repo);
1513
+ if( strncmp(zRepo, zDir, n)!=0 ){
1514
+ fossil_fatal("repo %s not under chroot dir %s", zRepo, zDir);
1515
+ }
1516
+ zRepo += n;
1517
+ if( *zRepo == '\0' ) zRepo = "/";
1518
+ }else {
1519
+ zRepo = "/";
1520
+ }
15061521
}else{
15071522
for(i=strlen(zDir)-1; i>0 && zDir[i]!='/'; i--){}
15081523
if( zDir[i]!='/' ) fossil_fatal("bad repository name: %s", zRepo);
15091524
if( i>0 ){
15101525
zDir[i] = 0;
@@ -1527,11 +1542,11 @@
15271542
if( g.db==0 && file_isfile(zRepo, ExtFILE) ){
15281543
db_open_repository(zRepo);
15291544
}
15301545
}
15311546
#endif
1532
- return zRepo;
1547
+ return (char*)zRepo; /* no longer const: always reassigned from blob_str() */
15331548
}
15341549
15351550
/*
15361551
** Called whenever a crash is encountered while processing a webpage.
15371552
*/
@@ -2814,15 +2829,12 @@
28142829
zIpAddr = cgi_ssh_remote_addr(0);
28152830
if( zIpAddr && zIpAddr[0] ){
28162831
g.fSshClient |= CGI_SSH_CLIENT;
28172832
}
28182833
}
2819
- if( zChRoot ){
2820
- enter_chroot_jail((char*)zChRoot, noJail);
2821
- }else{
2822
- g.zRepositoryName = enter_chroot_jail(g.zRepositoryName, noJail);
2823
- }
2834
+ g.zRepositoryName = enter_chroot_jail(
2835
+ zChRoot ? zChRoot : g.zRepositoryName, noJail);
28242836
if( useSCGI ){
28252837
cgi_handle_scgi_request();
28262838
}else if( g.fSshClient & CGI_SSH_CLIENT ){
28272839
ssh_request_loop(zIpAddr, glob_create(zFileGlob));
28282840
}else{
@@ -3319,15 +3331,12 @@
33193331
g.cgiOutput = 1;
33203332
find_server_repository(2, 0);
33213333
if( fossil_strcmp(g.zRepositoryName,"/")==0 ){
33223334
allowRepoList = 1;
33233335
}else{
3324
- if( zChRoot ){
3325
- enter_chroot_jail((char*)zChRoot, noJail);
3326
- }else{
3327
- g.zRepositoryName = enter_chroot_jail(g.zRepositoryName, noJail);
3328
- }
3336
+ g.zRepositoryName = enter_chroot_jail(
3337
+ zChRoot ? zChRoot : g.zRepositoryName, noJail);
33293338
}
33303339
if( flags & HTTP_SERVER_SCGI ){
33313340
cgi_handle_scgi_request();
33323341
}else if( g.httpUseSSL ){
33333342
#if FOSSIL_ENABLE_SSL
33343343
--- src/main.c
+++ src/main.c
@@ -1471,21 +1471,24 @@
1471 /*
1472 ** If running as root, chroot to the directory containing the
1473 ** repository zRepo and then drop root privileges. Return the
1474 ** new repository name.
1475 **
1476 ** zRepo might be a directory itself. In that case chroot into
1477 ** the directory zRepo.
 
 
 
1478 **
1479 ** Assume the user-id and group-id of the repository, or if zRepo
1480 ** is a directory, of that directory.
1481 **
1482 ** The noJail flag means that the chroot jail is not entered. But
1483 ** privileges are still lowered to that of the user-id and group-id
1484 ** of the repository file.
1485 */
1486 char *enter_chroot_jail(char *zRepo, int noJail){
1487 #if !defined(_WIN32)
1488 if( getuid()==0 ){
1489 int i;
1490 struct stat sStat;
1491 Blob dir;
@@ -1500,11 +1503,23 @@
1500 if( file_isdir(zDir, ExtFILE)==1 ){
1501 if( file_chdir(zDir, 1) ){
1502 fossil_panic("unable to chroot into %s", zDir);
1503 }
1504 g.fJail = 1;
1505 zRepo = "/";
 
 
 
 
 
 
 
 
 
 
 
 
1506 }else{
1507 for(i=strlen(zDir)-1; i>0 && zDir[i]!='/'; i--){}
1508 if( zDir[i]!='/' ) fossil_fatal("bad repository name: %s", zRepo);
1509 if( i>0 ){
1510 zDir[i] = 0;
@@ -1527,11 +1542,11 @@
1527 if( g.db==0 && file_isfile(zRepo, ExtFILE) ){
1528 db_open_repository(zRepo);
1529 }
1530 }
1531 #endif
1532 return zRepo;
1533 }
1534
1535 /*
1536 ** Called whenever a crash is encountered while processing a webpage.
1537 */
@@ -2814,15 +2829,12 @@
2814 zIpAddr = cgi_ssh_remote_addr(0);
2815 if( zIpAddr && zIpAddr[0] ){
2816 g.fSshClient |= CGI_SSH_CLIENT;
2817 }
2818 }
2819 if( zChRoot ){
2820 enter_chroot_jail((char*)zChRoot, noJail);
2821 }else{
2822 g.zRepositoryName = enter_chroot_jail(g.zRepositoryName, noJail);
2823 }
2824 if( useSCGI ){
2825 cgi_handle_scgi_request();
2826 }else if( g.fSshClient & CGI_SSH_CLIENT ){
2827 ssh_request_loop(zIpAddr, glob_create(zFileGlob));
2828 }else{
@@ -3319,15 +3331,12 @@
3319 g.cgiOutput = 1;
3320 find_server_repository(2, 0);
3321 if( fossil_strcmp(g.zRepositoryName,"/")==0 ){
3322 allowRepoList = 1;
3323 }else{
3324 if( zChRoot ){
3325 enter_chroot_jail((char*)zChRoot, noJail);
3326 }else{
3327 g.zRepositoryName = enter_chroot_jail(g.zRepositoryName, noJail);
3328 }
3329 }
3330 if( flags & HTTP_SERVER_SCGI ){
3331 cgi_handle_scgi_request();
3332 }else if( g.httpUseSSL ){
3333 #if FOSSIL_ENABLE_SSL
3334
--- src/main.c
+++ src/main.c
@@ -1471,21 +1471,24 @@
1471 /*
1472 ** If running as root, chroot to the directory containing the
1473 ** repository zRepo and then drop root privileges. Return the
1474 ** new repository name.
1475 **
1476 ** zRepo can be a directory. If so and if the repo name was saved
1477 ** to g.zRepositoryName before we were called, we canonicalize the
1478 ** two paths and check that one is the prefix of the other, else you
1479 ** won't be able to open the repo inside the jail. If it all works
1480 ** out, we return the "jailed" version of the repo name.
1481 **
1482 ** Assume the user-id and group-id of the repository, or if zRepo
1483 ** is a directory, of that directory.
1484 **
1485 ** The noJail flag means that the chroot jail is not entered. But
1486 ** privileges are still lowered to that of the user-id and group-id
1487 ** of the repository file.
1488 */
1489 static char *enter_chroot_jail(const char *zRepo, int noJail){
1490 #if !defined(_WIN32)
1491 if( getuid()==0 ){
1492 int i;
1493 struct stat sStat;
1494 Blob dir;
@@ -1500,11 +1503,23 @@
1503 if( file_isdir(zDir, ExtFILE)==1 ){
1504 if( file_chdir(zDir, 1) ){
1505 fossil_panic("unable to chroot into %s", zDir);
1506 }
1507 g.fJail = 1;
1508 if( g.zRepositoryName ){
1509 size_t n = strlen(zDir);
1510 Blob repo;
1511 file_canonical_name(g.zRepositoryName, &repo, 0);
1512 zRepo = blob_str(&repo);
1513 if( strncmp(zRepo, zDir, n)!=0 ){
1514 fossil_fatal("repo %s not under chroot dir %s", zRepo, zDir);
1515 }
1516 zRepo += n;
1517 if( *zRepo == '\0' ) zRepo = "/";
1518 }else {
1519 zRepo = "/";
1520 }
1521 }else{
1522 for(i=strlen(zDir)-1; i>0 && zDir[i]!='/'; i--){}
1523 if( zDir[i]!='/' ) fossil_fatal("bad repository name: %s", zRepo);
1524 if( i>0 ){
1525 zDir[i] = 0;
@@ -1527,11 +1542,11 @@
1542 if( g.db==0 && file_isfile(zRepo, ExtFILE) ){
1543 db_open_repository(zRepo);
1544 }
1545 }
1546 #endif
1547 return (char*)zRepo; /* no longer const: always reassigned from blob_str() */
1548 }
1549
1550 /*
1551 ** Called whenever a crash is encountered while processing a webpage.
1552 */
@@ -2814,15 +2829,12 @@
2829 zIpAddr = cgi_ssh_remote_addr(0);
2830 if( zIpAddr && zIpAddr[0] ){
2831 g.fSshClient |= CGI_SSH_CLIENT;
2832 }
2833 }
2834 g.zRepositoryName = enter_chroot_jail(
2835 zChRoot ? zChRoot : g.zRepositoryName, noJail);
 
 
 
2836 if( useSCGI ){
2837 cgi_handle_scgi_request();
2838 }else if( g.fSshClient & CGI_SSH_CLIENT ){
2839 ssh_request_loop(zIpAddr, glob_create(zFileGlob));
2840 }else{
@@ -3319,15 +3331,12 @@
3331 g.cgiOutput = 1;
3332 find_server_repository(2, 0);
3333 if( fossil_strcmp(g.zRepositoryName,"/")==0 ){
3334 allowRepoList = 1;
3335 }else{
3336 g.zRepositoryName = enter_chroot_jail(
3337 zChRoot ? zChRoot : g.zRepositoryName, noJail);
 
 
 
3338 }
3339 if( flags & HTTP_SERVER_SCGI ){
3340 cgi_handle_scgi_request();
3341 }else if( g.httpUseSSL ){
3342 #if FOSSIL_ENABLE_SSL
3343

Keyboard Shortcuts

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