Skip to content

Commit 3fbca7f

Browse files
authored
Support sysconf(_SC_GETPW_R_SIZE_MAX) == -1 (#13922)
1 parent 686afc1 commit 3fbca7f

File tree

3 files changed

+68
-19
lines changed

3 files changed

+68
-19
lines changed

ext/standard/filestat.c

+30-6
Original file line numberDiff line numberDiff line change
@@ -313,13 +313,25 @@ PHPAPI int php_get_gid_by_name(const char *name, gid_t *gid)
313313
struct group *retgrptr;
314314
long grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
315315
char *grbuf;
316+
int err;
316317

317318
if (grbuflen < 1) {
318-
return FAILURE;
319+
grbuflen = 1024;
319320
}
320-
321+
# if ZEND_DEBUG
322+
/* Test retry logic */
323+
grbuflen = 1;
324+
# endif
321325
grbuf = emalloc(grbuflen);
322-
if (getgrnam_r(name, &gr, grbuf, grbuflen, &retgrptr) != 0 || retgrptr == NULL) {
326+
327+
try_again:
328+
err = getgrnam_r(name, &gr, grbuf, grbuflen, &retgrptr);
329+
if (err != 0 || retgrptr == NULL) {
330+
if (err == ERANGE) {
331+
grbuflen *= 2;
332+
grbuf = erealloc(grbuf, grbuflen);
333+
goto try_again;
334+
}
323335
efree(grbuf);
324336
return FAILURE;
325337
}
@@ -439,13 +451,25 @@ PHPAPI uid_t php_get_uid_by_name(const char *name, uid_t *uid)
439451
struct passwd *retpwptr = NULL;
440452
long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
441453
char *pwbuf;
454+
int err;
442455

443456
if (pwbuflen < 1) {
444-
return FAILURE;
457+
pwbuflen = 1024;
445458
}
446-
459+
# if ZEND_DEBUG
460+
/* Test retry logic */
461+
pwbuflen = 1;
462+
# endif
447463
pwbuf = emalloc(pwbuflen);
448-
if (getpwnam_r(name, &pw, pwbuf, pwbuflen, &retpwptr) != 0 || retpwptr == NULL) {
464+
465+
try_again:
466+
err = getpwnam_r(name, &pw, pwbuf, pwbuflen, &retpwptr);
467+
if (err != 0 || retpwptr == NULL) {
468+
if (err == EAGAIN) {
469+
pwbuflen *= 2;
470+
pwbuf = erealloc(pwbuf, pwbuflen);
471+
goto try_again;
472+
}
449473
efree(pwbuf);
450474
return FAILURE;
451475
}

main/fopen_wrappers.c

+23-11
Original file line numberDiff line numberDiff line change
@@ -362,26 +362,38 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle)
362362

363363
if (s) { /* if there is no path name after the file, do not bother */
364364
char user[32]; /* to try open the directory */
365+
366+
length = s - (path_info + 2);
367+
if (length > sizeof(user) - 1) {
368+
length = sizeof(user) - 1;
369+
}
370+
memcpy(user, path_info + 2, length);
371+
user[length] = '\0';
372+
365373
struct passwd *pw;
366374
#if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
367375
struct passwd pwstruc;
368376
long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
369377
char *pwbuf;
378+
int err;
370379

371380
if (pwbuflen < 1) {
372-
return FAILURE;
381+
pwbuflen = 1024;
373382
}
374-
383+
# if ZEND_DEBUG
384+
/* Test retry logic */
385+
pwbuflen = 1;
386+
# endif
375387
pwbuf = emalloc(pwbuflen);
376-
#endif
377-
length = s - (path_info + 2);
378-
if (length > sizeof(user) - 1) {
379-
length = sizeof(user) - 1;
380-
}
381-
memcpy(user, path_info + 2, length);
382-
user[length] = '\0';
383-
#if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
384-
if (getpwnam_r(user, &pwstruc, pwbuf, pwbuflen, &pw)) {
388+
389+
try_again:
390+
err = getpwnam_r(user, &pwstruc, pwbuf, pwbuflen, &pw);
391+
if (err) {
392+
if (err == ERANGE) {
393+
pwbuflen *= 2;
394+
pwbuf = erealloc(pwbuf, pwbuflen);
395+
goto try_again;
396+
}
385397
efree(pwbuf);
386398
return FAILURE;
387399
}

main/main.c

+15-2
Original file line numberDiff line numberDiff line change
@@ -1460,12 +1460,25 @@ PHPAPI char *php_get_current_user(void)
14601460
struct passwd *retpwptr = NULL;
14611461
int pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
14621462
char *pwbuf;
1463+
int err;
14631464

14641465
if (pwbuflen < 1) {
1465-
return "";
1466+
pwbuflen = 1024;
14661467
}
1468+
# if ZEND_DEBUG
1469+
/* Test retry logic */
1470+
pwbuflen = 1;
1471+
# endif
14671472
pwbuf = emalloc(pwbuflen);
1468-
if (getpwuid_r(pstat->st_uid, &_pw, pwbuf, pwbuflen, &retpwptr) != 0) {
1473+
1474+
try_again:
1475+
err = getpwuid_r(pstat->st_uid, &_pw, pwbuf, pwbuflen, &retpwptr);
1476+
if (err != 0) {
1477+
if (err == ERANGE) {
1478+
pwbuflen *= 2;
1479+
pwbuf = erealloc(pwbuf, pwbuflen);
1480+
goto try_again;
1481+
}
14691482
efree(pwbuf);
14701483
return "";
14711484
}

0 commit comments

Comments
 (0)