Jenkins and plugins versions report
Environment
Jenkins: 2.555.3
OS: Linux - 5.4.17-2136.354.4.3.el8uek.x86_64
Java: 25.0.3 - Oracle Corporation (Java HotSpot(TM) 64-Bit Server VM)
---
ant:520.vd082ecfb_16a_9
antisamy-markup-formatter:173.v680e3a_b_69ff3
apache-httpcomponents-client-4-api:4.5.14-269.vfa_2321039a_83
apache-httpcomponents-client-5-api:5.6.1-195.v65ffe15189a_d
asm-api:9.10.1-216.va_9256d3b_844b_
authentication-tokens:1.144.v5ff4a_5ec5c33
authorize-project:531.vf8761dfd75d2
aws-java-sdk2-core:2.42.33-70.vd69c0763fa_60
badge:3.591.v9074c6c6f0b_9
blackduck-detect:11.0.0
bootstrap5-api:5.3.8-1038.vee76a_fe825ff
bouncycastle-api:2.30.1.84-291.v9f17b_21896e2
branch-api:2.1280.v0d4e5b_b_460ef
build-timeout:1.40
build-user-vars-plugin:214.va_eed2ed849ca_
built-on-column:1.5
caffeine-api:3.2.3-194.v31a_b_f7a_b_5a_81
checks-api:415.vf022234a_931d
cloudbees-folder:6.1100.ve9eed61d16c4
command-launcher:134.v025a_5fcf9dea_
commons-collections4-api:4.5.0-8.va_d5448ef9011
commons-compress-api:1.28.0-82.v4df6c060eb_66
commons-lang3-api:3.20.0-109.ve43756e2d2b_4
commons-text-api:1.15.0-218.va_61573470393
conditional-buildstep:1.5.0
configurationslicing:709.v4c76e613470f
copyartifact:795.ve8e151429b_27
credentials:1502.v5c95e620ddfe
credentials-binding:725.ve52b_2328a_fde
csp:2.58.v31cd65258cb_2
data-tables-api:2.3.8-1570.v1cb_1cd2a_0fb_c
deploy:1.17
description-setter:264.v1957f215dcd5
disable-job-button:1.3.vf55949267366
display-url-api:2.217.va_6b_de84cc74b_
docker-commons:472.vee120e23d3a_c
docker-workflow:634.vedc7242b_eda_7
downstream-buildview:69.v16da_b_2c36f6c
downstream-ext:73.vdda_16e6eb_0da
durable-task:671.v340ff7959010
echarts-api:6.0.0-1287.vfd24c22a_3d00
eddsa-api:0.3.0.1-29.v67e9a_1c969b_b_
email-ext:2038.v7b_8817a_499d9
emoji-symbols-api:17.0-57.v8d44b_9a_b_d5ea_
envinject:2.941.v351a_20c0a_3ca_
envinject-api:1.241.vdd714803b_403
external-monitor-job:223.vb_fddcf42c9b_3
font-awesome-api:7.2.0-990.vf220b_2a_496f9
fstrigger:1.02
git:5.10.1
git-client:6.6.0
git-server:137.ve0060b_432302
github:1.46.0.1
github-api:1.330-492.v3941a_032db_2a_
github-branch-source:1967.1969.v205fd594c821
gradle:2.19.1244.v1f9866817fec
gravatar:214.243.vd99f63e4175f
groovy:537.v741a_5a_f1b_581
groovy-postbuild:303.v5fe3da_6233f0
gson-api:2.14.0-201.v8eefe5515533
instance-identity:203.v15e81a_1b_7a_38
ionicons-api:94.vcc3065403257
jackson-annotations2-api:2.22-19.v10a_a_582ea_26e
jackson2-api:2.21.2-436.v29efdb_7418ff
jackson3-api:3.1.4-81.v804303fd947a_
jakarta-activation-api:2.1.4-1
jakarta-mail-api:2.1.5-1
jakarta-xml-bind-api:4.0.9-19.v2b_a_5b_44d9a_1c
javadoc:354.vee1a_660b_4990
javax-activation-api:1.2.0-8
javax-mail-api:1.6.2-11
jaxb:2.3.9-143.v5979df3304e6
jdk-tool:83.v417146707a_3d
jjwt-api:0.13.0-141.vd58b_a_9592b_6c
jnr-posix-api:3.1.22-204.v925e2b_09a_42c
jobConfigHistory:1356.ve360da_6c523a_
joda-time-api:2.14.2-193.v422b_efce56e0
jquery:1.12.4-3
jquery3-api:3.7.1-687.v68d468e40b_30
jsch:0.2.16-95.v3eecb_55fa_b_78
json-api:20260522-217.v0b_18b_8cd4672
json-path-api:3.0.0-218.vcd4dd1355de2
jsoup:1.22.2-95.vc5d00f1eb_42d
junit:1403.vd9d1413fd205
ldap:807.809.vd3a_4e5e4ec98
lockable-resources:1524.v2c727b_b_e56ef
log-parser:3.0.3
mailer:534.v1b_36f5864073
mapdb-api:1.0.9-44.va_1e1310c9118
mask-passwords:220.v95819055b_265
matrix-auth:3.2.10
matrix-project:870.v9db_fcfc2f45b_
maven-plugin:3.27
mina-sshd-api-common:2.17.1-187.v0341274c2905
mina-sshd-api-core:2.17.1-187.v0341274c2905
naginator:1.556.v14d723a_109a_c
nodelabelparameter:851.vd94e5048d321
okhttp-api:5.3.2-200.vedb_720a_cf1f8
oss-symbols-api:456.v46e634a_63b_99
pam-auth:1.12
parameterized-trigger:893.va_383a_9b_a_4c11
people-view:1.16.v774d3b_4b_3a_f3
pipeline-build-step:584.vdb_a_2cc3a_d07a_
pipeline-github-lib:65.v203688e7727e
pipeline-graph-analysis:254.v0f63a_a_447dca_
pipeline-groovy-lib:798.v5cc688825312
pipeline-input-step:551.vdff487c5998c
pipeline-milestone-step:152.v6e22b_8cfc66c
pipeline-model-api:2.2289.v6f731d0a_02da_
pipeline-model-definition:2.2289.v6f731d0a_02da_
pipeline-model-extensions:2.2289.v6f731d0a_02da_
pipeline-rest-api:2.41
pipeline-stage-step:345.va_96187909426
pipeline-stage-tags-metadata:2.2289.v6f731d0a_02da_
pipeline-stage-view:2.41
pipeline-utility-steps:3.810.va_7672d206740
plain-credentials:199.v9f8e1f741799
plugin-usage-plugin:418.v308c3c863d25
plugin-util-api:7.1341.v039f146993d9
postbuild-task:78.v24529f1f5cdb_
prism-api:1.30.0-741.v034eb_0b_0a_a_fa_
rebuild:338.va_0a_b_50e29397
resource-disposer:0.25
run-condition:276.v97298f3a_cd51
saml:4.600.v069e2e79eeb_f
scm-api:728.vc30dcf7a_0df5
script-security:1402.v94c9ce464861
shiningpanda:0.24
slack:795.v4b_9705b_e6d47
snakeyaml-api:2.5-149.v72471e9c6371
snakeyaml-engine-api:3.0.1-5.vd98ea_ff3b_92e
ssh-credentials:372.va_250881b_08cd
ssh-slaves:3.1097.v868116049892
sshd:3.384.vc89b_5e138cf9
structs:362.va_b_695ef4fdf9
subversion:1303.vcfd9679fb_c12
timestamper:1.30
token-macro:477.vd4f0dc3cb_cf1
trilead-api:2.284.v1974ea_324382
uno-choice:2.8.9
variant:70.va_d9f17f859e0
versioncolumn:400.v3c5c3004f31d
woodstox-core-api:7.1.1-1.v4d297985f397
workflow-aggregator:608.v67378e9d3db_1
workflow-api:1413.v2ff1a_5e720fa_
workflow-basic-steps:1098.v808b_fd7f8cf4
workflow-cps:4331.v9d06ed4658ff
workflow-durable-task-step:1479.v56e587f413a_7
workflow-job:1571.1580.v18e46842c125
workflow-multibranch:821.vc3b_4ea_780798
workflow-scm-step:466.va_d69e602552b_
workflow-step-api:724.v538c2362b_dfb_
workflow-support:1015.v785e5a_b_b_8b_22
ws-cleanup:0.49
xtrigger-api:1.2
What Operating System are you using (both controller, and any agents involved in the problem)?
Controller:
Linux x86_64
Kernel: 5.4.17-2136.354.4.3.el8uek.x86_64
Java: 25.0.3, Oracle Corporation, Java HotSpot(TM) 64-Bit Server VM
Agents:
No Jenkins agents were directly involved in the observed Winstone startup/webroot cleanup issue. The issue occurred during controller startup/WAR extraction before normal workload execution.
Reproduction steps
I do not yet have a clean minimal reproducer.
Observed sequence:
- Run Jenkins from
jenkins.war on Linux using Java 25.
- Configure Jenkins to use an explicit Winstone webroot, for example:
--webroot=/path/to/jenkins-war
- Start Jenkins as a non-root service user.
- Jenkins home is separate from the Winstone webroot.
- Upgrade Jenkins core from 2.555.2 to 2.555.3 using the Jenkins UI upgrade flow.
- Use the UI-provided restart/upgrade flow after the upgrade.
- During that UI-driven restart/startup path, Winstone began WAR extraction/webroot cleanup.
- At that point the startup log showed
winstone.HostConfiguration.deleteRecursive recursing through a /proc/self/task/<pid>/cwd/... path outside the configured webroot.
- I then killed the Java process and started Jenkins using the system service manager (
systemctl start jenkins / controlled service startup).
- The service-managed startup appeared healthy and did not reproduce the same Winstone
/proc/self/task/.../cwd recursion in the current startup log.
- In a later controlled restart with auditd enabled, auditd confirmed Java attempted an
unlink against a /proc/self/task/<pid>/cwd/... path. In the sampled event, the unlink failed with EACCES.
- Successful Java delete events during the controlled restart were limited to the configured webroot and temp/lock files.
Relevant configuration:
- Controller-only startup issue; no Jenkins agents were directly involved.
- Explicit Winstone webroot was configured.
- Jenkins home was separate from the Winstone webroot.
- Jenkins was running as a non-root service user.
- The configured webroot was owned by the Jenkins service user.
- The configured webroot was not a symlink.
- The configured webroot was not group/world writable.
Expected Results
Winstone should keep WAR extraction cleanup confined to the configured webroot.
Specifically:
- Recursive cleanup should only delete files/directories under the configured
--webroot path.
- Cleanup should not recurse through
/proc/self/task/<pid>/cwd or other process pseudo-filesystem paths.
- Cleanup should not follow symlinks or other traversal paths that escape the configured webroot.
- If Winstone detects an unsafe path or traversal outside the webroot, startup should fail safely or skip that path with a clear warning.
Actual Results
During the UI-driven Jenkins upgrade/restart flow, Winstone attempted recursive cleanup through a /proc/self/task/<pid>/cwd/... path outside the configured webroot.
The Jenkins startup log contained:
WARNING winstone.Logger#logInternal:
Failed to delete dirs /proc/self/task/<jenkins-pid>/cwd/proc/self/task/<jenkins-pid>/cwd/.../proc/<pid>/task/<pid>/net/psched
java.nio.file.AccessDeniedException:
proc/self/task/<jenkins-pid>/cwd/proc/self/task/<jenkins-pid>/cwd/.../proc/<pid>/task/<pid>/net/psched
at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:90)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
at java.base/sun.nio.fs.UnixFileSystemProvider.implDelete(UnixFileSystemProvider.java:271)
at java.base/sun.nio.fs.AbstractFileSystemProvider.deleteIfExists(AbstractFileSystemProvider.java:110)
at java.base/java.nio.file.Files.deleteIfExists(Files.java:1087)
at Jenkins Main ClassLoader//winstone.HostConfiguration.deleteRecursive(HostConfiguration.java:366)
at Jenkins Main ClassLoader//winstone.HostConfiguration.deleteRecursive(HostConfiguration.java:362)
...
at Jenkins Main ClassLoader//winstone.HostConfiguration.getWebRoot(HostConfiguration.java:282)
at Jenkins Main ClassLoader//winstone.HostConfiguration.<init>(HostConfiguration.java:84)
at Jenkins Main ClassLoader//winstone.HostGroup.initHost(HostGroup.java:59)
at Jenkins Main ClassLoader//winstone.HostGroup.<init>(HostGroup.java:37)
at Jenkins Main ClassLoader//winstone.Launcher.<init>(Launcher.java:171)
at Jenkins Main ClassLoader//winstone.Launcher.main(Launcher.java:493)
at executable.Main.main(Main.java:332)
After this occurred, I killed the Java process and restarted Jenkins through the system service manager. That service-managed startup completed successfully, and the current startup log did not contain the same deleteRecursive / /proc/self/task warning.
During a later controlled restart with auditd enabled, auditd captured Java attempting to unlink a /proc/self/task/<pid>/cwd/... path:
type=SYSCALL ... syscall=unlink success=no exit=EACCES(Permission denied) ... comm=java exe=/path/to/java key=delete_watch
type=PATH ... name=proc/self/task/<jenkins-pid>/cwd/proc/self/task/<jenkins-pid>/cwd/... nametype=DELETE
In that audited restart, the sampled /proc unlink failed with EACCES. Successful Java delete events were limited to the configured webroot and temp/lock files.
The concern is that Winstone recursive cleanup reached /proc/self/task/<pid>/cwd/... at all, despite an explicit --webroot being configured.
Anything else?
This may be related to Winstone WAR extraction cleanup when the existing extracted webroot is considered stale and is recursively deleted before re-extraction.
The relevant stack appears to be:
winstone.HostConfiguration.getWebRoot
winstone.HostConfiguration.deleteRecursive
java.nio.file.Files.deleteIfExists
The concern is not that the sampled /proc unlink succeeded. In the audited restart, it failed with EACCES. The concern is that recursive cleanup reached /proc/self/task/<pid>/cwd/... at all, even though an explicit --webroot was configured.
Local mitigations currently applied:
- Use an explicit
--webroot.
- Ensure the webroot is owned by the Jenkins service user.
- Ensure the webroot is not a symlink.
- Ensure the webroot is not group/world writable.
- Keep auditd delete rules enabled during controlled restarts.
- Avoid UI-driven restart/upgrade flow where possible; prefer controlled service restart.
- Preserve timestamped Jenkins startup logs for future analysis.
I initially considered whether this might have security impact because it involves recursive delete traversal outside the intended cleanup tree. I am filing this as a public bug report with internal hostnames, paths, and user details sanitized.
Are you interested in contributing a fix?
I am not currently familiar enough with Winstone internals to commit to contributing a fix, but I am willing to help validate a proposed fix or provide additional sanitized logs/audit output if needed.
Jenkins and plugins versions report
Environment
What Operating System are you using (both controller, and any agents involved in the problem)?
Controller:
Linux x86_64
Kernel: 5.4.17-2136.354.4.3.el8uek.x86_64
Java: 25.0.3, Oracle Corporation, Java HotSpot(TM) 64-Bit Server VM
Agents:
No Jenkins agents were directly involved in the observed Winstone startup/webroot cleanup issue. The issue occurred during controller startup/WAR extraction before normal workload execution.
Reproduction steps
I do not yet have a clean minimal reproducer.
Observed sequence:
jenkins.waron Linux using Java 25.--webroot=/path/to/jenkins-warwinstone.HostConfiguration.deleteRecursiverecursing through a/proc/self/task/<pid>/cwd/...path outside the configured webroot.systemctl start jenkins/ controlled service startup)./proc/self/task/.../cwdrecursion in the current startup log.unlinkagainst a/proc/self/task/<pid>/cwd/...path. In the sampled event, the unlink failed withEACCES.Relevant configuration:
Expected Results
Winstone should keep WAR extraction cleanup confined to the configured webroot.
Specifically:
--webrootpath./proc/self/task/<pid>/cwdor other process pseudo-filesystem paths.Actual Results
During the UI-driven Jenkins upgrade/restart flow, Winstone attempted recursive cleanup through a
/proc/self/task/<pid>/cwd/...path outside the configured webroot.The Jenkins startup log contained:
After this occurred, I killed the Java process and restarted Jenkins through the system service manager. That service-managed startup completed successfully, and the current startup log did not contain the same
deleteRecursive//proc/self/taskwarning.During a later controlled restart with auditd enabled, auditd captured Java attempting to unlink a
/proc/self/task/<pid>/cwd/...path:In that audited restart, the sampled
/procunlink failed withEACCES. Successful Java delete events were limited to the configured webroot and temp/lock files.The concern is that Winstone recursive cleanup reached
/proc/self/task/<pid>/cwd/...at all, despite an explicit--webrootbeing configured.Anything else?
This may be related to Winstone WAR extraction cleanup when the existing extracted webroot is considered stale and is recursively deleted before re-extraction.
The relevant stack appears to be:
winstone.HostConfiguration.getWebRootwinstone.HostConfiguration.deleteRecursivejava.nio.file.Files.deleteIfExistsThe concern is not that the sampled
/procunlink succeeded. In the audited restart, it failed withEACCES. The concern is that recursive cleanup reached/proc/self/task/<pid>/cwd/...at all, even though an explicit--webrootwas configured.Local mitigations currently applied:
--webroot.I initially considered whether this might have security impact because it involves recursive delete traversal outside the intended cleanup tree. I am filing this as a public bug report with internal hostnames, paths, and user details sanitized.
Are you interested in contributing a fix?
I am not currently familiar enough with Winstone internals to commit to contributing a fix, but I am willing to help validate a proposed fix or provide additional sanitized logs/audit output if needed.