mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8264111: (fs) Leaking NativeBuffers in case of errors during UnixUserDefinedFileAttributeView.read/write
Reviewed-by: alanb
This commit is contained in:
parent
57115fa23d
commit
4e74de4b2e
1 changed files with 71 additions and 64 deletions
|
@ -25,6 +25,7 @@
|
|||
|
||||
package sun.nio.fs;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.nio.file.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.io.IOException;
|
||||
|
@ -169,17 +170,31 @@ abstract class UnixUserDefinedFileAttributeView
|
|||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
|
||||
NativeBuffer nb;
|
||||
long address;
|
||||
if (dst instanceof sun.nio.ch.DirectBuffer) {
|
||||
nb = null;
|
||||
address = ((sun.nio.ch.DirectBuffer)dst).address() + pos;
|
||||
if (dst instanceof sun.nio.ch.DirectBuffer buf) {
|
||||
try {
|
||||
long address = buf.address() + pos;
|
||||
int n = read(name, address, rem);
|
||||
dst.position(pos + n);
|
||||
return n;
|
||||
} finally {
|
||||
Reference.reachabilityFence(buf);
|
||||
}
|
||||
} else {
|
||||
// substitute with native buffer
|
||||
nb = NativeBuffers.getNativeBuffer(rem);
|
||||
address = nb.address();
|
||||
}
|
||||
try (NativeBuffer nb = NativeBuffers.getNativeBuffer(rem)) {
|
||||
long address = nb.address();
|
||||
int n = read(name, address, rem);
|
||||
|
||||
// copy from buffer into backing array
|
||||
int off = dst.arrayOffset() + pos + Unsafe.ARRAY_BYTE_BASE_OFFSET;
|
||||
unsafe.copyMemory(null, address, dst.array(), off, n);
|
||||
dst.position(pos + n);
|
||||
|
||||
return n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int read(String name, long address, int rem) throws IOException {
|
||||
int fd = -1;
|
||||
try {
|
||||
fd = file.openForAttributeAccess(followLinks);
|
||||
|
@ -187,37 +202,26 @@ abstract class UnixUserDefinedFileAttributeView
|
|||
x.rethrowAsIOException(file);
|
||||
}
|
||||
try {
|
||||
try {
|
||||
int n = fgetxattr(fd, nameAsBytes(file,name), address, rem);
|
||||
int n = fgetxattr(fd, nameAsBytes(file, name), address, rem);
|
||||
|
||||
// if remaining is zero then fgetxattr returns the size
|
||||
if (rem == 0) {
|
||||
if (n > 0)
|
||||
throw new UnixException(ERANGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// copy from buffer into backing array if necessary
|
||||
if (nb != null) {
|
||||
int off = dst.arrayOffset() + pos + Unsafe.ARRAY_BYTE_BASE_OFFSET;
|
||||
unsafe.copyMemory(null, address, dst.array(), off, n);
|
||||
}
|
||||
dst.position(pos + n);
|
||||
return n;
|
||||
} catch (UnixException x) {
|
||||
String msg = (x.errno() == ERANGE) ?
|
||||
"Insufficient space in buffer" : x.getMessage();
|
||||
throw new FileSystemException(file.getPathForExceptionMessage(),
|
||||
null, "Error reading extended attribute '" + name + "': " + msg);
|
||||
} finally {
|
||||
close(fd);
|
||||
// if remaining is zero then fgetxattr returns the size
|
||||
if (rem == 0) {
|
||||
if (n > 0)
|
||||
throw new UnixException(ERANGE);
|
||||
return 0;
|
||||
}
|
||||
return n;
|
||||
} catch (UnixException x) {
|
||||
String msg = (x.errno() == ERANGE) ?
|
||||
"Insufficient space in buffer" : x.getMessage();
|
||||
throw new FileSystemException(file.getPathForExceptionMessage(),
|
||||
null, "Error reading extended attribute '" + name + "': " + msg);
|
||||
} finally {
|
||||
if (nb != null)
|
||||
nb.release();
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int write(String name, ByteBuffer src) throws IOException {
|
||||
if (System.getSecurityManager() != null)
|
||||
checkAccess(file.getPathForPermissionCheck(), false, true);
|
||||
|
@ -227,30 +231,40 @@ abstract class UnixUserDefinedFileAttributeView
|
|||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
|
||||
NativeBuffer nb;
|
||||
long address;
|
||||
if (src instanceof sun.nio.ch.DirectBuffer) {
|
||||
nb = null;
|
||||
address = ((sun.nio.ch.DirectBuffer)src).address() + pos;
|
||||
if (src instanceof sun.nio.ch.DirectBuffer buf) {
|
||||
try {
|
||||
long address = buf.address() + pos;
|
||||
write(name, address, rem);
|
||||
src.position(pos + rem);
|
||||
return rem;
|
||||
} finally {
|
||||
Reference.reachabilityFence(buf);
|
||||
}
|
||||
} else {
|
||||
// substitute with native buffer
|
||||
nb = NativeBuffers.getNativeBuffer(rem);
|
||||
address = nb.address();
|
||||
try (NativeBuffer nb = NativeBuffers.getNativeBuffer(rem)) {
|
||||
long address = nb.address();
|
||||
|
||||
if (src.hasArray()) {
|
||||
// copy from backing array into buffer
|
||||
int off = src.arrayOffset() + pos + Unsafe.ARRAY_BYTE_BASE_OFFSET;
|
||||
unsafe.copyMemory(src.array(), off, null, address, rem);
|
||||
} else {
|
||||
// backing array not accessible so transfer via temporary array
|
||||
byte[] tmp = new byte[rem];
|
||||
src.get(tmp);
|
||||
src.position(pos); // reset position as write may fail
|
||||
unsafe.copyMemory(tmp, Unsafe.ARRAY_BYTE_BASE_OFFSET, null,
|
||||
address, rem);
|
||||
if (src.hasArray()) {
|
||||
// copy from backing array into buffer
|
||||
int off = src.arrayOffset() + pos + Unsafe.ARRAY_BYTE_BASE_OFFSET;
|
||||
unsafe.copyMemory(src.array(), off, null, address, rem);
|
||||
} else {
|
||||
// backing array not accessible so transfer via temporary array
|
||||
byte[] tmp = new byte[rem];
|
||||
src.get(tmp);
|
||||
src.position(pos); // reset position as write may fail
|
||||
unsafe.copyMemory(tmp, Unsafe.ARRAY_BYTE_BASE_OFFSET, null,
|
||||
address, rem);
|
||||
}
|
||||
|
||||
write(name, address, rem);
|
||||
src.position(pos + rem);
|
||||
return rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void write(String name, long address, int rem) throws IOException {
|
||||
int fd = -1;
|
||||
try {
|
||||
fd = file.openForAttributeAccess(followLinks);
|
||||
|
@ -258,20 +272,13 @@ abstract class UnixUserDefinedFileAttributeView
|
|||
x.rethrowAsIOException(file);
|
||||
}
|
||||
try {
|
||||
try {
|
||||
fsetxattr(fd, nameAsBytes(file,name), address, rem);
|
||||
src.position(pos + rem);
|
||||
return rem;
|
||||
} catch (UnixException x) {
|
||||
throw new FileSystemException(file.getPathForExceptionMessage(),
|
||||
fsetxattr(fd, nameAsBytes(file,name), address, rem);
|
||||
} catch (UnixException x) {
|
||||
throw new FileSystemException(file.getPathForExceptionMessage(),
|
||||
null, "Error writing extended attribute '" + name + "': " +
|
||||
x.getMessage());
|
||||
} finally {
|
||||
close(fd);
|
||||
}
|
||||
} finally {
|
||||
if (nb != null)
|
||||
nb.release();
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue