Lesere som deg er med på å støtte MUO. Når du foretar et kjøp ved å bruke lenker på nettstedet vårt, kan vi tjene en tilknyttet provisjon.

En løpstilstand oppstår når to operasjoner må skje i en bestemt rekkefølge, men de kan kjøre i motsatt rekkefølge.

For eksempel, i en flertrådsapplikasjon kan to separate tråder få tilgang til en felles variabel. Som et resultat, hvis en tråd endrer verdien til variabelen, kan den andre fortsatt bruke den eldre versjonen, og ignorerer den nyeste verdien. Dette vil føre til uønskede resultater.

For bedre å forstå denne modellen, ville det være greit å undersøke prosessbytteprosessen til prosessoren nøye.

Hvordan en prosessor bytter prosesser

Moderne operativsystemer kan kjøre mer enn én prosess samtidig, kalt multitasking. Når du ser på denne prosessen i form av CPUs utførelsessyklus, kan det hende du finner ut at multitasking egentlig ikke eksisterer.

I stedet bytter prosessorer hele tiden mellom prosesser for å kjøre dem samtidig eller i det minste opptre som om de gjør det. CPU-en kan avbryte en prosess før den er fullført, og gjenoppta en annen prosess. Operativsystemet kontrollerer administrasjonen av disse prosessene.

For eksempel fungerer Round Robin-algoritmen, en av de enkleste byttealgoritmene, som følger:

Generelt lar denne algoritmen hver prosess kjøre i svært små biter av tid, slik operativsystemet bestemmer. Dette kan for eksempel være en periode på to mikrosekunder.

CPU-en tar hver prosess etter tur og utfører kommandoer som vil kjøre i to mikrosekunder. Den fortsetter så til neste prosess, uavhengig av om den nåværende er ferdig eller ikke. Fra sluttbrukerens synspunkt ser det ut til at mer enn én prosess kjører samtidig. Men når du ser bak kulissene, gjør CPU-en fortsatt ting i orden.

Forresten, som diagrammet ovenfor viser, mangler Round Robin-algoritmen noen optimaliserings- eller behandlingsprioritetsforestillinger. Som et resultat er det en ganske rudimentær metode som sjelden brukes i virkelige systemer.

For å forstå alt dette bedre, se for deg at to tråder kjører. Hvis trådene får tilgang til en felles variabel, kan det oppstå en rasetilstand.

Et eksempel på nettapplikasjon og løpstilstand

Sjekk ut den enkle Flask-appen nedenfor for å reflektere over et konkret eksempel på alt du har lest så langt. Hensikten med denne applikasjonen er å administrere pengetransaksjoner som vil finne sted på nettet. Lagre følgende i en fil med navnet money.py:

fra kolbe import Kolbe
fra flask.ext.sqlalchemy import SQLAlchemy

app = Kolbe (__navn__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy (app)

klasseRegnskap(db. Modell):
id = db. Kolonne (db. Heltall, primærnøkkel = ekte)
beløp = db. Kolonne (db. streng(80), unik = ekte)

def__i det__(selv, telle):
egenbeløp = beløp

def__repr__(selv):
komme tilbake '' % egenbeløp

@app.route("/")
defhei():
konto = Account.query.get(1) # Det er bare én lommebok.
komme tilbake "Total Money = {}".format (account.amount)

@app.route("/send/")
defsende(beløp):
konto = Account.query.get(1)

hvis int (konto.beløp) < beløp:
komme tilbake "Utilstrekkelig balanse. Tilbakestill penger med /reset!)"

konto.beløp = int (konto.beløp) - beløp
db.session.commit()
komme tilbake "Sendt beløp = {}".format (beløp)

@app.route("/reset")
defnullstille():
konto = Account.query.get(1)
konto.beløp = 5000
db.session.commit()
komme tilbake "Penger tilbakestilt."

hvis __navn__ == "__main__":
app.secret_key = 'heLLoTHisIsSeCReTKey!'
app.run()

For å kjøre denne koden, må du opprette en post i kontotabellen og fortsette transaksjonene over denne posten. Som du kan se i koden er dette et testmiljø, så det gjør transaksjoner mot den første posten i tabellen.

fra penger import db
db.create_all()
fra penger import Regnskap
konto = Konto (5000)
db.økt.Legg til(regnskap)
db.økt.begå()

Du har nå opprettet en konto med en saldo på $5 000. Til slutt, kjør kildekoden ovenfor ved å bruke følgende kommando, forutsatt at du har installert Flask- og Flask-SQLAlchemy-pakkene:

pythonpenger.py

Så du har Flask-webapplikasjonen som gjør en enkel utvinningsprosess. Denne applikasjonen kan utføre følgende operasjoner med GET-forespørselskoblinger. Siden Flask kjører på 5000-porten som standard, er adressen du får tilgang til den på 127.0.0.1:5000/. Appen gir følgende endepunkter:

  • 127.0.0.1:5000/ viser gjeldende saldo.
  • 127.0.0.1:5000/send/{amount} trekker beløp fra kontoen.
  • 127.0.0.1:5000/tilbakestill tilbakestiller kontoen til $5000.

Nå, på dette stadiet, kan du undersøke hvordan sårbarheten i rasetilstanden oppstår.

Sannsynlighet for en rasetilstandssårbarhet

Nettapplikasjonen ovenfor inneholder en mulig sårbarhet for rasetilstand.

Tenk deg at du har $5 000 til å begynne med og lag to forskjellige HTTP-forespørsler som sender $1. For dette kan du sende to forskjellige HTTP-forespørsler til lenken 127.0.0.1:5000/send/1. Anta at, så snart webserveren behandler den første forespørselen, stopper CPU denne prosessen og behandler den andre forespørselen. For eksempel kan den første prosessen stoppe etter å ha kjørt følgende kodelinje:

konto.beløp = int(konto.beløp) - beløp

Denne koden har beregnet en ny total, men har ennå ikke lagret posten i databasen. Når den andre forespørselen begynner, vil den utføre den samme beregningen, trekke $1 fra verdien i databasen—$5000—og lagre resultatet. Når den første prosessen gjenopptas, vil den lagre sin egen verdi—$4,999—som ikke vil reflektere den siste kontosaldoen.

Så to forespørsler er fullført, og hver skal ha trukket $1 fra kontosaldoen, noe som resulterer i en ny saldo på $4,998. Men avhengig av rekkefølgen nettserveren behandler dem i, kan den endelige kontosaldoen være $4 999.

Tenk deg at du sender 128 forespørsler om å foreta en $1-overføring til målsystemet i løpet av en tidsramme på fem sekunder. Som et resultat av denne transaksjonen vil den forventede kontoutskriften være $5,000 - $128 = $4,875. På grunn av løpstilstanden kan imidlertid den endelige saldoen variere mellom $4,875 og $4,999.

Programmerere er en av de viktigste komponentene i sikkerhet

I et programvareprosjekt, som programmerer, har du ganske mange ansvarsområder. Eksemplet ovenfor var for en enkel pengeoverføringsapplikasjon. Tenk deg å jobbe med et programvareprosjekt som administrerer en bankkonto eller backend av et stort e-handelsnettsted.

Du må være kjent med slike sårbarheter slik at programmet du har skrevet for å beskytte dem er fritt for sårbarheter. Dette krever et sterkt ansvar.

En rasetilstandssårbarhet er bare en av dem. Uansett hvilken teknologi du bruker, må du se opp for sårbarheter i koden du skriver. En av de viktigste ferdighetene du kan tilegne deg som programmerer er kjennskap til programvaresikkerhet.