kovidgoyal/kitty · critical

Incorrect owner on SHM file

Error message

Incorrect owner on SHM file

What it means

The ssh kitten passes data to the bootstrap script via POSIX shared memory (/dev/shm). Before reading, it verifies the shm file's owner matches the current uid/gid; if not, this error is returned to prevent reading a file planted by another user (privilege escalation / data spoofing guard).

Source

Thrown at kittens/ssh/main.go:78

			if p.User.Username() != "" {
				username = p.User.Username()
			}
		}
	} 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
}

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Remove the stale shm file: ls -l /dev/shm/kitty.* then rm the offending one
  2. Run the kitten consistently as the same user (avoid mixing sudo and normal runs)
  3. Reboot or remount /dev/shm if stale files persist from a crashed session
  4. Treat unexpected ownership as a security signal on multi-user hosts — investigate before deleting

Example fix

# before
sudo kitty +kitten ssh user@host   # after a normal-user run left /dev/shm files
# after (clean up and use one user)
rm -f /dev/shm/kitty.*
kitty +kitten ssh user@host
Defensive patterns

Strategy: try-catch

Validate before calling

if info, err := os.Stat(shmPath); err == nil {
    if st, ok := info.Sys().(*syscall.Stat_t); ok && int(st.Uid) != os.Getuid() {
        // refuse and clean up before calling
    }
}

Try / catch

if _, err := read_data_from_shared_memory(name); err != nil {
    if strings.Contains(err.Error(), "Incorrect owner") {
        os.Remove(shmPath) // stale from other-user run
    }
}

Prevention

When it happens

Trigger: read_data_from_shared_memory encountering a /dev/shm file owned by a different uid or gid than the current process — e.g. leftover file from a prior run under another user, or a file created by a setuid/sudo context.

Common situations: Running the kitten under sudo after a prior non-root run (or vice versa); container namespaces mapping different uids; shared machines where another user guessed the shm name; stale files in /dev/shm after a crash.

Related errors


AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27). Data as JSON: /api/errors/0d2174675234ce95. Report an issue: GitHub.