Skip to content

Commit 884f777

Browse files
committed
Merge branch 'master' of github.com:jenkinsci/pipeline-groovy-lib-plugin into feature/include-versions-caching
2 parents b1b6712 + 07c339c commit 884f777

File tree

22 files changed

+700
-294
lines changed

22 files changed

+700
-294
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* @jenkinsci/pipeline-groovy-lib-plugin-developers

.github/release-drafter.yml

Lines changed: 0 additions & 1 deletion
This file was deleted.

.mvn/extensions.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
<extension>
33
<groupId>io.jenkins.tools.incrementals</groupId>
44
<artifactId>git-changelist-maven-extension</artifactId>
5-
<version>1.4</version>
5+
<version>1.7</version>
66
</extension>
77
</extensions>

Jenkinsfile

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
buildPlugin(useContainerAgent: true, configurations: [
2-
[ platform: "linux", jdk: "8" ],
3-
[ platform: "windows", jdk: "8" ],
4-
[ platform: "linux", jdk: "11" ]
1+
buildPlugin(
2+
useContainerAgent: true,
3+
configurations: [
4+
[platform: 'linux', jdk: 17],
5+
[platform: 'windows', jdk: 11],
56
])

pom.xml

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
<parent>
2929
<groupId>org.jenkins-ci.plugins</groupId>
3030
<artifactId>plugin</artifactId>
31-
<version>4.44</version>
31+
<version>4.71</version>
3232
<relativePath/>
3333
</parent>
3434
<groupId>io.jenkins.plugins</groupId>
@@ -44,7 +44,7 @@
4444
</license>
4545
</licenses>
4646
<scm>
47-
<connection>scm:git:git://github.com/${gitHubRepo}.git</connection>
47+
<connection>scm:git:https://github.com/${gitHubRepo}.git</connection>
4848
<developerConnection>scm:git:[email protected]:${gitHubRepo}.git</developerConnection>
4949
<url>https://github.com/${gitHubRepo}</url>
5050
<tag>${scmTag}</tag>
@@ -63,15 +63,15 @@
6363
</pluginRepositories>
6464
<properties>
6565
<changelist>999999-SNAPSHOT</changelist>
66-
<jenkins.version>2.289.3</jenkins.version>
66+
<jenkins.version>2.361.4</jenkins.version>
6767
<gitHubRepo>jenkinsci/${project.artifactId}-plugin</gitHubRepo>
6868
</properties>
6969
<dependencyManagement>
7070
<dependencies>
7171
<dependency>
7272
<groupId>io.jenkins.tools.bom</groupId>
73-
<artifactId>bom-2.289.x</artifactId>
74-
<version>1500.ve4d05cd32975</version>
73+
<artifactId>bom-2.361.x</artifactId>
74+
<version>1883.vcb_768a_7c3610</version>
7575
<scope>import</scope>
7676
<type>pom</type>
7777
</dependency>
@@ -82,7 +82,7 @@
8282
<dependency>
8383
<groupId>org.apache.ivy</groupId>
8484
<artifactId>ivy</artifactId>
85-
<version>2.5.0</version>
85+
<version>2.5.1</version>
8686
</dependency>
8787

8888
<!-- required plugins -->
@@ -190,6 +190,16 @@
190190
<groupId>org.jenkins-ci.plugins</groupId>
191191
<artifactId>subversion</artifactId>
192192
<scope>test</scope>
193+
<exclusions>
194+
<exclusion>
195+
<groupId>org.apache.sshd</groupId>
196+
<artifactId>sshd-common</artifactId>
197+
</exclusion>
198+
<exclusion>
199+
<groupId>org.apache.sshd</groupId>
200+
<artifactId>sshd-core</artifactId>
201+
</exclusion>
202+
</exclusions>
193203
</dependency>
194204
<dependency>
195205
<groupId>org.jenkins-ci.plugins</groupId>
@@ -200,7 +210,7 @@
200210
<dependency>
201211
<groupId>org.tmatesoft.svnkit</groupId>
202212
<artifactId>svnkit-cli</artifactId>
203-
<version>1.10.7</version>
213+
<version>1.10.10</version>
204214
<scope>test</scope>
205215
</dependency>
206216
</dependencies>

src/main/java/org/jenkinsci/plugins/workflow/libs/LibraryStep.java

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import java.util.logging.Logger;
6060
import edu.umd.cs.findbugs.annotations.CheckForNull;
6161
import edu.umd.cs.findbugs.annotations.NonNull;
62+
import groovy.lang.MissingPropertyException;
6263
import javax.inject.Inject;
6364
import jenkins.model.Jenkins;
6465
import jenkins.scm.impl.SingleSCMSource;
@@ -75,6 +76,8 @@
7576
import org.jenkinsci.plugins.workflow.steps.StepContextParameter;
7677
import org.kohsuke.accmod.Restricted;
7778
import org.kohsuke.accmod.restrictions.DoNotUse;
79+
import org.kohsuke.groovy.sandbox.GroovyInterceptor;
80+
import org.kohsuke.groovy.sandbox.impl.Checker;
7881
import org.kohsuke.stapler.AncestorInPath;
7982
import org.kohsuke.stapler.DataBoundConstructor;
8083
import org.kohsuke.stapler.DataBoundSetter;
@@ -270,11 +273,15 @@ public static final class LoadedClasses extends GroovyObjectSupport implements S
270273
if (clazz != null) {
271274
// Field access?
272275
try {
273-
// not doing a Whitelist check since GroovyClassLoaderWhitelist would be allowing it anyway
276+
if (isSandboxed()) {
277+
return Checker.checkedGetAttribute(loadClass(prefix + clazz), false, false, property);
278+
}
274279
return loadClass(prefix + clazz).getField(property).get(null);
275-
} catch (NoSuchFieldException x) {
280+
} catch (MissingPropertyException | NoSuchFieldException x) {
276281
// guessed wrong
277-
} catch (IllegalAccessException x) {
282+
} catch (SecurityException x) {
283+
throw x;
284+
} catch (Throwable x) {
278285
throw new GroovyRuntimeException(x);
279286
}
280287
}
@@ -284,6 +291,8 @@ public static final class LoadedClasses extends GroovyObjectSupport implements S
284291
loadClass(prefix + fullClazz);
285292
// OK, class really exists, stash it and await methods
286293
return new LoadedClasses(library, trusted, changelog, prefix, fullClazz, srcUrl);
294+
} else if (clazz != null) {
295+
throw new MissingPropertyException(property, loadClass(prefix + clazz));
287296
} else {
288297
// Still selecting package components.
289298
return new LoadedClasses(library, trusted, changelog, prefix + property + '.', null, srcUrl);
@@ -293,13 +302,43 @@ public static final class LoadedClasses extends GroovyObjectSupport implements S
293302
@Override public Object invokeMethod(String name, Object _args) {
294303
Class<?> c = loadClass(prefix + clazz);
295304
Object[] args = _args instanceof Object[] ? (Object[]) _args : new Object[] {_args}; // TODO why does Groovy not just pass an Object[] to begin with?!
305+
if (isSandboxed()) {
306+
try {
307+
if (name.equals("new")) {
308+
return Checker.checkedConstructor(c, args);
309+
} else {
310+
return Checker.checkedStaticCall(c, name, args);
311+
}
312+
} catch (SecurityException x) {
313+
throw x;
314+
} catch (Throwable x) {
315+
throw new GroovyRuntimeException(x);
316+
}
317+
}
296318
if (name.equals("new")) {
297319
return InvokerHelper.invokeConstructorOf(c, args);
298320
} else {
299321
return InvokerHelper.invokeStaticMethod(c, name, args);
300322
}
301323
}
302324

325+
/**
326+
* Check whether the current thread has at least one active {@link GroovyInterceptor}.
327+
* <p>
328+
* Typically, {@code GroovyClassLoaderWhitelist} will allow access to everything defined in a class in a
329+
* library, but there are some synthetic constructors, fields, and methods which should not be accessible.
330+
* <p>
331+
* As a result, when getting properties or invoking methods using this class, we need to apply sandbox
332+
* protection if the Pipeline code performing the operation is sandbox-transformed. Unfortunately, it is
333+
* difficult to detect that case specifically, so we instead intercept all calls if the Pipeline itself is
334+
* sandboxed. This results in a false positive {@code RejectedAccessException} being thrown if a trusted
335+
* library uses the {@code library} step and tries to access static fields or methods that are not permitted to
336+
* be used in the sandbox.
337+
*/
338+
private static boolean isSandboxed() {
339+
return !GroovyInterceptor.getApplicableInterceptors().isEmpty();
340+
}
341+
303342
// TODO putProperty for static field set
304343

305344
private Class<?> loadClass(String name) {

0 commit comments

Comments
 (0)