@@ -237,8 +237,29 @@ func (s *Server) sessionHandler(session ssh.Session) {
237
237
err := s .sessionStart (logger , session , extraEnv )
238
238
var exitError * exec.ExitError
239
239
if xerrors .As (err , & exitError ) {
240
- logger .Info (ctx , "ssh session returned" , slog .Error (exitError ))
241
- _ = session .Exit (exitError .ExitCode ())
240
+ code := exitError .ExitCode ()
241
+ if code == - 1 {
242
+ // If we return -1 here, it will be transmitted as an
243
+ // uint32(4294967295). This exit code is nonsense, so
244
+ // instead we return 255 (same as OpenSSH). This is
245
+ // also the same exit code that the shell returns for
246
+ // -1.
247
+ //
248
+ // For signals, we could consider sending 128+signal
249
+ // instead (however, OpenSSH doesn't seem to do this).
250
+ code = 255
251
+ }
252
+ logger .Info (ctx , "ssh session returned" ,
253
+ slog .Error (exitError ),
254
+ slog .F ("process_exit_code" , exitError .ExitCode ()),
255
+ slog .F ("exit_code" , code ),
256
+ )
257
+
258
+ // TODO(mafredri): For signal exit, there's also an "exit-signal"
259
+ // request (session.Exit sends "exit-status"), however, since it's
260
+ // not implemented on the session interface and not used by
261
+ // OpenSSH, we'll leave it for now.
262
+ _ = session .Exit (code )
242
263
return
243
264
}
244
265
if err != nil {
0 commit comments