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

Commit571addd

Browse files
committed
Fix unsafe references to errno within error messaging logic.
Various places were supposing that errno could be expected to hold stillwithin an ereport() nest or similar contexts. This isn't true necessarily,though in some cases it accidentally failed to fail depending on how thecompiler chanced to order the subexpressions. This class of thinkoexplains recent reports of odd failures on clang-built versions, typicallymissing or inappropriate HINT fields in messages.Problem identified by Christian Kruse, who also submitted the patch thiscommit is based on. (I fixed a few issues in his patch and found a coupleof additional places with the same disease.)Back-patch as appropriate to all supported branches.
1 parent120c5cc commit571addd

File tree

5 files changed

+44
-27
lines changed

5 files changed

+44
-27
lines changed

‎src/backend/commands/tablespace.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,10 +782,14 @@ destroy_tablespace_directories(Oid tablespaceoid, bool redo)
782782
else
783783
{
784784
if (unlink(linkloc)<0)
785-
ereport(redo ?LOG : (errno==ENOENT ?WARNING :ERROR),
785+
{
786+
intsaved_errno=errno;
787+
788+
ereport(redo ?LOG : (saved_errno==ENOENT ?WARNING :ERROR),
786789
(errcode_for_file_access(),
787790
errmsg("could not remove symbolic link \"%s\": %m",
788791
linkloc)));
792+
}
789793
}
790794

791795
pfree(linkloc_with_version_dir);

‎src/backend/port/sysv_sema.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,17 @@ InternalIpcSemaphoreCreate(IpcSemaphoreKey semKey, int numSems)
9191

9292
if (semId<0)
9393
{
94+
intsaved_errno=errno;
95+
9496
/*
9597
* Fail quietly if error indicates a collision with existing set. One
9698
* would expect EEXIST, given that we said IPC_EXCL, but perhaps we
9799
* could get a permission violation instead? Also, EIDRM might occur
98100
* if an old set is slated for destruction but not gone yet.
99101
*/
100-
if (errno==EEXIST||errno==EACCES
102+
if (saved_errno==EEXIST||saved_errno==EACCES
101103
#ifdefEIDRM
102-
||errno==EIDRM
104+
||saved_errno==EIDRM
103105
#endif
104106
)
105107
return-1;
@@ -112,7 +114,7 @@ InternalIpcSemaphoreCreate(IpcSemaphoreKey semKey, int numSems)
112114
errdetail("Failed system call was semget(%lu, %d, 0%o).",
113115
(unsigned long)semKey,numSems,
114116
IPC_CREAT |IPC_EXCL |IPCProtection),
115-
(errno==ENOSPC) ?
117+
(saved_errno==ENOSPC) ?
116118
errhint("This error does *not* mean that you have run out of disk space. "
117119
"It occurs when either the system limit for the maximum number of "
118120
"semaphore sets (SEMMNI), or the system wide maximum number of "
@@ -136,13 +138,17 @@ IpcSemaphoreInitialize(IpcSemaphoreId semId, int semNum, int value)
136138

137139
semun.val=value;
138140
if (semctl(semId,semNum,SETVAL,semun)<0)
141+
{
142+
intsaved_errno=errno;
143+
139144
ereport(FATAL,
140145
(errmsg_internal("semctl(%d, %d, SETVAL, %d) failed: %m",
141146
semId,semNum,value),
142-
(errno==ERANGE) ?
147+
(saved_errno==ERANGE) ?
143148
errhint("You possibly need to raise your kernel's SEMVMX value to be at least "
144149
"%d. Look into the PostgreSQL documentation for details.",
145150
value) :0));
151+
}
146152
}
147153

148154
/*

‎src/backend/port/sysv_shmem.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,17 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
7373

7474
if (shmid<0)
7575
{
76+
intshmget_errno=errno;
77+
7678
/*
7779
* Fail quietly if error indicates a collision with existing segment.
7880
* One would expect EEXIST, given that we said IPC_EXCL, but perhaps
7981
* we could get a permission violation instead? Also, EIDRM might
8082
* occur if an old seg is slated for destruction but not gone yet.
8183
*/
82-
if (errno==EEXIST||errno==EACCES
84+
if (shmget_errno==EEXIST||shmget_errno==EACCES
8385
#ifdefEIDRM
84-
||errno==EIDRM
86+
||shmget_errno==EIDRM
8587
#endif
8688
)
8789
returnNULL;
@@ -95,10 +97,8 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
9597
* against SHMMIN in the preexisting-segment case, so we will not get
9698
* EINVAL a second time if there is such a segment.
9799
*/
98-
if (errno==EINVAL)
100+
if (shmget_errno==EINVAL)
99101
{
100-
intsave_errno=errno;
101-
102102
shmid=shmget(memKey,0,IPC_CREAT |IPC_EXCL |IPCProtection);
103103

104104
if (shmid<0)
@@ -124,8 +124,6 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
124124
elog(LOG,"shmctl(%d, %d, 0) failed: %m",
125125
(int)shmid,IPC_RMID);
126126
}
127-
128-
errno=save_errno;
129127
}
130128

131129
/*
@@ -137,25 +135,26 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
137135
* it should be. SHMMNI violation is ENOSPC, per spec. Just plain
138136
* not-enough-RAM is ENOMEM.
139137
*/
138+
errno=shmget_errno;
140139
ereport(FATAL,
141140
(errmsg("could not create shared memory segment: %m"),
142141
errdetail("Failed system call was shmget(key=%lu, size=%zu, 0%o).",
143142
(unsigned long)memKey,size,
144143
IPC_CREAT |IPC_EXCL |IPCProtection),
145-
(errno==EINVAL) ?
144+
(shmget_errno==EINVAL) ?
146145
errhint("This error usually means that PostgreSQL's request for a shared memory "
147146
"segment exceeded your kernel's SHMMAX parameter, or possibly that "
148147
"it is less than "
149148
"your kernel's SHMMIN parameter.\n"
150149
"The PostgreSQL documentation contains more information about shared "
151150
"memory configuration.") :0,
152-
(errno==ENOMEM) ?
151+
(shmget_errno==ENOMEM) ?
153152
errhint("This error usually means that PostgreSQL's request for a shared "
154153
"memory segment exceeded your kernel's SHMALL parameter. You might need "
155154
"to reconfigure the kernel with larger SHMALL.\n"
156155
"The PostgreSQL documentation contains more information about shared "
157156
"memory configuration.") :0,
158-
(errno==ENOSPC) ?
157+
(shmget_errno==ENOSPC) ?
159158
errhint("This error does *not* mean that you have run out of disk space. "
160159
"It occurs either if all available shared memory IDs have been taken, "
161160
"in which case you need to raise the SHMMNI parameter in your kernel, "
@@ -331,6 +330,7 @@ CreateAnonymousSegment(Size *size)
331330
{
332331
Sizeallocsize=*size;
333332
void*ptr=MAP_FAILED;
333+
intmmap_errno=0;
334334

335335
#ifndefMAP_HUGETLB
336336
if (huge_tlb_pages==HUGE_TLB_ON)
@@ -363,6 +363,7 @@ CreateAnonymousSegment(Size *size)
363363

364364
ptr=mmap(NULL,allocsize,PROT_READ |PROT_WRITE,
365365
PG_MMAP_FLAGS |MAP_HUGETLB,-1,0);
366+
mmap_errno=errno;
366367
if (huge_tlb_pages==HUGE_TLB_TRY&&ptr==MAP_FAILED)
367368
elog(DEBUG1,"mmap with MAP_HUGETLB failed, huge pages disabled: %m");
368369
}
@@ -376,20 +377,25 @@ CreateAnonymousSegment(Size *size)
376377
* back to non-huge pages.
377378
*/
378379
allocsize=*size;
379-
ptr=mmap(NULL,allocsize,PROT_READ |PROT_WRITE,PG_MMAP_FLAGS,-1,0);
380+
ptr=mmap(NULL,allocsize,PROT_READ |PROT_WRITE,
381+
PG_MMAP_FLAGS,-1,0);
382+
mmap_errno=errno;
380383
}
381384

382385
if (ptr==MAP_FAILED)
386+
{
387+
errno=mmap_errno;
383388
ereport(FATAL,
384389
(errmsg("could not map anonymous shared memory: %m"),
385-
(errno==ENOMEM) ?
390+
(mmap_errno==ENOMEM) ?
386391
errhint("This error usually means that PostgreSQL's request "
387392
"for a shared memory segment exceeded available memory, "
388393
"swap space or huge pages. To reduce the request size "
389394
"(currently %zu bytes), reduce PostgreSQL's shared "
390395
"memory usage, perhaps by reducing shared_buffers or "
391396
"max_connections.",
392397
*size) :0));
398+
}
393399

394400
*size=allocsize;
395401
returnptr;

‎src/bin/psql/command.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -264,14 +264,15 @@ exec_command(const char *cmd,
264264
{
265265
#ifndefWIN32
266266
structpasswd*pw;
267+
uid_tuser_id=geteuid();
267268

268-
errno=0;/* clear errno before call */
269-
pw=getpwuid(geteuid());
269+
errno=0;/* clear errno before call */
270+
pw=getpwuid(user_id);
270271
if (!pw)
271272
{
272-
psql_error("could not get home directory for user id %d: %s\n",
273-
(int)geteuid(),errno ?
274-
strerror(errno) :"user does not exist");
273+
psql_error("could not get home directory for user id %ld: %s\n",
274+
(long)user_id,
275+
errno ?strerror(errno) :_("user does not exist"));
275276
exit(EXIT_FAILURE);
276277
}
277278
dir=pw->pw_dir;

‎src/common/username.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,17 @@ get_user_name(char **errstr)
3434
{
3535
#ifndefWIN32
3636
structpasswd*pw;
37-
uid_tuser_id=geteuid();
37+
uid_tuser_id=geteuid();
3838

3939
*errstr=NULL;
4040

41-
errno=0;/* clear errno before call */
41+
errno=0;/* clear errno before call */
4242
pw=getpwuid(user_id);
4343
if (!pw)
4444
{
45-
*errstr=psprintf(_("failed to look up effective user id %d: %s"),
46-
(int)user_id,errno ?strerror(errno) :
47-
_("user does not exist"));
45+
*errstr=psprintf(_("failed to look up effective user id %ld: %s"),
46+
(long)user_id,
47+
errno ?strerror(errno) :_("user does not exist"));
4848
returnNULL;
4949
}
5050

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp