@@ -97,6 +97,7 @@ @implementation AppInstaller
9797
9898 // Setting _performedStage1Installation on main thread must be synchronzied with reading it from new connection handler
9999 BOOL _performedStage1Installation;
100+ BOOL _receivedAppcastItemData;
100101
101102 BOOL _performedStage2Installation;
102103 BOOL _performedStage3Installation;
@@ -142,9 +143,9 @@ - (BOOL)listener:(NSXPCListener *)__unused listener shouldAcceptNewConnection:(N
142143 BOOL connectionCodeSigningValidationSkipped = NO ;
143144 #endif
144145
145- // It's safe to allow any connections once stage 1 installation is complete
146+ // It's safe to allow any connections once stage 1 installation is complete and appcast data has been received.
146147 // This is to allow general updaters to resume the installation.
147- if (!_performedStage1Installation) {
148+ if (!_performedStage1Installation || !_receivedAppcastItemData ) {
148149 BOOL passesValidation;
149150 NSError *validationError = nil ;
150151 SUValidateConnectionStatus status = [SUCodeSigningVerifier validateConnection: newConnection error: &validationError];
@@ -597,6 +598,10 @@ - (void)handleMessageWithIdentifier:(int32_t)identifier data:(NSData *)data
597598 [self extractAndInstallUpdate ];
598599 });
599600 } else if (identifier == SPUSentUpdateAppcastItemData) {
601+ os_unfair_lock_lock (&_newConnectionLock);
602+ _receivedAppcastItemData = YES ;
603+ os_unfair_lock_unlock (&_newConnectionLock);
604+
600605 SUAppcastItem *updateItem = (data != nil ) ? (SUAppcastItem *)SPUUnarchiveRootObjectSecurely (data, [SUAppcastItem class ]) : nil ;
601606 if (updateItem != nil ) {
602607 SPUInstallationInfo *installationInfo = [[SPUInstallationInfo alloc ] initWithAppcastItem: updateItem];
0 commit comments