Skip to content

Fix GH-19320: Prevent FPM UID and GID overflow - #22986

Open
prateekbhujel wants to merge 1 commit into
php:PHP-8.4from
prateekbhujel:prateek/fix-gh-19320-fpm-id-overflow
Open

Fix GH-19320: Prevent FPM UID and GID overflow#22986
prateekbhujel wants to merge 1 commit into
php:PHP-8.4from
prateekbhujel:prateek/fix-gh-19320-fpm-id-overflow

Conversation

@prateekbhujel

Copy link
Copy Markdown
Contributor

FPM parses numeric user, group, listen.owner, and listen.group values with strtoul(), but stores them in signed int fields. That can silently change an ID before it reaches setuid(), setgid(), or chown().

This stores the values in uid_t/gid_t and rejects IDs that the platform types cannot represent during config validation. It also rejects the all-bits-one value used by chown() as its no-change sentinel.

I added coverage for all four numeric directives and ran the full FPM test suite.

Fixes GH-19320

@bukka bukka left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic makes sense to me. Just not sure about that shift if it's safe. If someone could re-check that would be great.

Comment thread sapi/fpm/fpm/fpm_unix.c
{
uintmax_t max = (uid_t) -1 > (uid_t) 0
? (uintmax_t) ((uid_t) -2)
: (UINTMAX_C(1) << (sizeof(uid_t) * CHAR_BIT - 1)) - 1;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should someone re-check but couldn't that shift be in some cases undefined (e.g. on 32bit)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I re-checked this. UINTMAX_C(1) makes the left operand an unsigned uintmax_t, so on a 32-bit system this is a shift by 31 and is defined. uintmax_t is required to be able to represent any unsigned integer type, and this branch is only used when uid_t is signed. So this should be safe here, but I can add a short comment if you think it would make the intent clearer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants