Skip to content

Commit 945c3a9

Browse files
committed
Destructure pipeFds, close in finally, limit read length to maxOutputLengthBytes
1 parent 82aa6ed commit 945c3a9

File tree

1 file changed

+32
-23
lines changed

1 file changed

+32
-23
lines changed

aws-runtime/aws-config/native/src/aws/sdk/kotlin/runtime/auth/credentials/executeCommandNative.kt

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,30 @@ internal actual suspend fun executeCommand(
2222
timeoutMillis: Long,
2323
clock: Clock,
2424
): Pair<Int, String> = withContext(SdkDispatchers.IO) {
25-
val pipeFd = IntArray(2)
26-
if (pipe(pipeFd.refTo(0)) != 0) {
25+
val pipeFds = IntArray(2)
26+
if (pipe(pipeFds.refTo(0)) != 0) {
2727
error("Failed to create pipe")
2828
}
29+
val (readFd, writeFd) = pipeFds
2930

3031
val pid = fork()
3132
if (pid == -1) {
33+
close(readFd)
34+
close(writeFd)
3235
error("Failed to fork")
3336
}
3437

3538
if (pid == 0) {
3639
// Child process
37-
close(pipeFd[0]) // Close read end
40+
close(readFd) // Close read end
3841

3942
// Pass stdout and stderr back to parent
40-
dup2(pipeFd[1], STDOUT_FILENO)
41-
dup2(pipeFd[1], STDERR_FILENO)
42-
close(pipeFd[1])
43+
try {
44+
dup2(writeFd, STDOUT_FILENO)
45+
dup2(writeFd, STDERR_FILENO)
46+
} finally {
47+
close(writeFd)
48+
}
4349

4450
val shell = when (platformProvider.osInfo().family) {
4551
OsFamily.Windows -> "cmd.exe"
@@ -57,28 +63,31 @@ internal actual suspend fun executeCommand(
5763
}
5864

5965
// Parent process
60-
close(pipeFd[1]) // Close write end
61-
62-
val output = buildString {
63-
val buffer = ByteArray(maxOutputLengthBytes.toInt())
64-
65-
withTimeout(timeoutMillis) {
66-
while (true) {
67-
val bytesRead = read(pipeFd[0], buffer.refTo(0), buffer.size.toULong()).toInt()
68-
if (bytesRead <= 0) break
69-
70-
append(buffer.decodeToString(0, bytesRead))
71-
72-
if (length > maxOutputLengthBytes) {
73-
close(pipeFd[0])
74-
throw CredentialsProviderException("Process output exceeded limit of $maxOutputLengthBytes bytes")
66+
close(writeFd) // Close write end
67+
68+
val output = try {
69+
buildString {
70+
val buffer = ByteArray(1024)
71+
var totalBytesRead = 0L
72+
73+
withTimeout(timeoutMillis) {
74+
while (true) {
75+
val nBytes = minOf(maxOutputLengthBytes - totalBytesRead, buffer.size.toLong())
76+
if (nBytes == 0L) {
77+
throw CredentialsProviderException("Process output exceeded limit of $maxOutputLengthBytes bytes")
78+
}
79+
80+
val rc = read(readFd, buffer.refTo(0), nBytes.toULong()).toInt()
81+
if (rc <= 0) break
82+
totalBytesRead += rc
83+
append(buffer.decodeToString(0, rc))
7584
}
7685
}
7786
}
87+
} finally {
88+
close(readFd)
7889
}
7990

80-
close(pipeFd[0])
81-
8291
memScoped {
8392
val status = alloc<IntVar>()
8493
waitpid(pid, status.ptr, 0)

0 commit comments

Comments
 (0)