{"id":78514,"date":"2020-04-20T01:42:32","date_gmt":"2020-04-19T23:42:32","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/kak-zashhishhat-proczessy-i-rasshireniya-yadra-v-macos"},"modified":"2020-04-20T01:42:32","modified_gmt":"2020-04-19T23:42:32","slug":"kak-zashhishhat-proczessy-i-rasshireniya-yadra-v-macos","status":"publish","type":"post","link":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/kak-zashhishhat-proczessy-i-rasshireniya-yadra-v-macos","title":{"rendered":"Jak chr\u00e1nit procesy a roz\u0161\u00ed\u0159en\u00ed j\u00e1dra v macOS","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Ahoj, Habr! Dnes bych cht\u011bl mluvit o tom, jak chr\u00e1nit procesy p\u0159ed \u00fatoky \u00fato\u010dn\u00edk\u016f v macOS. Nap\u0159\u00edklad to je u\u017eite\u010dn\u00e9 pro antivirus nebo z\u00e1lohovac\u00ed syst\u00e9m, zvl\u00e1\u0161t\u011b vzhledem k tomu, \u017ee v macOS existuje hned n\u011bkolik zp\u016fsob\u016f, jak \"zab\u00edt\" proces. O tom a metod\u00e1ch ochrany si p\u0159e\u010dt\u011bte n\u00ed\u017ee.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/acronis\/blog\/497714\/\"><img decoding=\"async\" alt=\"Jak chr\u00e1nit procesy a roz\u0161\u00ed\u0159en\u00ed j\u00e1dra v macOS\" src=\"\/wp-content\/uploads\/2020\/04\/621276e5dd7c90dd48c34c94f3b37cf2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>Klasick\u00fd zp\u016fsob \"zabit\u00ed\" procesu<\/h3>\n<p>\nV\u0161em zn\u00e1m\u00fd zp\u016fsob \"zab\u00edt\" proces \u2013 poslat sign\u00e1l SIGKILL procesu. P\u0159es bash m\u016f\u017eete zavolat standardn\u00ed \"kill -SIGKILL PID\" nebo \"pkill -9 NAME\" pro jeho zabit\u00ed. P\u0159\u00edkaz \"kill\" je zn\u00e1m\u00fd u\u017e od dob UNIXu a je dostupn\u00fd nejen v macOS, ale i na dal\u0161\u00edch unixov\u00fdch syst\u00e9mech.<\/p>\n<p>Stejn\u011b jako v unixov\u00fdch syst\u00e9mech, macOS umo\u017e\u0148uje zachytit jak\u00e9koliv sign\u00e1ly pro proces krom\u011b dvou \u2013 SIGKILL a SIGSTOP. V tomto \u010dl\u00e1nku se p\u0159edev\u0161\u00edm budeme zab\u00fdvat sign\u00e1lem SIGKILL jako sign\u00e1lem, kter\u00fd zp\u016fsobuje zabit\u00ed procesu.<\/p>\n<h3>Specifika macOS<br \/>\n<\/h3>\n<p>\nV macOS syst\u00e9mov\u00fd hovor kill v j\u00e1dru XNU vyvol\u00e1v\u00e1 funkci psignal(SIGKILL,&#8230;). Poj\u010fme se pod\u00edvat, jak\u00e9 dal\u0161\u00ed akce u\u017eivatele v userspace mohou vyvolat funkci psignal. Odstran\u00edme vol\u00e1n\u00ed funkce psignal v intern\u00edch mechanismech j\u00e1dra (i kdy\u017e mohou b\u00fdt komplikovan\u00e9, ale nech\u00e1me je na jin\u00fd \u010dl\u00e1nek \ud83d\ude42 \u2014 kontrola podpisu, chyby pam\u011bti, zpracov\u00e1n\u00ed exit\/terminate, poru\u0161en\u00ed ochrany soubor\u016f atd. <\/p>\n<p>Za\u010dn\u011bme p\u0159ehled funkc\u00ed a p\u0159\u00edslu\u0161n\u00e9ho syst\u00e9mov\u00e9ho vol\u00e1n\u00ed <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/apple\/darwin-xnu\/blob\/a449c6a3b8014d9406c2ddbdc81795da24aa7443\/bsd\/kern\/kern_sig.c#L1672\">terminate_with_payload<\/a><\/noindex>. Je z\u0159ejm\u00e9, \u017ee krom\u011b klasick\u00e9ho vol\u00e1n\u00ed kill existuje alternativn\u00ed p\u0159\u00edstup, kter\u00fd je specifick\u00fd pro opera\u010dn\u00ed syst\u00e9m macOS a nenajdete ho v BSD. Principy fungov\u00e1n\u00ed obou syst\u00e9mov\u00fdch vol\u00e1n\u00ed jsou tak\u00e9 podobn\u00e9. P\u0159edstavuj\u00ed p\u0159\u00edm\u00e9 vol\u00e1n\u00ed funkce j\u00e1dra psignal. Tak\u00e9 si pov\u0161imn\u011bme, \u017ee p\u0159ed zabit\u00edm procesu prob\u00edh\u00e1 kontrola \"cansignal\" \u2013 zda m\u016f\u017ee proces poslat sign\u00e1l jin\u00e9mu procesu, syst\u00e9m neumo\u017e\u0148uje \u017e\u00e1dn\u00e9 aplikaci zab\u00edjet syst\u00e9mov\u00e9 procesy.<\/p>\n<pre><code class=\"cpp\">static int\nterminate_with_payload_internal(struct proc *cur_proc, int target_pid, uint32_t reason_namespace,\n\t\t\t\tuint64_t reason_code, user_addr_t payload, uint32_t payload_size,\n\t\t\t\tuser_addr_t reason_string, uint64_t reason_flags)\n{\n...\n\ttarget_proc = proc_find(target_pid);\n...\n\tif (!cansignal(cur_proc, cur_cred, target_proc, SIGKILL)) {\n\t\tproc_rele(target_proc);\n\t\treturn EPERM;\n\t}\n...\n\tif (target_pid == cur_proc-&gt;p_pid) {\n\t\t\tdo {\n\t\t\t * psignal_thread_with_reason() will pend a SIGKILL on the specified thread or\n\t\t\t * return if the thread and\/or task are already terminating. Either way, the\n\t\t\t * current thread won't return to userspace.\n\t\t\t *\n\t\t\tpsignal_thread_with_reason(target_proc, current_thread(), SIGKILL, signal_reason);\n\t\t} else {\n\t\t\tpsignal_with_reason(target_proc, SIGKILL, signal_reason);\n\t\t}\n...\n}\n<\/code><\/pre>\n<p><\/p>\n<h3>launchd<\/h3>\n<p>\nStandardn\u00ed zp\u016fsob, jak vytv\u00e1\u0159et d\u00e9mony p\u0159i spu\u0161t\u011bn\u00ed syst\u00e9mu a \u0159\u00eddit jejich \u017eivotnost, je launchd. R\u00e1d bych zd\u016fraznil, \u017ee zdrojov\u00e9 k\u00f3dy uveden\u00e9 pro starou verzi launchctl p\u0159ed macOS 10.10 a p\u0159\u00edklady k\u00f3du byly uvedeny jako ilustrace. Modern\u00ed launchctl pos\u00edl\u00e1 sign\u00e1ly launchd prost\u0159ednictv\u00edm XPC, logika launchctl byla p\u0159esunuta do n\u011bho.<\/p>\n<p>Pod\u00edv\u00e1me se, jak se vlastn\u011b prov\u00e1d\u00ed zastaven\u00ed aplikac\u00ed. P\u0159ed odesl\u00e1n\u00edm sign\u00e1lu SIGTERM se aplikace sna\u017e\u00ed zastavit pomoc\u00ed syst\u00e9mov\u00e9ho vol\u00e1n\u00ed \u201cproc_terminate\u201d.<\/p>\n<pre><code class=\"cpp\">...\n\terror = proc_terminate(j-&gt;p, &amp;sig);\n\tif (error) {\n\t\tjob_log(j, LOG_ERR | LOG_CONSOLE, \"Could not terminate job: %d: %s\", error, strerror(error));\n\t\tjob_log(j, LOG_NOTICE | LOG_CONSOLE, \"Using fallback option to terminate job...\");\n\t\terror = kill2(j-&gt;p, SIGTERM);\n\t\tif (error) {\n\t\t\tjob_log(j, LOG_ERR, \"Could not signal job: %d: %s\", error, strerror(error));\n\t\t} \n...\n<\/code><\/pre>\n<p>\nPod kapotou proc_terminate, navzdory sv\u00e9mu n\u00e1zvu, m\u016f\u017ee odes\u00edlat nejen psignal s SIGTERM, ale tak\u00e9 SIGKILL.<\/p>\n<h3>Nep\u0159\u00edm\u00e9 zabit\u00ed \u2014 omezen\u00ed zdroj\u016f<\/h3>\n<p>\nZaj\u00edmav\u011bj\u0161\u00ed p\u0159\u00edpad lze vid\u011bt v jin\u00e9m syst\u00e9mov\u00e9m vol\u00e1n\u00ed <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/apple\/darwin-xnu\/blob\/a449c6a3b8014d9406c2ddbdc81795da24aa7443\/bsd\/kern\/process_policy.c#L652\">process_policy<\/a><\/noindex>. Standardn\u00ed pou\u017eit\u00ed tohoto syst\u00e9mov\u00e9ho vol\u00e1n\u00ed \u2014 omezen\u00ed zdroj\u016f aplikac\u00ed, nap\u0159\u00edklad pro indexer omezen\u00ed na kv\u00f3tu procesorov\u00e9ho \u010dasu a pam\u011bti, aby se syst\u00e9m nezd\u016fraznil z akc\u00ed ke\u0161ov\u00e1n\u00ed souboru. Pokud aplikace dos\u00e1hla omezen\u00ed zdroj\u016f, jak lze vid\u011bt z funkce proc_apply_resource_actions, je procesu odesl\u00e1n sign\u00e1l SIGKILL.<\/p>\n<p>Navzdory tomu, \u017ee toto syst\u00e9mov\u00e9 vol\u00e1n\u00ed m\u016f\u017ee potenci\u00e1ln\u011b prov\u00e1d\u011bt zabit\u00ed procesu, syst\u00e9m adekv\u00e1tn\u011b nekontroloval pr\u00e1va procesu, kter\u00fd syst\u00e9mov\u00e9 vol\u00e1n\u00ed vyvolal. Ve skute\u010dnosti kontrola <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/apple\/darwin-xnu\/blob\/a449c6a3b8014d9406c2ddbdc81795da24aa7443\/bsd\/kern\/process_policy.c#L267\">existovala<\/a><\/noindex>, ale sta\u010d\u00ed pou\u017e\u00edt alternativn\u00ed p\u0159\u00edznak PROC_POLICY_ACTION_SET k obchodu tohoto podm\u00ednku.<\/p>\n<p>Pokud \"omez\u00edte\" kv\u00f3tu vyu\u017e\u00edv\u00e1n\u00ed CPU aplikac\u00ed (nap\u0159\u00edklad povol\u00edte spu\u0161t\u011bn\u00ed pouze 1 ns), m\u016f\u017eete zab\u00edt jak\u00fdkoli proces v syst\u00e9mu. Tak m\u016f\u017ee malware zab\u00edt jak\u00fdkoli proces v syst\u00e9mu, v\u010detn\u011b procesu antiviru. Zaj\u00edmav\u00fd je tak\u00e9 efekt, kter\u00fd nast\u00e1v\u00e1 p\u0159i zab\u00edjen\u00ed procesu s pid 1 (launchctl) \u2014 kernel panic p\u0159i pokusu o zpracov\u00e1n\u00ed sign\u00e1lu SIGKILL \ud83d\ude42<\/p>\n<p><img decoding=\"async\" alt=\"Jak chr\u00e1nit procesy a roz\u0161\u00ed\u0159en\u00ed j\u00e1dra v macOS\" src=\"\/wp-content\/uploads\/2020\/04\/46adadb9b3f28b78f0b9df410e601bb9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Jak vy\u0159e\u0161it probl\u00e9m?<\/h3>\n<p>\nNejjednodu\u0161\u0161\u00ed zp\u016fsob, jak zak\u00e1zat zab\u00edjen\u00ed procesu, je nahradit ukazatel na funkci v tabulce syst\u00e9mov\u00fdch vol\u00e1n\u00ed. Bohu\u017eel, tento zp\u016fsob je z mnoha d\u016fvod\u016f netrivi\u00e1ln\u00ed.<\/p>\n<p>Za prv\u00e9, symbol, kter\u00fd odpov\u00edd\u00e1 za um\u00edst\u011bn\u00ed sysent v pam\u011bti, je nejen priv\u00e1tn\u00edm symbolem j\u00e1dra XNU, ale nelze jej naj\u00edt ani mezi symboly j\u00e1dra. Bude nutn\u00e9 pou\u017e\u00edt heuristick\u00e9 metody vyhled\u00e1v\u00e1n\u00ed, nap\u0159\u00edklad dynamickou disassemblaci funkce a hled\u00e1n\u00ed ukazatele v n\u00ed.<\/p>\n<p>Za druh\u00e9, struktura z\u00e1znam\u016f v tabulce z\u00e1vis\u00ed na flagech, se kter\u00fdmi bylo j\u00e1dro sestaveno. Pokud je vyhl\u00e1\u0161en flag CONFIG_REQUIRES_U32_MUNGING, velikost struktury se zm\u011bn\u00ed \u2014 p\u0159id\u00e1 se dal\u0161\u00ed pole. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/apple\/darwin-xnu\/blob\/a449c6a3b8014d9406c2ddbdc81795da24aa7443\/bsd\/sys\/sysent.h#L45\">sy_arg_munge32<\/a><\/noindex>. Je nutn\u00e9 prov\u00e9st dal\u0161\u00ed kontrolu na to, s jak\u00fdm flagem bylo j\u00e1dro zkompilov\u00e1no, nap\u0159\u00edklad porovnat ukazatele funkc\u00ed se zn\u00e1m\u00fdmi.<\/p>\n<pre><code class=\"cpp\">struct sysent {         \n        \/* tabulka syst\u00e9mov\u00fdch vol\u00e1n\u00ed *\/\n        sy_call_t       *sy_call;       \/* implementuj\u00edc\u00ed funkce *\/\n#if CONFIG_REQUIRES_U32_MUNGING || (__arm__ &amp;&amp; (__BIGGEST_ALIGNMENT__ &gt; 4))\n        sy_munge_t      *sy_arg_munge32; \/* munger argument\u016f syst\u00e9mov\u00e9ho vol\u00e1n\u00ed pro 32-bitov\u00e9 procesy *\/\n#endif\n        int32_t         sy_return_type; \/* typy n\u00e1vrat\u016f syst\u00e9mov\u00fdch vol\u00e1n\u00ed *\/\n        int16_t         sy_narg;        \/* po\u010det argument\u016f *\/\n        uint16_t        sy_arg_bytes;   \/* Celkov\u00e1 velikost argument\u016f v bajtech pro\n                                         * 32-bitov\u00e1 syst\u00e9mov\u00e1 vol\u00e1n\u00ed\n                                         *\/\n};\n<\/code><\/pre>\n<p>\nNa\u0161t\u011bst\u00ed, v modern\u00edch verz\u00edch macOS Apple poskytuje nov\u00e9 API pro pr\u00e1ci s procesy. Endpoint Security API umo\u017e\u0148uje klient\u016fm autorizovat mnoho po\u017eadavk\u016f k jin\u00fdm proces\u016fm. Lze tak blokovat jak\u00e9koli sign\u00e1ly k proces\u016fm, v\u010detn\u011b sign\u00e1lu SIGKILL pomoc\u00ed v\u00fd\u0161e zm\u00edn\u011bn\u00e9ho API.<\/p>\n<pre><code class=\"cpp\">#include &lt;bsm\/libbsm.h&gt;\n#include &lt;EndpointSecurity\/EndpointSecurity.h&gt;\n#include &lt;unistd.h&gt;\n\nint main(int argc, const char * argv[]) {\n    es_client_t* cli = nullptr;\n    {\n        auto res = es_new_client(&amp;cli, ^(es_client_t * client, const es_message_t * message) {\n            switch (message-&gt;event_type) {\n                case ES_EVENT_TYPE_AUTH_SIGNAL:\n                {\n                    auto&amp; msg = message-&gt;event.signal;\n                    auto target = msg.target;\n                    auto&amp; token = target-&gt;audit_token;\n                    auto pid = audit_token_to_pid(token);\n                    printf(&quot;signal '%d' sent to pid '%d'n&quot;, msg.sig, pid);\n                    es_respond_auth_result(client, message, pid == getpid() ? ES_AUTH_RESULT_DENY : ES_AUTH_RESULT_ALLOW, false);\n                }\n                    break;\n                default:\n                    break;\n            }\n        });\n    }\n\n    {\n        es_event_type_t evs[] = { ES_EVENT_TYPE_AUTH_SIGNAL };\n        es_subscribe(cli, evs, sizeof(evs) \/ sizeof(*evs));\n    }\n\n    printf(&quot;%dn&quot;, getpid());\n    sleep(60); \/\/ could be replaced with other waiting primitive\n\n    es_unsubscribe_all(cli);\n    es_delete_client(cli);\n\n    return 0;\n}\n<\/code><\/pre>\n<p>\nPodobn\u011b lze v j\u00e1dru zaregistrovat MAC Policy, kter\u00e1 poskytuje metodu ochrany p\u0159ed sign\u00e1ly (policy proc_check_signal), nicm\u00e9n\u011b API nen\u00ed ofici\u00e1ln\u011b podporov\u00e1no.<\/p>\n<h3>Ochrana roz\u0161\u00ed\u0159en\u00ed j\u00e1dra<\/h3>\n<p>\nKrom\u011b ochrany proces\u016f v syst\u00e9mu je tak\u00e9 nezbytn\u00e1 ochrana samotn\u00e9ho j\u00e1dra (kext). macOS poskytuje pro v\u00fdvoj\u00e1\u0159e r\u00e1mec pro pohodln\u00fd v\u00fdvoj ovlada\u010d\u016f za\u0159\u00edzen\u00ed IOKit. Krom\u011b poskytov\u00e1n\u00ed prost\u0159edk\u016f pro pr\u00e1ci se za\u0159\u00edzen\u00edmi IOKit zaji\u0161\u0165uje tak\u00e9 metody pro stohov\u00e1n\u00ed ovlada\u010d\u016f (driver stacking) pomoc\u00ed instanc\u00ed t\u0159\u00edd C++. Aplikace v u\u017eivatelsk\u00e9m prostoru m\u016f\u017ee \u201enaj\u00edt\u201c registrovanou instanci t\u0159\u00eddy pro nav\u00e1z\u00e1n\u00ed vztahu mezi j\u00e1drem a u\u017eivatelsk\u00fdm prostorem.<\/p>\n<p>Pro zji\u0161t\u011bn\u00ed po\u010dtu instanc\u00ed t\u0159\u00edd v syst\u00e9mu existuje utilita ioclasscount.<\/p>\n<pre><code class=\"cpp\">my_kext_ioservice = 1\nmy_kext_iouserclient = 1\n<\/code><\/pre>\n<p>\nJak\u00e9koli roz\u0161\u00ed\u0159en\u00ed j\u00e1dra, kter\u00e9 si p\u0159eje registrovat se ve stohu ovlada\u010d\u016f, mus\u00ed deklarovat t\u0159\u00eddu odvozenou od IOService, nap\u0159\u00edklad my_kext_ioservice v tomto p\u0159\u00edpad\u011b. P\u0159ipojen\u00ed u\u017eivatelsk\u00fdch aplikac\u00ed vyvol\u00e1v\u00e1 vytvo\u0159en\u00ed nov\u00e9 instance t\u0159\u00eddy, kter\u00e1 je odvozena od IOUserClient, v p\u0159\u00edkladu my_kext_iouserclient.<\/p>\n<p>P\u0159i pokusu o odpojen\u00ed ovlada\u010de ze syst\u00e9mu (p\u0159\u00edkaz kextunload) se vyvol\u00e1 virtu\u00e1ln\u00ed funkce \u201cbool terminate(IOOptionBits options)\u201d. Sta\u010d\u00ed vr\u00e1tit false p\u0159i vol\u00e1n\u00ed funkce terminate p\u0159i pokusu o odpojen\u00ed, aby se zak\u00e1zal kextunload.<\/p>\n<pre><code class=\"cpp\">bool Kext::terminate(IOOptionBits options)\n{\n\n  if (!IsUnloadAllowed)\n  {\n    \/\/ Odpojen\u00ed nen\u00ed povoleno, vrac\u00ed false\n    return false;\n  }\n\n  return super::terminate(options);\n}\n\n<\/code><\/pre>\n<p>\nP\u0159\u00edznak IsUnloadAllowed m\u016f\u017ee b\u00fdt nastaven IOUserClient p\u0159i na\u010d\u00edt\u00e1n\u00ed. P\u0159i omezen\u00ed na na\u010d\u00edt\u00e1n\u00ed vr\u00e1t\u00ed p\u0159\u00edkaz kextunload n\u00e1sleduj\u00edc\u00ed v\u00fdstup:<\/p>\n<pre><code class=\"cpp\">admin@admins-Mac drivermanager % sudo kextunload .\\\/test.kext\nHeslo:\n(kernel) Nelze odstranit kext my.kext.test; slu\u017eby se nepoda\u0159ilo ukon\u010dit - 0xe00002c7.\nNepoda\u0159ilo se odpojit my.kext.test - (iokit\/common) nepodporovan\u00e1 funkce.\n<\/code><\/pre>\n<p>\nPodobnou ochranu je nutn\u00e9 prov\u00e9st tak\u00e9 pro IOUserClient. Instance t\u0159\u00edd lze odpojit pomoc\u00ed u\u017eivatelsk\u00e9 funkce IOKitLib \u201cIOCatalogueTerminate(mach_port_t, uint32_t flag, io_name_t description);\u201d. M\u016f\u017ee se vracet false p\u0159i vol\u00e1n\u00ed p\u0159\u00edkazu \u201cterminate\u201d, dokud u\u017eivatelsk\u00e1 aplikace \u201eneum\u0159e\u201c, tedy dokud nebude vyvol\u00e1na funkce \u201cclientDied\u201d.<\/p>\n<h3>Ochrana soubor\u016f<\/h3>\n<p>\nPro ochranu soubor\u016f sta\u010d\u00ed vyu\u017e\u00edt Kauth API, kter\u00e9 umo\u017e\u0148uje omezit p\u0159\u00edstup k soubor\u016fm. Apple poskytuje v\u00fdvoj\u00e1\u0159\u016fm upozorn\u011bn\u00ed na r\u016fzn\u00e9 ud\u00e1losti v rozsahu, a pro n\u00e1s jsou d\u016fle\u017eit\u00e9 operace KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA a KAUTH_VNODE_DELETE_CHILD. Omezit p\u0159\u00edstup k soubor\u016fm je nejjednodu\u0161\u0161\u00ed podle cesty \u2014 pou\u017eijeme API \u201evn_getpath\u201c pro z\u00edsk\u00e1n\u00ed cesty k souboru a provedeme porovn\u00e1n\u00ed prefixu cesty. Upozor\u0148ujeme, \u017ee pro optimalizaci p\u0159ejmenov\u00e1n\u00ed cest slo\u017eek se syst\u00e9m neautorizuje p\u0159\u00edstup k ka\u017ed\u00e9mu souboru, ale pouze k samotn\u00e9 slo\u017ece, kterou jsme p\u0159ejmenovali. Je nutn\u00e9 prov\u00e9st porovn\u00e1n\u00ed rodi\u010dovsk\u00e9 cesty a omezit KAUTH_VNODE_DELETE pro ni.<\/p>\n<p><img decoding=\"async\" alt=\"Jak chr\u00e1nit procesy a roz\u0161\u00ed\u0159en\u00ed j\u00e1dra v macOS\" src=\"\/wp-content\/uploads\/2020\/04\/409cf53d1cdbeee6a6f56f5c90574bf6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNev\u00fdhodou tohoto p\u0159\u00edstupu m\u016f\u017ee b\u00fdt n\u00edzk\u00fd v\u00fdkon p\u0159i zvy\u0161ov\u00e1n\u00ed po\u010dtu prefix\u016f. Aby porovn\u00e1n\u00ed nebylo rovno O(prefix*length), kde prefix je po\u010det prefix\u016f a length je d\u00e9lka \u0159et\u011bzce, lze pou\u017e\u00edt deterministick\u00fd kone\u010dn\u00fd automat (DKA) postaven\u00fd na prefixech. <\/p>\n<p>Zva\u017eme zp\u016fsob konstrukce DKA pro danou mno\u017einu prefix\u016f. Inicializujeme kurzory na za\u010d\u00e1tek ka\u017ed\u00e9ho prefixu. Pokud v\u0161echny kurzory ukazuj\u00ed na stejn\u00fd znak, zv\u00fd\u0161\u00edme ka\u017ed\u00fd kurzor o jeden znak a zapamatujeme si, \u017ee d\u00e9lka shodn\u00e9 \u0159et\u011bzce je v\u011bt\u0161\u00ed o jednotku. Pokud existuj\u00ed dva kurzory, pod kter\u00fdmi jsou r\u016fzn\u00e9 znaky, rozd\u011bl\u00edme kurzory do skupin podle znaku, na kter\u00fd ukazuj\u00ed, a opakujeme algoritmus pro ka\u017edou skupinu.<\/p>\n<p>V prvn\u00edm p\u0159\u00edpad\u011b (v\u0161echny znaky pod kurzory jsou shodn\u00e9) z\u00edsk\u00e1v\u00e1me stav DKA, kter\u00fd m\u00e1 pouze jeden p\u0159echod podle shodn\u00e9 \u0159et\u011bzce. Ve druh\u00e9m p\u0159\u00edpad\u011b z\u00edsk\u00e1v\u00e1me tabulku p\u0159echod\u016f velikosti 256 (po\u010det znak\u016f a maxim\u00e1ln\u00ed po\u010det skupin) do n\u00e1sleduj\u00edc\u00edch stav\u016f, kter\u00e9 byly z\u00edsk\u00e1ny p\u0159i rekurzivn\u00edm vol\u00e1n\u00ed funkce.<\/p>\n<p>Uva\u017eujme p\u0159\u00edklad. Pro sadu prefix\u016f (\u201c\/foo\/bar\/tmp\/\u201d, \u201c\/var\/db\/foo\/\u201d, \u201c\/foo\/bar\/aba\/\u201d, \u201cfoo\/bar\/aac\/\u201d) lze z\u00edskat n\u00e1sleduj\u00edc\u00ed DKA. Na obr\u00e1zku jsou uvedeny pouze p\u0159echody vedouc\u00ed do jin\u00fdch stav\u016f, ostatn\u00ed p\u0159echody nebudou kone\u010dn\u00fdmi.<\/p>\n<p><img decoding=\"async\" alt=\"Jak chr\u00e1nit procesy a roz\u0161\u00ed\u0159en\u00ed j\u00e1dra v macOS\" src=\"\/wp-content\/uploads\/2020\/04\/6f5c4734ee6c677749f2f7b55307549d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nP\u0159i proch\u00e1zen\u00ed stavy DKA m\u016f\u017ee nastat 3 p\u0159\u00edpady.<\/p>\n<ol>\n<li>Bylo dosa\u017eeno kone\u010dn\u00e9ho stavu \u2014 cesta je chr\u00e1n\u011bn\u00e1, omezujeme operace KAUTH_VNODE_DELETE, KAUTH_VNODE_WRITE_DATA a KAUTH_VNODE_DELETE_CHILD.<\/li>\n<li>Fin\u00e1ln\u00ed stav nebyl dosa\u017een, ale cesta \"skon\u010dila\" (byl dosa\u017een nulov\u00fd termin\u00e1tor) \u2014 cesta je rodi\u010dovsk\u00e1, je nutn\u00e9 omezit KAUTH_VNODE_DELETE. V\u0161imn\u011bte si, \u017ee pokud je vnode slo\u017eka, je t\u0159eba p\u0159idat na konec \"\/\", jinak m\u016f\u017ee b\u00fdt omezen\u00ed aplikov\u00e1no na soubor \"\/foor\/bar\/t\", co\u017e je nespr\u00e1vn\u00e9.<\/li>\n<li>Fin\u00e1ln\u00ed stav nebyl dosa\u017een, cesta neskon\u010dila. \u017d\u00e1dn\u00fd z prefix\u016f neodpov\u00edd\u00e1 dan\u00e9mu, omezov\u00e1n\u00ed nenastavujeme.<\/li>\n<\/ol>\n<p><\/p>\n<h3>Z\u00e1v\u011br<\/h3>\n<p>\nC\u00edlem vyv\u00edjen\u00fdch bezpe\u010dnostn\u00edch \u0159e\u0161en\u00ed je zv\u00fd\u0161en\u00ed \u00farovn\u011b bezpe\u010dnosti u\u017eivatele a jeho dat. Na jedn\u00e9 stran\u011b je tohoto c\u00edle dosa\u017eeno v\u00fdvojem produktu Acronis, kter\u00fd uzav\u00edr\u00e1 ty zranitelnosti, kde je \"slab\u00e1\" samotn\u00e1 operan\u00ed syst\u00e9m. Na druh\u00e9 stran\u011b by nem\u011bly b\u00fdt opom\u00edjeny ani aspekty zabezpe\u010den\u00ed, kter\u00e9 lze vylep\u0161it na stran\u011b OS, zvl\u00e1\u0161\u0165 kdy\u017e uzav\u0159en\u00ed takov\u00fdch zranitelnost\u00ed zvy\u0161uje na\u0161i vlastn\u00ed odolnost jako produktu. Zranitelnost byla nahl\u00e1\u0161ena Apple Product Security Team a byla opravena v macOS 10.14.5 (https:\/\/support.apple.com\/en-gb\/HT210119).<\/p>\n<p><img decoding=\"async\" alt=\"Jak chr\u00e1nit procesy a roz\u0161\u00ed\u0159en\u00ed j\u00e1dra v macOS\" src=\"\/wp-content\/uploads\/2020\/04\/98cd51cb47a81e8262a87bc792d59455.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nTo v\u0161e je mo\u017en\u00e9 prov\u00e9st pouze v p\u0159\u00edpad\u011b, \u017ee va\u0161e utilita byla ofici\u00e1ln\u011b nainstalov\u00e1na do j\u00e1dra. To znamen\u00e1, \u017ee pro extern\u00ed a ne\u017e\u00e1douc\u00ed software neexistuj\u00ed \u017e\u00e1dn\u00e9 skuliny. Nicm\u00e9n\u011b, jak vid\u00edte, i pro ochranu legitimn\u00edch program\u016f, jako jsou antiviry a z\u00e1lohovac\u00ed syst\u00e9my, je zapot\u0159eb\u00ed se sna\u017eit. Ale za to nyn\u00ed nov\u00e9 produkty Acronis pro macOS budou m\u00edt zv\u00fd\u0161enou ochranu proti vysazen\u00ed ze syst\u00e9mu.<br \/>\n<br \/>Zdroj: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/acronis\/blog\/497714\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0449\u0438\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u043e\u0442 \u043f\u043e\u0441\u044f\u0433\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432 \u0437\u043b\u043e\u0443\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u0438\u043a\u043e\u0432 \u0432 macOS. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u044d\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0434\u043b\u044f \u0430\u043d\u0442\u0438\u0432\u0438\u0440\u0443\u0441\u0430 \u0438\u043b\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u043e\u0433\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0432 \u0441\u0432\u0435\u0442\u0435 \u0442\u043e\u0433\u043e \u0447\u0442\u043e \u043f\u043e\u0434 macOS \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0441\u0440\u0430\u0437\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u201c\u0443\u0431\u0438\u0442\u044c\u201d \u043f\u0440\u043e\u0446\u0435\u0441\u0441. \u041e\u0431 \u044d\u0442\u043e\u043c \u0438 \u043e \u043c\u0435\u0442\u043e\u0434\u0430\u0445 \u0437\u0430\u0449\u0438\u0442\u044b \u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c. \u041a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u201c\u0443\u0431\u0438\u0442\u044c\u201d \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0412\u0441\u0435\u043c \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":78515,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-78514","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0449\u0438\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u043e\u0442 \u043f\u043e\u0441\u044f\u0433\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432 \u0437\u043b\u043e\u0443\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u0438\u043a\u043e\u0432 \u0432 macOS.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/kak-zashhishhat-proczessy-i-rasshireniya-yadra-v-macos\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"cs_CZ\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041a\u0430\u043a \u0437\u0430\u0449\u0438\u0449\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u044f\u0434\u0440\u0430 \u0432 macOS | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0449\u0438\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u043e\u0442 \u043f\u043e\u0441\u044f\u0433\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432 \u0437\u043b\u043e\u0443\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u0438\u043a\u043e\u0432 \u0432 macOS.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/kak-zashhishhat-proczessy-i-rasshireniya-yadra-v-macos\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-04-19T23:42:32+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-04-19T23:42:32+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Jak chr\u00e1nit procesy a roz\u0161\u00ed\u0159en\u00ed j\u00e1dra v macOS | ProHoster","description":"Ahoj, Habr! Dnes bych cht\u011bl hovo\u0159it o tom, jak chr\u00e1nit procesy p\u0159ed \u00fatoky \u00fato\u010dn\u00edk\u016f v macOS.","canonical_url":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/kak-zashhishhat-proczessy-i-rasshireniya-yadra-v-macos","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"cs_CZ","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041a\u0430\u043a \u0437\u0430\u0449\u0438\u0449\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u044f\u0434\u0440\u0430 \u0432 macOS | ProHoster","og:description":"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0449\u0438\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u043e\u0442 \u043f\u043e\u0441\u044f\u0433\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432 \u0437\u043b\u043e\u0443\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u0438\u043a\u043e\u0432 \u0432 macOS.","og:url":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/kak-zashhishhat-proczessy-i-rasshireniya-yadra-v-macos","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-04-19T23:42:32+00:00","article:modified_time":"2020-04-19T23:42:32+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"78514","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 16:56:36","updated":"2022-09-28 22:19:40","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/78514","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/comments?post=78514"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/78514\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media\/78515"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media?parent=78514"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/categories?post=78514"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/tags?post=78514"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}