jetty.project icon indicating copy to clipboard operation
jetty.project copied to clipboard

Jetty 11.0.18 does not startup with setuid-mechanism as jetty.state not writable

Open lglowania opened this issue 1 year ago • 6 comments

Jetty version(s) Jetty 11.0.18

Java version/vendor openjdk version "21.0.1" 2023-10-17 LTS

OS type/version Debian/Bookworm

Description Some months ago I upgraded from Jetty 11.0.16 to 11.0.18. My setup uses the setuid-mechanism. So it is started as root to use port 80 and 443 and switches to a jetty-user. Since 11.0.18 the jetty.state-file is created with root-privileges and is not writable by the jetty-user any more. This results in a failed startup. When i manually change the owner of the jetty.state-file to jetty during startup, it starts successfully.

09:58:55.072  [wnThread] WARN  StateLifeCycleListener - Unable to append to state file: /home/luk/jbase/jetty.state
java.nio.file.AccessDeniedException: /home/luk/jbase/jetty.state
	at sun.nio.fs.UnixException.translateToIOException(UnixException.java:90) ~[?:?]
	at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106) ~[?:?]
	at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111) ~[?:?]
	at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:261) ~[?:?]
	at java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:482) ~[?:?]
	at java.nio.file.Files.newOutputStream(Files.java:227) ~[?:?]
	at java.nio.file.Files.newBufferedWriter(Files.java:2988) ~[?:?]
	at org.eclipse.jetty.server.StateLifeCycleListener.appendStateChange(StateLifeCycleListener.java:62) ~[jetty-server-11.0.18.jar:11.0.18]
	at org.eclipse.jetty.server.StateLifeCycleListener.lifeCycleStopped(StateLifeCycleListener.java:104) ~[jetty-server-11.0.18.jar:11.0.18]
	at org.eclipse.jetty.util.component.AbstractLifeCycle.setStopped(AbstractLifeCycle.java:286) ~[jetty-util-11.0.18.jar:11.0.18]
	at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:133) ~[jetty-util-11.0.18.jar:11.0.18]
	at org.eclipse.jetty.util.thread.ShutdownThread.run(ShutdownThread.java:136) ~[jetty-util-11.0.18.jar:11.0.18]

How to reproduce? Start Jetty with the jetty.sh-script and the setuid-module as root, e.g. sudo ./jetty.sh start.

lglowania avatar Dec 21 '23 09:12 lglowania

First steps. delete the jetty.state file, upgrade to Jetty 11.0.19, and try again.

We introduced testing for starting Jetty via the jetty.sh in Jetty 11.0.18. Looks like we need to add test cases for JDK21 use, and setuid use.

Are you using the old-school setuid? or the new setuid-jna stuff? Are you starting via the old school System V init.d behaviors? or are you kicking off jetty.sh from a systemd service file?

joakime avatar Dec 21 '23 15:12 joakime

Deleted jetty.state, upgraded to Jetty 11.0.19, same error.

I'm using the standard-setuid-module, that is added with java -jar start.jar --add-modules=setuid. In our production-environment we use systemd, where jetty.sh is called.

The startup of Jetty 11.0.19 works ok with the version of jetty.sh from the 11.0.16-release.

lglowania avatar Dec 24 '23 13:12 lglowania

No, it does not work ok. It only reports to successfully startup, but it still can't write to jetty.state.

lglowania avatar Dec 24 '23 13:12 lglowania

Same issue for me, Jetty 11.0.20, when using setuid. jetty.sh starts, creates the state file as root (not writable by non-root), launches the process as non-root, and that process then cannot update the state file, so jetty.sh kills the process. It worked in 11.0.16 but not in any version after that. I don't really have a good proposed fix for this. Jetty would need to chown the state file to the setuid user.

Edit: using JDK 21, this happens using jetty.sh.

chiralsoftware avatar Feb 06 '24 20:02 chiralsoftware

The state file is created very early in the lifecycle of the server. The setuid call happens much later. So it makes sense that the state file is owned by the user starting jetty (root in your cases). The state file cannot be deleted by Jetty once the setuid call is performed. What about just having the jetty.sh delete the state file (if the pid file shows that the process isn't running)?

joakime avatar Feb 06 '24 20:02 joakime

As a not very beautiful hack to let me upgrade my jetty installations, I added this at line 155 in jetty.sh:

chmod ugo+w $STATEFILE

chiralsoftware avatar Feb 06 '24 21:02 chiralsoftware

This situation still exists in Jetty 12.0.9. For Setuid module to work, I need to add that line at 155 in jetty.sh. I realize the right answer might be, don't use setuid, instead use

 setcap 'cap_net_bind_service=+ep' /path/to/jetty/bin/jetty.sh

and just run the whole thing as that user. I haven't tested this.

chiralsoftware avatar May 22 '24 19:05 chiralsoftware