Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch overwrite-avoidance Excluding Merge-Ins
This is equivalent to a diff from d4b6ad33 to 66dddda0
2013-08-29
| ||
23:36 | Make the unix VFS defensive against the error of having a database file open on file descriptors 1 or 2, as an error message might easily be written onto those file descriptors and thus overwrite and corrupt the database. (check-in: 30d38cc4 user: drh tags: trunk) | |
23:34 | Change the unix VFS so that it refuses to open a database file using a file descriptor less than 3. (Closed-Leaf check-in: 66dddda0 user: drh tags: overwrite-avoidance) | |
21:26 | Never leave an open file descriptor pointing into the middle of the database file if the file descriptor number is 2 or less. (check-in: 3426673e user: drh tags: overwrite-avoidance) | |
15:08 | Merge from trunk: (1) Recent bug fixes (2) STAT4 support (3) win32-longpath support. (check-in: e7ebc8f7 user: drh tags: sessions) | |
14:56 | Restore fix [f15591f802], which was accidentally clobbered by the stat4 merge. (check-in: d4b6ad33 user: dan tags: trunk) | |
10:46 | Candidate fix for [9f2eb3abac]: Have the whereShortCut() planner ignore indexes with more than four columns. (check-in: c1152bdc user: dan tags: trunk) | |
Changes to src/os_unix.c.
︙ | ︙ | |||
546 547 548 549 550 551 552 553 554 555 556 557 558 559 | } } for(i++; i<ArraySize(aSyscall); i++){ if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName; } return 0; } /* ** Invoke open(). Do so multiple times, until it either succeeds or ** fails for some reason other than EINTR. ** ** If the file creation mode "m" is 0 then set it to the default for ** SQLite. The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally | > > > > > > > > > > > > > > > > > > > > > > > > > | 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 | } } for(i++; i<ArraySize(aSyscall); i++){ if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName; } return 0; } /* ** If fd is a file descriptor that would be dangerous to use for an ** ordinary file, the close it, reopen it as /dev/null to get it out ** of the way, then return true. ** ** If fd is safe, return 0. ** ** It is dangerous to have a database file open of file descriptors 1 or ** 2 because those normally mean standard output and standard error. Other ** components of the system might write directly to those file descriptors ** and overwrite parts of the database file. Something like this happened ** on 2013-08-29 to the canonical Fossil repository when some error caused ** the database file to be opened on file descriptor 2 and later an assert() ** fired and wrote error message text into file descriptor 2, corrupting ** the repository. */ static int isReservedFd(int fd, const char *z, int f, int m){ if( fd<0 || fd>2 ) return 0; sqlite3_log(SQLITE_WARNING, "attempt to open \"%s\" as file descriptor %d", z, fd); osClose(fd); (void)osOpen("/dev/null",f,m); return 1; } /* ** Invoke open(). Do so multiple times, until it either succeeds or ** fails for some reason other than EINTR. ** ** If the file creation mode "m" is 0 then set it to the default for ** SQLite. The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally |
︙ | ︙ | |||
573 574 575 576 577 578 579 | mode_t m2 = m ? m : SQLITE_DEFAULT_FILE_PERMISSIONS; do{ #if defined(O_CLOEXEC) fd = osOpen(z,f|O_CLOEXEC,m2); #else fd = osOpen(z,f,m2); #endif | | | 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 | mode_t m2 = m ? m : SQLITE_DEFAULT_FILE_PERMISSIONS; do{ #if defined(O_CLOEXEC) fd = osOpen(z,f|O_CLOEXEC,m2); #else fd = osOpen(z,f,m2); #endif }while( (fd<0 && errno==EINTR) || isReservedFd(fd,z,f,m2) ); if( fd>=0 ){ if( m!=0 ){ struct stat statbuf; if( osFstat(fd, &statbuf)==0 && statbuf.st_size==0 && (statbuf.st_mode&0777)!=m ){ |
︙ | ︙ | |||
3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 | int got; int prior = 0; #if (!defined(USE_PREAD) && !defined(USE_PREAD64)) i64 newOffset; #endif TIMER_START; assert( cnt==(cnt&0x1ffff) ); cnt &= 0x1ffff; do{ #if defined(USE_PREAD) got = osPread(id->h, pBuf, cnt, offset); SimulateIOError( got = -1 ); #elif defined(USE_PREAD64) got = osPread64(id->h, pBuf, cnt, offset); | > | 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 | int got; int prior = 0; #if (!defined(USE_PREAD) && !defined(USE_PREAD64)) i64 newOffset; #endif TIMER_START; assert( cnt==(cnt&0x1ffff) ); assert( id->h>2 ); cnt &= 0x1ffff; do{ #if defined(USE_PREAD) got = osPread(id->h, pBuf, cnt, offset); SimulateIOError( got = -1 ); #elif defined(USE_PREAD64) got = osPread64(id->h, pBuf, cnt, offset); |
︙ | ︙ | |||
3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 | const void *pBuf, /* Copy data from this buffer to the file */ int nBuf, /* Size of buffer pBuf in bytes */ int *piErrno /* OUT: Error number if error occurs */ ){ int rc = 0; /* Value returned by system call */ assert( nBuf==(nBuf&0x1ffff) ); nBuf &= 0x1ffff; TIMER_START; #if defined(USE_PREAD) do{ rc = osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR ); #elif defined(USE_PREAD64) do{ rc = osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR); | > | 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 | const void *pBuf, /* Copy data from this buffer to the file */ int nBuf, /* Size of buffer pBuf in bytes */ int *piErrno /* OUT: Error number if error occurs */ ){ int rc = 0; /* Value returned by system call */ assert( nBuf==(nBuf&0x1ffff) ); assert( fd>2 ); nBuf &= 0x1ffff; TIMER_START; #if defined(USE_PREAD) do{ rc = osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR ); #elif defined(USE_PREAD64) do{ rc = osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR); |
︙ | ︙ |