Skip to content

Parse /proc/pid/status "Groups" field as u32#334

Merged
eminence merged 1 commit intoeminence:masterfrom
Jongy:fix-status-groups-u32
Feb 8, 2025
Merged

Parse /proc/pid/status "Groups" field as u32#334
eminence merged 1 commit intoeminence:masterfrom
Jongy:fix-status-groups-u32

Conversation

@Jongy
Copy link
Contributor

@Jongy Jongy commented Feb 5, 2025

Groups is printed as unsigned:
https://github.com/torvalds/linux/blob/5c8c229261f14159b54b9a32f12e5fa89d88b905/fs/proc/array.c#L199-L203

I got an error like this:

Err(InternalError(bug at procfs-core/src/process/status.rs:309 (please report this procfs bug)
Internal Unwrap Error: Failed to parse i ("3555555555") as a T: number too large to fit in target type))

(procfs/procfs-core 0.17.0)

I suspect it's the Groups , other users of parse_list are NStgid NSpid NSpgid NSsid (which are also printed unsigned...) but the kernel limits them to 1 billion per the docs here: https://github.com/torvalds/linux/blob/5c8c229261f14159b54b9a32f12e5fa89d88b905/include/linux/threads.h#L30-L35 so it's safe to assume the issue I observed is from Groups, and we don't need to change their type (pid_t is truly signed).

Here's is a small reproducer program:

#include <unistd.h>
#include <stdlib.h>
#include <grp.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

int main() {
    gid_t new_gid = 3555555555;
    int ngroups;
    gid_t *groups;

    // Get current number of supplementary groups
    ngroups = getgroups(0, NULL);
    if (ngroups == -1) {
        printf("getgroups failed: %s\n", strerror(errno));
        return 1;
    }

    // Allocate space for current groups plus one more
    groups = malloc((ngroups + 1) * sizeof(gid_t));
    if (!groups) {
        printf("malloc failed\n");
        return 1;
    }

    // Get current supplementary groups
    if (getgroups(ngroups, groups) == -1) {
        printf("getgroups failed: %s\n", strerror(errno));
        free(groups);
        return 1;
    }

    // Add new group
    groups[ngroups] = new_gid;
    ngroups++;

    // Set new supplementary groups list
    if (setgroups(ngroups, groups) == -1) {
        printf("setgroups failed: %s\n", strerror(errno));
        free(groups);
        return 1;
    }

    free(groups);
    printf("Successfully added GID %u\n", new_gid);

    sleep(9999999);
    return 0;
}

proc.status() on this PID fails on master and works on this PR.

Groups are gid_t which is unsigned.
@Jongy Jongy force-pushed the fix-status-groups-u32 branch from c88277b to 2233ed3 Compare February 5, 2025 11:31
@eminence
Copy link
Owner

eminence commented Feb 8, 2025

Nice find, thank you!

@eminence eminence merged commit f712a74 into eminence:master Feb 8, 2025
6 checks passed
@Jongy Jongy deleted the fix-status-groups-u32 branch February 8, 2025 20:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants