16.0.0

From Nintendo Switch Brew
Jump to navigation Jump to search

The Switch 16.0.0 system update was released on February 21, 2023 (UTC). This Switch update was released for the following regions: ALL, CHN.

Security flaws fixed: <fill this in manually later, see the updatedetails page from the ninupdates-report page(s) once available for now>.

Change-log

Official ALL change-log:

  • User nicknames that cannot be used will be replaced with “???” which can be updated from the profile settings.
  • General system stability improvements to enhance the user's experience.

System Titles

  • New sysmodule ngc was added (0100000000000050).
  • All sysmodules were updated (excluding stubbed-lbl).
  • Most SystemData were updated, except for: Chinese and Korean dictionaries, Dictionary, AvatarImage, UrlBlackList, ControllerIcon, ApplicationBlackList, FunctionBlackList.
  • Most applets were updated, except for: cabinet, controller, netConnect, swkbd, miiEdit, starter, maintenance.

NPDM changes (besides usual version-bump):

  • boot2.ProdBoot now has access to ncm.
  • friends no longer has access to csrng.
  • nifm now has htc:nd access.
  • nifm, ldn, ns: pl:u access was replaced with pl:s.
  • ns now has access to ns:am2 and ns:su (for GetService).
  • nim no longer has access to spl: (on older versions this was unused besides service-init).
  • vi now has pl:u access.
  • glue now has hosted-service pl:u access (moved from sdb) and access to svcCreateSharedMemory.
  • fatal had access for the following removed: nvdrv:s, pl:u, vi:s.
  • sdb had access for pl:u (hosted-service) and svcCreateSharedMemory removed.
  • qlaunch, playerSelect, photoViewer, myPage: access to ngc:u was added.

The SafeMode bootpkgs KIP for PCV had "Default CPU Core" changed from 3 to 63.

RomFs changes:

  • CertStore: "/ssl_TrustedCerts.bdf" updated and "/ssl_TrustedCerts.Ounce.bdf" added.
  • ErrorMessage: updated
  • BrowserDll:
    • "/browser/MediaControlsInline.css" updated
    • "/browser/MediaControlsInline.js" updated
    • "/browser/UserCssCore0.dat" added
    • "/browser/UserCss.dat" updated
    • "/buildinfo/buildinfo.dat" updated
    • "/gfxShader/" added, which contains "BrowserOffscreenDrawer.bnsh".
    • "/lyt/Browse/Page.arc" updated
    • "/nro/" The various NROs located under here were updated.
  • Help: "/legallines.htdocs/img/HDMI.png" and "/legallines.htdocs/index.html" were updated.
  • NgWord: updated.
  • LocalNews: "/image/LnSupIntro/main_Other.jpg", "/message/EUnl/localNews.msbt.szs", "/message/revision.txt" updated.
  • Eula: "/KRko/Eula.msbt.szs" and "/revision.txt" updated.
  • FirmwareDebugSettings: updated
  • NgWord2: updated. Added "/ac_similar_form_nx" and "/table_similar_form_nx".
  • NgWordT: "/mars_dirty_words_db" updated
  • applets: various UI/message/gfx data updated.
  • web-applets: "/buildinfo/buildinfo.dat" and "/.nrr/modules.nrr" updated.

IPC Interface Changes

  • The following interfaces were removed:
    • nn::pl::detail::IPlatformServiceManager
  • The following interfaces were added:
    • nn::ngc::detail::IService
    • nn::pl::sharedresource::detail::IPlatformSharedResourceManager
  • The following interfaces were changed:
    • nn::account::IAccountEntityServiceForAccountPolicy
      • Added command 910 - inbytes: 0, outbytes: 0
    • nn::account::IAccountServiceForAdministrator
      • Added command 910 - inbytes: 0, outbytes: 0
    • nn::account::baas::IAdministrator
      • Added command 161 - inbytes: 0, outbytes: 0
    • nn::account::baas::IManagerForSystemService
      • Added command 161 - inbytes: 0, outbytes: 0
    • nn::account::nas::IOAuthProcedureForNintendoAccountLinkage
      • Added command 200 - buffers: [9, 9, 9], inbytes: 0, outbytes: 0, outinterfaces: ['nn::account::detail::IAsyncContext']
    • nn::am::service::IApplicationFunctions
      • Removed command 34 - buffers: [5], inbytes: 0, outbytes: 1
    • nn::am::service::IDebugFunctions
      • Added command 51 - inbytes: 4, outbytes: 0
      • Added command 300 - inbytes: 0, outbytes: 0
    • nn::am::service::IHomeMenuFunctions
      • Added command 50 - inbytes: 0, outbytes: 0
      • Added command 51 - inbytes: 0, outbytes: 0
    • nn::aocsrv::detail::IAddOnContentManager
      • Added command 300 - inbytes: 8, outbytes: 0, pid: True
      • Added command 301 - buffers: [6], inbytes: 16, outbytes: 0, pid: True
      • Added command 302 - inbytes: 0, outbytes: 0
    • nn::bsdsocket::cfg::ServerInterface
      • Added command 13 - buffers: [5], inbytes: 0, outbytes: 0
      • Added command 14 - buffers: [5], inbytes: 0, outbytes: 0
      • Added command 15 - buffers: [5], inbytes: 0, outbytes: 0
    • nn::codec::detail::IHardwareOpusDecoderManager
      • Added command 8 - inbytes: 16, outbytes: 4
      • Added command 9 - buffers: [25], inbytes: 0, outbytes: 4
    • nn::dauth::detail::IService
      • Added command 3 - inbytes: 8, outbytes: 16
      • Added command 13 - inbytes: 16, outbytes: 16
    • nn::dp2hdmi::detail::IDp2hdmiController
      • Added command 7 - inbytes: 0, outbytes: 0
      • Added command 8 - inbytes: 4, inhandles: [1], outbytes: 0
    • nn::ec::IContentsServiceManager
      • Added command 1 - buffers: [5], inbytes: 96, outbytes: 0, outhandles: [1], outinterfaces: [None], pid: True
    • nn::es::IActiveRightsContext
      • Changed command 11 - inbytes: 8 -> 16 (final state: buffers: [6], inbytes: 16, outbytes: 4)
      • Changed command 16 - inbytes: 8 -> 16 (final state: buffers: [6], inbytes: 16, outbytes: 4)
      • Added command 18 - buffers: [6, 6, 6], inbytes: 16, outbytes: 8
    • nn::es::IETicketService
      • Removed command 3001 - buffers: [22, 22, 5], inbytes: 0, outbytes: 0
      • Removed command 3002 - buffers: [22], inbytes: 0, outbytes: 0
    • nn::fan::detail::IManager
      • Added command 1 - inbytes: 4, outbytes: 4
    • nn::friends::detail::ipc::IServiceCreator
      • Changed command 2 - outinterfaces: ['0x7100078D58'] -> ['0x710007990C'] (final state: inbytes: 0, outbytes: 0, outinterfaces: ['0x710007990C'])
    • nn::fssrv::sf::IFileSystemProxy
      • Added command 10 - buffers: [25], inbytes: 16, outbytes: 0, outinterfaces: ['nn::fssrv::sf::IFileSystem']
      • Changed command 206 - inbytes: 4 -> 8 (final state: buffers: [25], inbytes: 8, outbytes: 0, outinterfaces: ['nn::fssrv::sf::IStorage'])
      • Removed command 609 - buffers: [25], inbytes: 0, outbytes: 16
      • Changed command 610 - inbytes: 0 -> 1 (final state: buffers: [25], inbytes: 1, outbytes: 24)
    • nn::fssrv::sf::IFileSystemProxyForLoader
      • Changed command 0 - inbytes: 8 -> 16 (final state: buffers: [26, 25], inbytes: 16, outbytes: 0, outinterfaces: ['nn::fssrv::sf::IFileSystem'])
    • nn::hid::IHidDebugServer
      • Added command 25 - inbytes: 28, outbytes: 0
      • Added command 26 - inbytes: 0, outbytes: 0
      • Added command 3000 - inbytes: 0, outbytes: 0
    • nn::hid::IHidServer
      • Added command 26 - inbytes: 8, outbytes: 0, pid: True
    • nn::hid::IHidSystemServer
      • Removed command 1130 - inbytes: 16, inhandles: [1], outbytes: 0, pid: True
    • nn::ncm::IContentManager
      • Added command 15 - inbytes: 4, outbytes: 0
    • nn::ncm::IContentStorage
      • Changed command 19 - inbytes: 16 -> 17 (final state: inbytes: 17, outbytes: 24)
      • Changed command 20 - inbytes: 16 -> 17 (final state: inbytes: 17, outbytes: 24)
      • Changed command 27 - inbytes: 32 -> 33 (final state: inbytes: 33, outbytes: 24)
    • nn::nim::detail::INetworkInstallManager
      • Changed command 10 - outbytes: 88 -> 96 (final state: inbytes: 16, outbytes: 96)
    • nn::ns::detail::IApplicationManagerInterface
      • Changed command 21 - outbytes: 0 -> 1 (final state: buffers: [22], inbytes: 16, outbytes: 1)
      • Removed command 604 - inbytes: 16, outbytes: 0
      • Added command 611 - inbytes: 16, outbytes: 0
    • nn::ns::detail::IDocumentInterface
      • Changed command 21 - outbytes: 0 -> 1 (final state: buffers: [22], inbytes: 16, outbytes: 1)
    • nn::ns::detail::IDynamicRightsInterface
      • Removed command 14 - buffers: [5], inbytes: 8, outbytes: 1
    • nn::pdm::detail::IQueryService
      • Changed command 4 - outbytes: 40 -> 72 (final state: inbytes: 16, outbytes: 72)
      • Changed command 5 - outbytes: 40 -> 72 (final state: inbytes: 32, outbytes: 72)
    • nn::pl::detail::IPlatformServiceManagerForSystem
      • Removed command 0 - inbytes: 4, outbytes: 0
      • Removed command 1 - inbytes: 4, outbytes: 4
      • Removed command 2 - inbytes: 4, outbytes: 4
      • Removed command 3 - inbytes: 4, outbytes: 4
      • Removed command 4 - inbytes: 0, outbytes: 0, outhandles: [1]
      • Removed command 5 - buffers: [6, 6, 6], inbytes: 8, outbytes: 8
      • Removed command 6 - buffers: [6, 6, 6], inbytes: 8, outbytes: 8
    • nn::ssl::sf::ISslConnection
      • Added command 28 - buffers: [5], inbytes: 4, outbytes: 4
      • Added command 29 - buffers: [6], inbytes: 0, outbytes: 0
      • Added command 30 - inbytes: 8, outbytes: 0
      • Added command 31 - buffers: [5], inbytes: 0, outbytes: 0
      • Added command 32 - inbytes: 0, outbytes: 2
      • Added command 33 - buffers: [6, 5, 5], inbytes: 0, outbytes: 0
      • Added command 34 - inbytes: 4, outbytes: 0
      • Added command 35 - inbytes: 0, outbytes: 4
    • nn::ssl::sf::ISslContext
      • Added command 12 - buffers: [5, 5], inbytes: 4, outbytes: 8
      • Added command 13 - buffers: [6, 6, 5], inbytes: 4, outbytes: 8
    • nn::ssl::sf::ISslContextForSystem
      • Added command 12 - buffers: [5, 5], inbytes: 4, outbytes: 8
      • Added command 13 - buffers: [6, 6, 5], inbytes: 4, outbytes: 8
    • nn::visrv::sf::IManagerDisplayService
      • Added command 2060 - inbytes: 4, outbytes: 0
      • Added command 2062 - buffers: [5], inbytes: 4, outbytes: 0
      • Added command 2063 - inbytes: 8, outbytes: 0
      • Added command 6014 - inbytes: 16, outbytes: 0
      • Added command 6015 - inbytes: 8, outbytes: 0
    • nn::visrv::sf::IManagerRootService
      • Added command 100 - inbytes: 0, outbytes: 0
      • Added command 101 - inbytes: 0, outbytes: 0
      • Added command 102 - inbytes: 20, outbytes: 0
      • Added command 103 - buffers: [5], inbytes: 32, outbytes: 4

BootImagePackages

All files in RomFs were updated.

Kernel

  • Compiler upgrade
    • Version is currently unknown, probably ~LLVM 15?
    • Many NOPs inserted to align branch destinations to 16 bytes, many ADRP + ADD pairs replaced with NOP + ADR
    • Compiler now more frequently detecting a reusable computed offset for load/store
  • KThreadStackParameters:
    • Stack parameters are now 0x10 larger.
    • The additional 0x10 bytes appear to be completely unused, at least on prod NX builds of the kernel.
  • KScheduler changes:
    • Idle count tracking has been changed to use two fields ("idle count", "switch count").
      • In UpdateHighestThreads(), switching to the idle thread does idle_count = ++switch_count, and switching to a non-kernel thread does ++switch_count.
      • KProcess now has an additional array of counts ("running_thread_switch_counts"), UpdateHighestThreads() also sets running_thread_switch_counts[core] = switch_count.
    • KDebug::GetRunningThreadInfo() now only succeeds if running_thread_switch_counts[core] == Scheduler->switch_count + 1.
      • Previously, this checked running_thread_idle_counts[core] == Scheduler->idle_count, which meant the thread had to have not switched to idle between its last execution and the GetRunningThreadInfo() wait finishing.
      • Now, this requires the core to have switched directly from the target thread to GetRunningThreadInfo(), which is to say the condition is "The thread is actually running at the target time".
      • In addition, now ResultNoThread is returned if switch_count == idle_count + 1, otherwise ResultUnknownThread is returned; previously only NoThread was returnable.
        • switch_count == idle_count + 1 implies that the switch to GetRunningThreadInfo() happened from idle thread, so ResultNoThread is returned exactly when the running thread was the idle thread.
        • Otherwise, if a thread other than the idle thread was the running thread, UnknownThread is returned.
    • KSchedulerLock::Lock() now always increments count, instead of setting count = 1 when the lock owner is not the current thread.
    • Note: Several KScheduler functions have big assembly changes, but this appears to be pure compiler optimization changes with no semantic differences.
  • KProcess had the creation time member deleted.
  • A new KPageTable::Operate operation was added ("ChangePermsAndRefreshWithFlushDataCache")
    • Previously, all calls to Operate with ChangePermsAndRefresh would flush data cache; now, calls to ChangePermsAndRefresh do not flush data cache and calls to ChangePermsAndRefreshWithFlushDataCache do.
      • ChangePermsAndRefreshWithFlushDataCache is otherwise identical to ChangePermsAndRefresh semantically.
  • QueryIoMapping now supports querying memory regions with KMemoryState_Static in addition to KMemoryState_Io.
  • Some changes surrounding KIoRegion:
    • KIoRegion now uses an intrusive red black tree member for the pool list, rather than an intrusive list node.
    • KIoPool::AddIoRegion() uses the intrusive tree to check fewer regions for Contains().
    • KPageTableBase::UnmapIoRegion now takes the MemoryMapping as argument (which was passed to CreateIoRegion).
      • When mapping is MemoryMapping_Memory, the mapping following is done before unmap:
        • The region is permission changed to be uncached, using ChangePermsAndRefresh (without FlushDataCache).
        • The table's lock is released.
        • cpu::FlushDataCache() is called to flush the mapping.
        • The table's lock is reacquired.
      • All fallible operations now call KernelPanic() on failure, rather than returning the result code
  • KAddressSpaceInfo::GetAddressSpaceStart()/GetAddressSpaceSize() no longer use complicated switch logic to only examine the indices with the right bit-width, and instead just iterate all indices with an if to check bit width.
  • Big changes to KThread waiting/priority inheritance:
    • m_waiter_list, m_lock_owner fields were deleted.
    • New fields m_held_lock_info_list, m_waiting_lock_info were added.
      • This is an intrusive list of new type KThreadLockInfo (storing info on all locks held), and a pointer to the lock this thread is waiting on, if any.
      • There is one lock info for each address key.
      • KThreadLockInfo is slab allocated, count = # of KThreads
      • KThreadLockInfo has the following fields:
        • LockWithPriorityInheritanceThreadTree m_cv_tree; // Tree of threads waiting on the lock, this re-uses the node for condvar/arbiter.
        • KProcessAddress m_address_key;
        • KThread *m_owner;
        • u32 m_waiter_count;
    • This greatly simplifies RemoveWaiterByKey (as there is a single KThreadLockInfo representing all threads waiting on the key).
      • RemoveWaiterByKey now also has an output bool pointer for whether the lock still has waiters, rather than an output s32 pointer for # of waiters.
    • RestorePriority has been shuffled to ensure the new CV tree inside lock info has its invariants maintained across the priority set.
    • Several calls to RestorePriority are now guarded by if statements, to only invoke RestorePriority if there is a possible change in inherited priority.
  • Big changes to crt0/Initialize0/KInitialPageTable/Sleep Manager:
    • KInitialPageTable::Map (and others) now take a new physical-to-virtual-offset argument, and add this to L1 table etc.
    • Changes to Initial Arguments:
      • Initial arguments are now size 0x80.
      • Initial argument pointers are no longer used; Init arguments array addresses are used directly, with presumption that no page boundary is crossed.
      • Initial arguments no longer use setup function/etc.
      • Instead of setting ep = HorizonKernelMain, Initial arguments now set ep = InvokeMain (this function was previously "InvokeEntryPoint")
      • idle stack is now retrieved from KMemoryLayout inside InvokeMain, instead of being a field inside Initial Arguments.
    • After setting up initial arguments, Initialize0 now returns to crt0, which sets sp = InitArguments[0]->sp and calls new function ("Initialize1").
      • All KInitialPageTable calls from here onward now pass g_LinearPhysToVirtDiff, and thus page table accesses are done using the Linear mapping set up by Initialize0.
    • Initialize1 does the following:
      • The initial identity mapping is unmapped in its entirety.
        • The single-page containing crt0 + interrupt vectors is re-identity-mapped as R-X.
        • PageAllocator for this is an extremely simplified new InitialPageAllocator type, which always has exactly two free pages to be allocated.
      • All remaining logic which used to be in Initialize0 happens here, with no changes.
    • TurnOnAllCores now calls a helper function ("TurnOnCore") to turn on the cores.
      • void TurnOnCore(__int64 core, InitArguments *argument);
      • TurnOnCore does virt->phys translation lookup (using at s1e1r) on StartOtherCore (from crt0 page) + argument, and calls smc::CpuOn directly.
        • TurnOnCore is "probably" a KSystemControl function.
    • Sleep handler thread function now sets resume entry addr = StartOtherCore, and sets up an InitArguments for each core.
      • ResumeEntry and ResumeEntryVirtual are now merged/simplified.
  • Changes to pool allocations:
    • Minimum non-secure system pool size is now ~2MB larger (0x2C04000 vs 0x2A0C000).
    • Slab heap gaps size is now 0x9000 smaller (0x1A7000 vs 0x1B0000).
  • KSystemControl::Initialize has been restructured (operations reordered), and now calls a helper which sets up the MT, creates system resource limit, etc.
    • This helper also modifies the KAddressSpaceInfo tables, when memory is large (these were previously read-only).
    • In particular, the following modifications are made to the 39-bit address space infos based on the total memory size:
      • size <= 8 GB: No changes (Heap Region = 8 GB, Alias region = 64 GB)
      • 8 GB < size <= 16 GB: Heap Region = size, Alias Region = 8 * size
      • 16 GB < size <= 32 GB: Heap region = size, Alias region = 128 GB
      • 32 GB <= size: Heap region = 32 GB, Alias region = 128 GB
  • KSystemControl::Init::GenerateRandomRange now supports min=0, max=0xFFFFFFFFFFFFFFFF (previously it was incorrect for this case).
  • New InfoType (0x1B) ("IoRegionHint")
    • This takes a handle to a KIoRegion, and returns the low bits of the region's address.
      • If the region's size is < 0x10000, this is the low 12 bits, otherwise if size < 0x200000, this is the low 16 bits, otherwise it's the low 21 bits.
  • UserspaceAccess functions no longer do adr X30, fail in the loop, now do adr X#, fail before the loop and mov X30, X# in the loop.
  • All code which sets ThreadContext's pstate field now uses the mask 0xF0000000 for aarch64 threads and 0xFE0FFE20 for aarch32 threads.
    • Previously, this used the mask 0xFF0FFE20 for both.
    • This removes the ability to get/set the DIT bit for both aarch64 and aarch32, and removes many other bits for aarch64 only.
  • Interrupt disable logic was removed from a number of functions:
    • KAddressArbiter::SignalAndIncrementIfEqual, KAddressArbiter::SignalAndModifyBasedOnWaitingThreadCount, KAddressArbiter::WaitIfLessThan, KConditionVariable::SignalConditionVariableImpl
  • KConditionVariable::SignalToAddress now does dmb before copying updated value to userspace.
  • KDebugBase functions for DebugEvents were changed to take pointer to params + count, instead of 5 parameter arguments.
    • This propagates up to many/all caller functions.
    • The only variable length parameter counts are DebugEvent_Exception + DebugException_UserBreak/DebugException_DebuggerBreak
      • This copies the variable-count parameters directly to the result exception info without maximum size check.
        • This is not exploitable, because there is no way for userspace to control parameter count, and it will always remain in bounds.
        • Presumably exception info type is larger if compiling for a target with more than 4 CPUs, to prevent out-of-bounds copies.


See Also

System update report(s):


Nintendo Switch System Versions
1.0.0
2.0.02.1.02.2.02.3.0
3.0.03.0.13.0.2
4.0.04.0.14.1.0
5.0.05.0.15.0.25.1.0
6.0.06.0.16.1.06.2.0
7.0.07.0.1
8.0.08.0.18.1.08.1.1
9.0.09.0.19.1.09.2.0
10.0.010.0.110.0.210.0.310.0.410.1.010.1.110.2.0
11.0.011.0.1
12.0.012.0.112.0.212.0.312.1.0
13.0.013.1.013.2.013.2.1
14.0.014.1.014.1.114.1.2
15.0.015.0.1
16.0.016.0.116.0.216.0.316.1.0
17.0.017.0.1
18.0.018.0.118.1.0
19.0.019.0.1