Skip to content

Commit 140d7de

Browse files
authored
Fix: Exec provider potential deadlock (#1457)
* Fix: Exec Process deadlock WaitForExit should have been called after all other methods are called on the process * Non-blocking standard output stream parsing * Force buffer flush for non-infinite timeout
1 parent 37d8e3d commit 140d7de

File tree

1 file changed

+22
-6
lines changed

1 file changed

+22
-6
lines changed

src/KubernetesClient/KubernetesClientConfiguration.ConfigFile.cs

+22-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Net;
66
using System.Runtime.InteropServices;
77
using System.Security.Cryptography.X509Certificates;
8+
using System.Text;
89

910
namespace k8s
1011
{
@@ -537,12 +538,29 @@ public static ExecCredentialResponse ExecuteExternalCommand(ExternalExecution co
537538

538539
try
539540
{
540-
if (!process.WaitForExit((int)(ExecTimeout.TotalMilliseconds)))
541+
var output = new StringBuilder();
542+
process.OutputDataReceived += (_, args) =>
543+
{
544+
if (args.Data != null)
545+
{
546+
output.Append(args.Data);
547+
}
548+
};
549+
process.BeginOutputReadLine();
550+
551+
if (!process.WaitForExit((int)ExecTimeout.TotalMilliseconds))
541552
{
542553
throw new KubeConfigException("external exec failed due to timeout");
543554
}
544555

545-
var responseObject = KubernetesJson.Deserialize<ExecCredentialResponse>(process.StandardOutput.ReadToEnd());
556+
// Force flush the output buffer to avoid case of missing data
557+
if (ExecTimeout != Timeout.InfiniteTimeSpan)
558+
{
559+
process.WaitForExit();
560+
}
561+
562+
var responseObject = KubernetesJson.Deserialize<ExecCredentialResponse>(output.ToString());
563+
546564
if (responseObject == null || responseObject.ApiVersion != config.ApiVersion)
547565
{
548566
throw new KubeConfigException(
@@ -553,10 +571,8 @@ public static ExecCredentialResponse ExecuteExternalCommand(ExternalExecution co
553571
{
554572
return responseObject;
555573
}
556-
else
557-
{
558-
throw new KubeConfigException($"external exec failed missing token or clientCertificateData field in plugin output");
559-
}
574+
575+
throw new KubeConfigException($"external exec failed missing token or clientCertificateData field in plugin output");
560576
}
561577
catch (JsonException ex)
562578
{

0 commit comments

Comments
 (0)