kovidgoyal/kitty · critical
Incorrect permissions on SHM file
Error message
Incorrect permissions on SHM file
What it means
Companion check to the owner verification: the /dev/shm bootstrap file must have exactly 0600 permissions. Looser modes would let other local users read the transmitted data (which can include sensitive payloads), so the read is aborted.
Solutions
- Fix your umask before launching kitty (e.g. umask 022 or 077)
- Delete and let the kitten recreate the file: rm /dev/shm/<name> and rerun
- Verify no other tool/user is pre-creating the shm file: ls -l /dev/shm/
- If it recurs, audit what writes to /dev/shm with wide modes (could be tampering)
Example fix
# before umask 000 kitty +kitten ssh user@host # after umask 077 kitty +kitten ssh user@host
Defensive patterns
Strategy: try-catch
Validate before calling
if info, err := os.Stat(shmPath); err == nil && info.Mode().Perm() != 0o600 {
os.Chmod(shmPath, 0o600) // or remove to force recreation
} Try / catch
if err != nil && strings.Contains(err.Error(), "Incorrect permissions") {
os.Remove(shmPath) // recreate with correct mode
} Prevention
- Set umask 077 (or at least restrictive) in shells that launch kitty
- Audit /dev/shm for wide-mode files on shared hosts
When it happens
Trigger: read_data_from_shared_memory seeing a shm file whose mode bits are not 0600 — e.g. created under a permissive umask (0002/0666 gone wide), or chmod'ed afterwards, or a foreign file with the same name.
Common situations: Users with umask 000 in shell profiles; containers or CI images with odd umask defaults; multi-user systems; files copied into /dev/shm manually for debugging.
Related errors
- Incorrect owner on SHM file
- Incorrect owner on pwfile: uid=
- Incorrect permissions on pwfile: 0o
- Attempted path traversal in tar file
- Cannot access the mmap of a closed shared memory object
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/e015331e53723841.
Report an issue: GitHub.
Appendix: source
Thrown at kittens/ssh/main.go:82
} else if strings.Contains(hostname, "@") && hostname[0] != '@' {
username, hostname_for_match, _ = strings.Cut(hostname, "@")
parsed = true
}
if !parsed && strings.Contains(hostname, "@") && hostname[0] != '@' {
_, hostname_for_match, _ = strings.Cut(hostname, "@")
}
return
}
func read_data_from_shared_memory(shm_name string) ([]byte, error) {
data, err := shm.ReadWithSizeAndUnlink(shm_name, func(s fs.FileInfo) error {
if stat, ok := s.Sys().(syscall.Stat_t); ok {
if os.Getuid() != int(stat.Uid) || os.Getgid() != int(stat.Gid) {
return fmt.Errorf("Incorrect owner on SHM file")
}
}
if s.Mode().Perm() != 0o600 {
return fmt.Errorf("Incorrect permissions on SHM file")
}
return nil
})
return data, err
}
func add_cloned_env(val string) (ans map[string]string, err error) {
data, err := read_data_from_shared_memory(val)
if err != nil {
return nil, err
}
err = json.Unmarshal(data, &ans)
return ans, err
}
func parse_kitten_args(found_extra_args []string, username, hostname_for_match string) (overrides []string, literal_env map[string]string, ferr error) {
literal_env = make(map[string]string)
overrides = make([]string, 0, 4)View on GitHub (pinned to 6d5d0c4406)