Skip to content

Enable Increased Memory Limit for free teams - #4

Open
playportdev wants to merge 1 commit into
SideStore:mainfrom
playportdev:increased-memory-limit-free
Open

playportdev wants to merge 1 commit into
SideStore:mainfrom
playportdev:increased-memory-limit-free

Conversation

@playportdev

Copy link
Copy Markdown

Fixes the SideSign side of SideStore/SideStore#1616: apps signed with a free Apple ID lose com.apple.developer.kernel.increased-memory-limit, so they get the normal memory limit (about 3.3 GB on an 8 GB phone, against about 6 GB with the entitlement).

Cause

Apple offers Increased Memory Limit to free teams (Xcode with a Personal Team, AltStore 2.2+ and GetMoreRam all get it), but:

  • Feature.freeFeatures does not list increasedMemoryLimit, so SideStore's updateFeatures drops it for a free team, and
  • the legacy ios/updateAppId.action request cannot enable it anyway. It is only enabled through the developer services v1 API, with a bundleIdCapabilities relationship on PATCH v1/bundleIds/<id>.

Changes

  • Feature.capabilityID: the v1 capability ID of a feature the legacy request cannot enable (INCREASED_MEMORY_LIMIT), nil for legacy features.
  • updateAppID leaves such features out of the legacy request. After it succeeds, it enables the ones set to true with one v1 PATCH. This is the request AltSign sends since rileytestut/AltSign@b2c8861, and the one hugeBlack/GetMoreRam sends. If Apple refuses the PATCH, updateAppID logs the refusal and still returns the updated App ID, so an install behaves as it does today instead of failing.
  • freeFeatures lists increasedMemoryLimit (it is already in freeEntitlements).
  • sendServicesBodyRequest: a v1 request with its own method and JSON body. sendServicesRequest sends a query through POST plus X-HTTP-Method-Override, which cannot carry a JSON:API body. Both share one servicesHeaders builder.

SideStore needs no code change beyond the submodule bump. OperationEntitlements already asks for the entitlement, and the signer keeps every entitlement that is in both the profile and the app. Because the legacy App ID listing may not report the v1 capability, SideStore may send the update on every install or refresh. That costs one extra idempotent request.

Testing

Tests/SideSignTests/CapabilityTests.swift mocks both requests with a URLProtocol:

  • the legacy body carries App Groups but no increasedMemoryLimit;
  • the PATCH goes to services/v1/bundleIds/<id> and names INCREASED_MEMORY_LIMIT, enabled;
  • there is no PATCH when the feature is absent or false;
  • a refused PATCH (HTTP 409 with a JSON:API error) does not fail the update.

swift test passes (9 tests) on Linux, Swift 6.4, with a local libunicorn for AnisetteKit. To build the existing SideSignTests.swift on Linux I added import Foundation locally; that change is not in this PR. I have not run it against Apple's servers or on a phone through a SideStore build. The request body is the same as AltSign's and GetMoreRam's.

Not included: extendedVirtualAddressing and increasedDebuggingMemoryLimit (GetMoreRamExtended sends EXTENDED_VIRTUAL_ADDRESSING the same way). Each would only need its capabilityID and a freeFeatures entry once someone confirms Apple grants it to free teams.

Overlaps #3 in the freeFeatures list (one-line conflict).

Apple offers the Increased Memory Limit capability to free teams, but the
legacy updateAppId.action request cannot enable it, and Feature.freeFeatures
did not list it, so SideStore dropped it and the profile came back without
com.apple.developer.kernel.increased-memory-limit (SideStore#1616).

- Feature.capabilityID names the developer services v1 capability ID of a
  feature the legacy request cannot enable (INCREASED_MEMORY_LIMIT).
- updateAppID leaves such features out of the legacy request and, after it,
  enables them with a PATCH to v1/bundleIds/<id> (bundleIdCapabilities), the
  request Xcode, AltSign (b2c8861) and GetMoreRam send. If Apple refuses it,
  the update still succeeds without the capability, as before.
- freeFeatures lists increasedMemoryLimit.
- sendServicesBodyRequest sends a v1 request with its own method and JSON
  body; the header set is shared with sendServicesRequest.

Tests mock both requests: the legacy body carries no modern feature, the
PATCH body names the capability, no PATCH without it, and a refused PATCH
does not fail the update.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant