{"record":{"id":"ec1d2d5a4857e96d","repo":"crowdsecurity/crowdsec","slug":"out-of-bound-gid","errorCode":null,"errorMessage":"out of bound gid","messagePattern":"out of bound gid","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/csplugin/utils.go","lineNumber":63,"sourceCode":"\t\treturn 0, err\n\t}\n\tif uid < 0 || uid > math.MaxInt32 {\n\t\treturn 0, errors.New(\"out of bound uid\")\n\t}\n\treturn uint32(uid), nil\n}\n\nfunc getGID(groupname string) (uint32, error) {\n\tg, err := user.LookupGroup(groupname)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tgid, err := strconv.ParseInt(g.Gid, 10, 32)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif gid < 0 || gid > math.MaxInt32 {\n\t\treturn 0, errors.New(\"out of bound gid\")\n\t}\n\treturn uint32(gid), nil\n}\n\nfunc getPluginTypeAndSubtypeFromPath(path string) (string, string, error) {\n\tpluginFileName := filepath.Base(path)\n\tparts := strings.Split(pluginFileName, \"-\")\n\tif len(parts) < 2 {\n\t\treturn \"\", \"\", fmt.Errorf(\"plugin name %s is invalid. Name should be like {type-name}\", path)\n\t}\n\treturn strings.Join(parts[:len(parts)-1], \"-\"), parts[len(parts)-1], nil\n}\n\nfunc getProcessAttr(username string, groupname string) (*unix.SysProcAttr, error) {\n\tuid, err := getUID(username)\n\tif err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/csplugin/utils.go#L45-L81","documentation":"getGID parses the group ID string from a syscall.Stat_t / user lookup into an int32 and validates it fits in a uint32-compatible range before returning it. It throws 'out of bound gid' when the parsed gid is negative or exceeds math.MaxInt32, guarding against invalid or corrupted group identifiers.","triggerScenarios":"Called from getProcessAttr when starting a plugin subprocess: the configured group (via config user/group or the process's own gid from os.Getgroups/stat) parses to a value < 0 or > 2147483647.","commonSituations":"A corrupted or hand-edited config specifying a gid string like '-1' or a huge number; unusual numeric gids from exotic user databases; a stat reporting an overflowed gid on a weird filesystem.","solutions":["Check the gid configured for the crowdsec user/group in the config (api.server or plugin section) and set a valid numeric group ID between 0 and 2147483647","Verify with 'id <user>' that the group's gid is a sane positive value","Fix the /etc/group entry if the gid is corrupt or negative"],"exampleFix":"// before\ngid, err := strconv.ParseInt(g.Gid, 10, 32)\n// after\nif gid, err := strconv.ParseInt(g.Gid, 10, 32); err == nil && gid >= 0 && gid <= math.MaxInt32 {\n    // proceed\n}","handlingStrategy":"validation","validationCode":"if v, err := strconv.ParseInt(gidStr, 10, 32); err != nil || v < 0 || v > math.MaxInt32 { return fmt.Errorf(\"invalid gid %q\", gidStr) }","typeGuard":"func gidInRange(v int64) bool { return v >= 0 && v <= math.MaxInt32 }","tryCatchPattern":"gid, err := getGID(g)\nif err != nil { return fmt.Errorf(\"while getting gid for plugin user: %w\", err) }","preventionTips":["Verify the configured group's numeric gid with 'id -g <user>'","Keep /etc/group entries within the signed int32 range","Validate user/group config at startup before spawning plugin processes"],"tags":["go","validation","out-of-range","plugin"],"backgroundTag":"value-out-of-range","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}