Čitatelia ako vy pomáhajú podporovať MUO. Keď uskutočníte nákup pomocou odkazov na našej stránke, môžeme získať pridruženú províziu.

Súbeh nastane, keď sa dve operácie musia uskutočniť v určitom poradí, ale môžu sa spustiť v opačnom poradí.

Napríklad vo viacvláknovej aplikácii môžu dve samostatné vlákna pristupovať k spoločnej premennej. Výsledkom je, že ak jedno vlákno zmení hodnotu premennej, druhé môže stále používať staršiu verziu, pričom bude ignorovať najnovšiu hodnotu. To spôsobí nežiaduce výsledky.

Pre lepšie pochopenie tohto modelu by bolo dobré podrobne preskúmať proces prepínania procesov procesora.

Ako procesor prepína procesy

Moderné operačné systémy môže súčasne spustiť viac ako jeden proces, nazývaný multitasking. Keď sa na tento proces pozriete z hľadiska cyklus vykonávania CPU, možno zistíte, že multitasking v skutočnosti neexistuje.

Namiesto toho procesory neustále prepínajú medzi procesmi, aby ich spúšťali súčasne alebo sa aspoň správali tak, ako keby to robili. CPU môže prerušiť proces pred jeho dokončením a pokračovať v inom procese. Riadenie týchto procesov riadi operačný systém.

instagram viewer

Napríklad algoritmus Round Robin, jeden z najjednoduchších prepínacích algoritmov, funguje takto:

Vo všeobecnosti tento algoritmus umožňuje, aby každý proces bežal veľmi krátky čas, ako určí operačný systém. Môže to byť napríklad obdobie dvoch mikrosekúnd.

CPU prevezme každý proces postupne a vykoná príkazy, ktoré budú prebiehať dve mikrosekundy. Potom pokračuje ďalším procesom bez ohľadu na to, či ten aktuálny skončil alebo nie. Z pohľadu koncového používateľa sa teda zdá, že súčasne beží viac ako jeden proces. Keď sa však pozriete do zákulisia, CPU stále robí veci v poriadku.

Mimochodom, ako ukazuje vyššie uvedený diagram, algoritmu Round Robin chýba akákoľvek optimalizácia alebo priorita spracovania. V dôsledku toho ide o pomerne rudimentárnu metódu, ktorá sa v reálnych systémoch používa len zriedka.

Teraz, aby ste to všetko lepšie pochopili, predstavte si, že bežia dve vlákna. Ak vlákna pristupujú k spoločnej premennej, môže dôjsť k sporu.

Príklad webovej aplikácie a podmienky preteku

Pozrite si jednoduchú aplikáciu Flask nižšie a zamyslite sa nad konkrétnym príkladom všetkého, čo ste doteraz čítali. Účelom tejto aplikácie je spravovať peňažné transakcie, ktoré budú prebiehať na webe. Uložte nasledujúce do súboru s názvom peniaze.py:

od banke importovať Banka
od flask.ext.sqlalchemy importovať SQLAlchemy

app = Banka (__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy (aplikácia)

triedaúčtu(db. Model):
id = db. Stĺpec (db. Celé číslo, primárny_kľúč = Pravda)
množstvo = db. Stĺpec (db. String(80), jedinečný = Pravda)

def__init__(ja, počítať):
seba.suma = suma

def__repr__(ja):
vrátiť '' % seba.suma

@app.route("/")
defAhoj():
účet = Account.query.get(1) # Peňaženka je len jedna.
vrátiť "Celkové peniaze = {}".formát (účet.suma)

@app.route("/odoslať/")
defposlať(suma):
účet = Account.query.get(1)

ak int (účet.suma) < suma:
vrátiť „Nedostatočná rovnováha. Resetovať peniaze s /reset!)"

uct.suma = int (uct.suma) - suma
db.session.commit()
vrátiť "Odoslaná suma = {}".formát (suma)

@app.route("/reset")
defresetovať():
účet = Account.query.get(1)
účet.suma = 5000
db.session.commit()
vrátiť "Resetovanie peňazí."

ak __name__ == "__main__":
app.secret_key = 'helloTHisIsSeCReTKey!'
app.run()

Ak chcete spustiť tento kód, budete musieť vytvoriť záznam v tabuľke účtov a pokračovať v transakciách nad týmto záznamom. Ako vidíte v kóde, toto je testovacie prostredie, takže robí transakcie proti prvému záznamu v tabuľke.

od peniaze importovať db
db.create_all()
od peniaze importovať účtu
účet = účet (5000)
db.relácia.pridať(účtu)
db.relácia.zaviazať sa()

Teraz ste si vytvorili účet so zostatkom 5 000 USD. Nakoniec spustite vyššie uvedený zdrojový kód pomocou nasledujúceho príkazu za predpokladu, že máte nainštalované balíky Flask a Flask-SQLAlchemy:

pytónpeniaze.py

Takže máte webovú aplikáciu Flask, ktorá robí jednoduchý proces extrakcie. Táto aplikácia môže vykonávať nasledujúce operácie s odkazmi na požiadavku GET. Keďže Flask štandardne beží na porte 5000, adresa, na ktorej k nemu pristupujete, je 127.0.0.1:5000/. Aplikácia poskytuje nasledujúce koncové body:

  • 127.0.0.1:5000/ zobrazuje aktuálny zostatok.
  • 127.0.0.1:5000/odoslať/{suma} odpočíta sumu z účtu.
  • 127.0.0.1:5000/reset resetuje účet na 5 000 USD.

Teraz, v tejto fáze, môžete preskúmať, ako sa vyskytuje zraniteľnosť rasovej podmienky.

Pravdepodobnosť zraniteľnosti rasových podmienok

Vyššie uvedená webová aplikácia obsahuje možnú zraniteľnosť typu race condition.

Predstavte si, že máte 5 000 USD na začiatok a vytvorte dve rôzne požiadavky HTTP, ktoré pošlú 1 USD. Na tento účel môžete na odkaz poslať dve rôzne požiadavky HTTP 127.0.0.1:5000/odoslať/1. Predpokladajme, že čo najskôr webový server spracuje prvú požiadavku, CPU tento proces zastaví a spracuje druhú požiadavku. Prvý proces sa môže napríklad zastaviť po spustení nasledujúceho riadku kódu:

účet.suma = int(účet.suma) - suma

Tento kód vypočítal nový súčet, ale záznam ešte neuložil do databázy. Keď začne druhá požiadavka, vykoná rovnaký výpočet, odčíta 1 $ od hodnoty v databáze – 5 000 $ – a uloží výsledok. Keď sa prvý proces obnoví, uloží svoju vlastnú hodnotu – 4 999 USD – ktorá nebude odrážať najnovší zostatok na účte.

Takže boli dokončené dve žiadosti a každá by mala odpočítať 1 USD od zostatku účtu, čo viedlo k novému zostatku 4 998 USD. Ale v závislosti od poradia, v ktorom ich webový server spracuje, konečný zostatok na účte môže byť 4 999 USD.

Predstavte si, že odošlete 128 požiadaviek na uskutočnenie prevodu 1 USD do cieľového systému v časovom rámci piatich sekúnd. V dôsledku tejto transakcie bude očakávaný výpis z účtu 5 000 USD – 128 USD = 4 875 USD. Avšak vzhľadom na podmienky pretekov sa konečný zostatok môže líšiť od 4 875 do 4 999 USD.

Programátori sú jedným z najdôležitejších komponentov bezpečnosti

V softvérovom projekte máte ako programátor pomerne veľa povinností. Vyššie uvedený príklad bol pre jednoduchú aplikáciu na prevod peňazí. Predstavte si, že pracujete na softvérovom projekte, ktorý spravuje bankový účet alebo backend veľkého e-shopu.

Musíte byť oboznámení s takýmito zraniteľnosťami, aby program, ktorý ste napísali na ich ochranu, neobsahoval zraniteľné miesta. Vyžaduje si to veľkú zodpovednosť.

Zraniteľnosť rasovej podmienky je len jednou z nich. Bez ohľadu na to, akú technológiu používate, musíte si dávať pozor na zraniteľnosti v kóde, ktorý píšete. Jednou z najdôležitejších zručností, ktoré môžete ako programátor získať, je znalosť softvérovej bezpečnosti.