mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-31 04:36:43 +08:00
GT-2912 - fix CPIO filesystem infinite loop when opening bad file.
Also improve "getinfo" to show info elements that it should have been showing but were lost.
This commit is contained in:
+57
-51
@@ -48,33 +48,20 @@ public class CpioFileSystem extends GFileSystemBase {
|
|||||||
public void open(TaskMonitor monitor) throws IOException, CryptoException, CancelledException {
|
public void open(TaskMonitor monitor) throws IOException, CryptoException, CancelledException {
|
||||||
monitor.setMessage("Opening CPIO...");
|
monitor.setMessage("Opening CPIO...");
|
||||||
|
|
||||||
byte[] bytes = provider.readBytes(0, provider.length());
|
try (CpioArchiveInputStream cpioInputStream =
|
||||||
InputStream inputStream = new ByteArrayInputStream(bytes);
|
new CpioArchiveInputStream(provider.getInputStream(0))) {
|
||||||
|
CpioArchiveEntry entry;
|
||||||
try (CpioArchiveInputStream cpioInputStream = new CpioArchiveInputStream(inputStream)) {
|
while ((entry = cpioInputStream.getNextCPIOEntry()) != null) {
|
||||||
while (!monitor.isCancelled()) {
|
skipEntryContents(cpioInputStream, monitor);
|
||||||
/* TODO is this check needed?
|
storeEntry(entry, monitor);
|
||||||
if ( cpioInputStream.available() == 0 ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
try {
|
|
||||||
CpioArchiveEntry entry = cpioInputStream.getNextCPIOEntry();
|
|
||||||
if (entry == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
readEntryContents(cpioInputStream, monitor);//ignore contents now, but it must be read from stream
|
|
||||||
storeEntry(entry, monitor);
|
|
||||||
}
|
|
||||||
catch (EOFException e) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
FSUtilities.displayException(this, null, "Error While Opening CPIO",
|
|
||||||
e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (EOFException e) {
|
||||||
|
// silently ignore EOFExceptions
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
FSUtilities.displayException(this, null, "Error While Opening CPIO", e.getMessage(), e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -112,21 +99,31 @@ public class CpioFileSystem extends GFileSystemBase {
|
|||||||
StringBuilder buffer = new StringBuilder();
|
StringBuilder buffer = new StringBuilder();
|
||||||
try {
|
try {
|
||||||
buffer.append("Name: " + entry.getName() + "\n");
|
buffer.append("Name: " + entry.getName() + "\n");
|
||||||
buffer.append("Checksum: " + Long.toHexString(entry.getChksum()) + "\n");
|
|
||||||
buffer.append("Format: " + Long.toHexString(entry.getFormat()) + "\n");
|
buffer.append("Format: " + Long.toHexString(entry.getFormat()) + "\n");
|
||||||
buffer.append("GID: " + Long.toHexString(entry.getGID()) + "\n");
|
buffer.append("GID: " + Long.toHexString(entry.getGID()) + "\n");
|
||||||
buffer.append("Inode: " + Long.toHexString(entry.getInode()) + "\n");
|
buffer.append("Inode: " + Long.toHexString(entry.getInode()) + "\n");
|
||||||
buffer.append("Last Modified: " + entry.getLastModifiedDate() + "\n");
|
buffer.append("Last Modified: " + entry.getLastModifiedDate() + "\n");
|
||||||
buffer.append("Links: " + Long.toHexString(entry.getNumberOfLinks()) + "\n");
|
buffer.append("Links: " + Long.toHexString(entry.getNumberOfLinks()) + "\n");
|
||||||
buffer.append("Mode: " + Long.toHexString(entry.getMode()) + "\n");
|
buffer.append("Mode: " + Long.toHexString(entry.getMode()) + "\n");
|
||||||
buffer.append("Remote Device: " + Long.toHexString(entry.getRemoteDevice()) + "\n");
|
|
||||||
buffer.append("Size: " + Long.toHexString(entry.getSize()) + "\n");
|
buffer.append("Size: " + Long.toHexString(entry.getSize()) + "\n");
|
||||||
buffer.append("Time: " + new Date(entry.getTime()) + "\n");
|
buffer.append("Time: " + new Date(entry.getTime()) + "\n");
|
||||||
buffer.append("UID: " + Long.toHexString(entry.getUID()) + "\n");
|
buffer.append("UID: " + Long.toHexString(entry.getUID()) + "\n");
|
||||||
buffer.append("Device ID: " + Long.toHexString(entry.getDevice()) + "\n");
|
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
// ignore
|
// ignore
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
buffer.append("Device ID: " + Long.toHexString(entry.getDevice()) + "\n");
|
||||||
|
buffer.append("Remote Device: " + Long.toHexString(entry.getRemoteDevice()) + "\n");
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
// ignore old format missing exception
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
buffer.append("Checksum: " + Long.toHexString(entry.getChksum()) + "\n");
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
// ignore new format missing exception
|
||||||
}
|
}
|
||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
@@ -138,28 +135,22 @@ public class CpioFileSystem extends GFileSystemBase {
|
|||||||
if (!fileEntry.isRegularFile()) {
|
if (!fileEntry.isRegularFile()) {
|
||||||
throw new IOException("CPIO entry " + file.getName() + " is not a regular file.");
|
throw new IOException("CPIO entry " + file.getName() + " is not a regular file.");
|
||||||
}
|
}
|
||||||
byte[] bytes = provider.readBytes(0, provider.length());
|
try (CpioArchiveInputStream cpioInputStream =
|
||||||
InputStream inputStream = new ByteArrayInputStream(bytes);
|
new CpioArchiveInputStream(provider.getInputStream(0));) {
|
||||||
CpioArchiveInputStream cpioInputStream = new CpioArchiveInputStream(inputStream);
|
|
||||||
try {
|
CpioArchiveEntry entry;
|
||||||
while (true) {
|
while ((entry = cpioInputStream.getNextCPIOEntry()) != null) {
|
||||||
if (monitor.isCancelled()) {
|
if (!entry.equals(fileEntry)) {
|
||||||
break;
|
skipEntryContents(cpioInputStream, monitor);
|
||||||
}
|
}
|
||||||
CpioArchiveEntry entry = cpioInputStream.getNextCPIOEntry();
|
else {
|
||||||
if (entry == null) {
|
byte[] entryBytes = readEntryContents(cpioInputStream, monitor);
|
||||||
break;
|
|
||||||
}
|
|
||||||
byte[] entryBytes = readEntryContents(cpioInputStream, monitor);
|
|
||||||
if (entry.equals(fileEntry)) {
|
|
||||||
return new ByteArrayInputStream(entryBytes);
|
return new ByteArrayInputStream(entryBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException e) {//unknown MODES..
|
catch (IllegalArgumentException e) {
|
||||||
}
|
//unknown MODES..
|
||||||
finally {
|
|
||||||
cpioInputStream.close();
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -189,18 +180,33 @@ public class CpioFileSystem extends GFileSystemBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private byte[] readEntryContents(CpioArchiveInputStream cpioInputStream, TaskMonitor monitor)
|
private byte[] readEntryContents(CpioArchiveInputStream cpioInputStream, TaskMonitor monitor)
|
||||||
throws IOException {
|
throws IOException, CancelledException {
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
byte[] buffer = new byte[64 * 1024];
|
||||||
while (true) {
|
while (true) {
|
||||||
if (monitor.isCancelled()) {
|
if (monitor.isCancelled()) {
|
||||||
return null;
|
throw new CancelledException();
|
||||||
}
|
}
|
||||||
int b = cpioInputStream.read();
|
int bytesRead = cpioInputStream.read(buffer);
|
||||||
if (b == -1) {
|
if (bytesRead <= 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
out.write(b);
|
out.write(buffer, 0, bytesRead);
|
||||||
}
|
}
|
||||||
return out.toByteArray();
|
return out.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void skipEntryContents(CpioArchiveInputStream cpioInputStream, TaskMonitor monitor)
|
||||||
|
throws IOException, CancelledException {
|
||||||
|
byte[] buffer = new byte[64 * 1024];
|
||||||
|
while (true) {
|
||||||
|
if (monitor.isCancelled()) {
|
||||||
|
throw new CancelledException();
|
||||||
|
}
|
||||||
|
int bytesRead = cpioInputStream.read(buffer);
|
||||||
|
if (bytesRead <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user