Browse Source

create local copies of realThing to avoid TOCTOU race condition

see https://bz.apache.org/bugzilla/show_bug.cgi?id=65316
master
Stefan Bodewig 4 years ago
parent
commit
96fa99ee6c
2 changed files with 35 additions and 23 deletions
  1. +3
    -0
      WHATSNEW
  2. +32
    -23
      src/main/org/apache/tools/ant/UnknownElement.java

+ 3
- 0
WHATSNEW View File

@@ -4,6 +4,9 @@ Changes from Ant 1.10.10 TO Ant 1.10.11
Fixed bugs: Fixed bugs:
----------- -----------


* a race condition could lead to NullPointerExceptions when running
tasks in parallel.
Bugzilla Report 65316


Other changes: Other changes:
-------------- --------------


+ 32
- 23
src/main/org/apache/tools/ant/UnknownElement.java View File

@@ -159,7 +159,8 @@ public class UnknownElement extends Task {
* @exception BuildException if the configuration fails * @exception BuildException if the configuration fails
*/ */
public void maybeConfigure() throws BuildException { public void maybeConfigure() throws BuildException {
if (realThing != null) {
final Object copy = realThing;
if (copy != null) {
return; return;
} }
configure(makeObject(this, getWrapper())); configure(makeObject(this, getWrapper()));
@@ -177,10 +178,10 @@ public class UnknownElement extends Task {
} }
realThing = realObject; realThing = realObject;


getWrapper().setProxy(realThing);
getWrapper().setProxy(realObject);
Task task = null; Task task = null;
if (realThing instanceof Task) {
task = (Task) realThing;
if (realObject instanceof Task) {
task = (Task) realObject;


task.setRuntimeConfigurableWrapper(getWrapper()); task.setRuntimeConfigurableWrapper(getWrapper());


@@ -188,7 +189,7 @@ public class UnknownElement extends Task {
// targets to work. *very* Ugly // targets to work. *very* Ugly
// The reference is replaced by RuntimeConfigurable // The reference is replaced by RuntimeConfigurable
if (getWrapper().getId() != null) { if (getWrapper().getId() != null) {
this.getOwningTarget().replaceChild(this, (Task) realThing);
this.getOwningTarget().replaceChild(this, (Task) realObject);
} }
} }


@@ -203,7 +204,7 @@ public class UnknownElement extends Task {
getWrapper().maybeConfigure(getProject()); getWrapper().maybeConfigure(getProject());
} }


handleChildren(realThing, getWrapper());
handleChildren(realObject, getWrapper());
} }


/** /**
@@ -212,8 +213,9 @@ public class UnknownElement extends Task {
* @param output The output to log. Should not be <code>null</code>. * @param output The output to log. Should not be <code>null</code>.
*/ */
protected void handleOutput(String output) { protected void handleOutput(String output) {
if (realThing instanceof Task) {
((Task) realThing).handleOutput(output);
final Object copy = realThing;
if (copy instanceof Task) {
((Task) copy).handleOutput(output);
} else { } else {
super.handleOutput(output); super.handleOutput(output);
} }
@@ -233,8 +235,9 @@ public class UnknownElement extends Task {
*/ */
protected int handleInput(byte[] buffer, int offset, int length) protected int handleInput(byte[] buffer, int offset, int length)
throws IOException { throws IOException {
if (realThing instanceof Task) {
return ((Task) realThing).handleInput(buffer, offset, length);
final Object copy = realThing;
if (copy instanceof Task) {
return ((Task) copy).handleInput(buffer, offset, length);
} }
return super.handleInput(buffer, offset, length); return super.handleInput(buffer, offset, length);
} }
@@ -245,8 +248,9 @@ public class UnknownElement extends Task {
* @param output The output to log. Should not be <code>null</code>. * @param output The output to log. Should not be <code>null</code>.
*/ */
protected void handleFlush(String output) { protected void handleFlush(String output) {
if (realThing instanceof Task) {
((Task) realThing).handleFlush(output);
final Object copy = realThing;
if (copy instanceof Task) {
((Task) copy).handleFlush(output);
} else { } else {
super.handleFlush(output); super.handleFlush(output);
} }
@@ -258,8 +262,9 @@ public class UnknownElement extends Task {
* @param output The error output to log. Should not be <code>null</code>. * @param output The error output to log. Should not be <code>null</code>.
*/ */
protected void handleErrorOutput(String output) { protected void handleErrorOutput(String output) {
if (realThing instanceof Task) {
((Task) realThing).handleErrorOutput(output);
final Object copy = realThing;
if (copy instanceof Task) {
((Task) copy).handleErrorOutput(output);
} else { } else {
super.handleErrorOutput(output); super.handleErrorOutput(output);
} }
@@ -271,8 +276,9 @@ public class UnknownElement extends Task {
* @param output The error output to log. Should not be <code>null</code>. * @param output The error output to log. Should not be <code>null</code>.
*/ */
protected void handleErrorFlush(String output) { protected void handleErrorFlush(String output) {
if (realThing instanceof Task) {
((Task) realThing).handleErrorFlush(output);
final Object copy = realThing;
if (copy instanceof Task) {
((Task) copy).handleErrorFlush(output);
} else { } else {
super.handleErrorFlush(output); super.handleErrorFlush(output);
} }
@@ -283,13 +289,14 @@ public class UnknownElement extends Task {
* (e.g. a data type) then this method does nothing. * (e.g. a data type) then this method does nothing.
*/ */
public void execute() { public void execute() {
if (realThing == null) {
final Object copy = realThing;
if (copy == null) {
// Got here if the runtimeconfigurable is not enabled. // Got here if the runtimeconfigurable is not enabled.
return; return;
} }
try { try {
if (realThing instanceof Task) {
((Task) realThing).execute();
if (copy instanceof Task) {
((Task) copy).execute();
} }
} finally { } finally {
// Finished executing the task // Finished executing the task
@@ -503,8 +510,9 @@ public class UnknownElement extends Task {
* @return the name to use in logging messages. * @return the name to use in logging messages.
*/ */
public String getTaskName() { public String getTaskName() {
return !(realThing instanceof Task) ? super.getTaskName()
: ((Task) realThing).getTaskName();
final Object copy = realThing;
return !(copy instanceof Task) ? super.getTaskName()
: ((Task) copy).getTaskName();
} }


/** /**
@@ -514,8 +522,9 @@ public class UnknownElement extends Task {
* a task. * a task.
*/ */
public Task getTask() { public Task getTask() {
if (realThing instanceof Task) {
return (Task) realThing;
final Object copy = realThing;
if (copy instanceof Task) {
return (Task) copy;
} }
return null; return null;
} }


Loading…
Cancel
Save