Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | When writing files to disk for a check-out, refuse to write through a symbolic link to a directory. Ticket [f9831fdef1d4edcc]. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | sec2020 |
| Files: | files | file ages | folders |
| SHA3-256: |
a64e384f0c53ddce4cc0b1f46a671c07 |
| User & Date: | drh 2020-08-18 12:17:39.566 |
Context
|
2020-08-19
| ||
| 01:07 | Cherrypick key fixes from the sec2020 branch in order to devise a minimal patch to get us to version 2.12.1. check-in: fe1264d35d user: drh tags: sec2020-2.12-patch | |
|
2020-08-18
| ||
| 13:17 | More missing db_unprotect() calls. check-in: 06d3789a2a user: drh tags: sec2020 | |
| 12:17 | When writing files to disk for a check-out, refuse to write through a symbolic link to a directory. Ticket [f9831fdef1d4edcc]. check-in: a64e384f0c user: drh tags: sec2020 | |
| 02:58 | More missing calls to db_unprotect(). check-in: 3ced48bdf8 user: drh tags: sec2020 | |
Changes
Changes to src/file.c.
| ︙ | ︙ | |||
321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
** This routines RepoFILE - that zFilename is always a file under management.
**
** On Windows, always return False.
*/
int file_islink(const char *zFilename){
return file_perm(zFilename, RepoFILE)==PERM_LNK;
}
/*
** Return 1 if zFilename is a directory. Return 0 if zFilename
** does not exist. Return 2 if zFilename exists but is something
** other than a directory.
*/
int file_isdir(const char *zFilename, int eFType){
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
** This routines RepoFILE - that zFilename is always a file under management.
**
** On Windows, always return False.
*/
int file_islink(const char *zFilename){
return file_perm(zFilename, RepoFILE)==PERM_LNK;
}
/*
** Check every sub-directory of zRoot along the path to zFile.
** If any sub-directory is really an ordinary file or a symbolic link,
** then delete that object. The inputs are expected to be full
** pathnames.
**
** Example: Given inputs
**
** zRoot = /home/alice/project1
** zFile = /home/alice/project1/main/src/js/fileA.js
**
** Look for objects in the following order:
**
** /home/alice/project/main
** /home/alice/project/main/src
** /home/alice/project/main/src/js
**
** If any of those objects exist and are something other than a directory
** then delete the object and return.
*/
void file_delete_objects_on_path(const char *zRoot, const char *zFile){
int i = (int)strlen(zRoot);
char *z = fossil_strdup(zFile);
assert( fossil_strnicmp(zRoot, z, i)==0 );
if( i && zRoot[i-1]=='/' ) i--;
while( z[i]=='/' ){
int j, rc;
for(j=i+1; z[j] && z[j]!='/'; j++){}
if( z[j]!='/' ) break;
z[j] = 0;
rc = file_isdir(z, SymFILE);
if( rc!=1 ){
if( rc==2 ) file_delete(z);
break;
}
z[j] = '/';
i = j;
}
fossil_free(z);
}
/*
** Return 1 if zFilename is a directory. Return 0 if zFilename
** does not exist. Return 2 if zFilename exists but is something
** other than a directory.
*/
int file_isdir(const char *zFilename, int eFType){
|
| ︙ | ︙ | |||
568 569 570 571 572 573 574 |
** zFilename is a symbolic link, it is the object that zFilename points
** to that is modified.
*/
int file_setexe(const char *zFilename, int onoff){
int rc = 0;
#if !defined(_WIN32)
struct stat buf;
| | > > > | 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 |
** zFilename is a symbolic link, it is the object that zFilename points
** to that is modified.
*/
int file_setexe(const char *zFilename, int onoff){
int rc = 0;
#if !defined(_WIN32)
struct stat buf;
if( fossil_stat(zFilename, &buf, RepoFILE)!=0
|| S_ISLNK(buf.st_mode)
|| S_ISDIR(buf.st_mode)
){
return 0;
}
if( onoff ){
int targetMode = (buf.st_mode & 0444)>>2;
if( (buf.st_mode & 0100)==0 ){
chmod(zFilename, buf.st_mode | targetMode);
rc = 1;
|
| ︙ | ︙ |
Changes to src/vfile.c.
| ︙ | ︙ | |||
337 338 339 340 341 342 343 344 345 346 347 348 349 350 |
promptFlag = 0;
} else if( cReply!='y' && cReply!='Y' ){
blob_reset(&content);
continue;
}
}
if( verbose ) fossil_print("%s\n", &zName[nRepos]);
if( file_isdir(zName, RepoFILE)==1 ){
/*TODO(dchest): remove directories? */
fossil_fatal("%s is directory, cannot overwrite", zName);
}
if( file_size(zName, RepoFILE)>=0 && (isLink || file_islink(0)) ){
file_delete(zName);
}
| > | 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 |
promptFlag = 0;
} else if( cReply!='y' && cReply!='Y' ){
blob_reset(&content);
continue;
}
}
if( verbose ) fossil_print("%s\n", &zName[nRepos]);
file_delete_objects_on_path(g.zLocalRoot, zName);
if( file_isdir(zName, RepoFILE)==1 ){
/*TODO(dchest): remove directories? */
fossil_fatal("%s is directory, cannot overwrite", zName);
}
if( file_size(zName, RepoFILE)>=0 && (isLink || file_islink(0)) ){
file_delete(zName);
}
|
| ︙ | ︙ |