Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1219823

Browse files
committed
Add safeguards for pg_fsync() called with incorrectly-opened fds
On some platforms, fsync() returns EBADFD when opening a file descriptorwith O_RDONLY (read-only), leading ultimately now to a PANIC to preventdata corruption.This commit adds a new sanity check in pg_fsync() based on fcntl() tomake sure that we don't repeat again mistakes with incorrectly-set filedescriptors so as problems are detected at an early stage. Withoutthat, such errors could only be detected after running Postgres on aspecific supported platform for the culprit code path, which could takesome time before being found.b8e19b9 was a fix for such a problem,which got undetected for more than 5 years, anda586cc4 fixed anothersimilar issue.Note that the new check added works as well when fsync=off isconfigured, so as all regression tests would detect problems as long asassertions are enabled. fcntl() being not available on Windows, thenew checks do not happen there.Author: Michael PaquierReviewed-by: Mark DilgerDiscussion:https://postgr.es/m/20191009062640.GB21379@paquier.xyz
1 parent080313f commit1219823

File tree

1 file changed

+38
-0
lines changed
  • src/backend/storage/file

1 file changed

+38
-0
lines changed

‎src/backend/storage/file/fd.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,44 @@ static intfsync_parent_path(const char *fname, int elevel);
329329
int
330330
pg_fsync(intfd)
331331
{
332+
#if !defined(WIN32)&& defined(USE_ASSERT_CHECKING)
333+
structstatst;
334+
335+
/*
336+
* Some operating system implementations of fsync() have requirements
337+
* about the file access modes that were used when their file descriptor
338+
* argument was opened, and these requirements differ depending on whether
339+
* the file descriptor is for a directory.
340+
*
341+
* For any file descriptor that may eventually be handed to fsync(), we
342+
* should have opened it with access modes that are compatible with
343+
* fsync() on all supported systems, otherwise the code may not be
344+
* portable, even if it runs ok on the current system.
345+
*
346+
* We assert here that a descriptor for a file was opened with write
347+
* permissions (either O_RDWR or O_WRONLY) and for a directory without
348+
* write permissions (O_RDONLY).
349+
*
350+
* Ignore any fstat errors and let the follow-up fsync() do its work.
351+
* Doing this sanity check here counts for the case where fsync() is
352+
* disabled.
353+
*/
354+
if (fstat(fd,&st)==0)
355+
{
356+
intdesc_flags=fcntl(fd,F_GETFL);
357+
358+
/*
359+
* O_RDONLY is historically 0, so just make sure that for directories
360+
* no write flags are used.
361+
*/
362+
if (S_ISDIR(st.st_mode))
363+
Assert((desc_flags& (O_RDWR |O_WRONLY))==0);
364+
else
365+
Assert((desc_flags& (O_RDWR |O_WRONLY))!=0);
366+
}
367+
errno=0;
368+
#endif
369+
332370
/* #if is to skip the sync_method test if there's no need for it */
333371
#if defined(HAVE_FSYNC_WRITETHROUGH)&& !defined(FSYNC_WRITETHROUGH_IS_FSYNC)
334372
if (sync_method==SYNC_METHOD_FSYNC_WRITETHROUGH)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp