Underhanded contest: The OS war [chiuso]


29

Sappiamo tutti come la discussione su quale sia il miglior sistema operativo abbia causato molte guerre di fiamma. Il tuo obiettivo ora è fornire una "prova" decisiva che il tuo sistema operativo preferito sia migliore ... ah, no, molto meglio, fornire una "prova" decisiva che un altro sistema operativo è difettoso.

Il compito: scrivere un programma che esegua alcuni calcoli e funzioni correttamente su almeno un sistema operativo e in modo errato su almeno un altro.

  • il programma dovrebbe fare almeno alcuni calcoli, quindi deve leggere alcuni input semplici (preferibilmente sull'input standard, o se dai file se lo si desidera, ma l'uso improprio di little endian / big endian non sarebbe solo economico, ma anche ovvio) , e fornire un output in base all'input. I calcoli dovrebbero essere significativi e giustificati, ad esempio per risolvere una vita reale o un problema matematico.
  • dovresti specificare entrambi i sistemi operativi, indicando su quale funzionerà correttamente e su quale non funzionerà. Entrambi i sistemi operativi dovrebbero essere ben noti e più o meno allo stesso tempo (quindi nessun DOS 1.0 rispetto a un sistema operativo moderno). Si consiglia di fornire una breve descrizione della causa della differenza (specialmente se si sospetta che molte persone non se ne renderebbero conto) nei tag spoiler.

come questo

  • la causa della differenza deve essere sottile, quindi no #ifdef _WIN32o simile, per favore! Ricorda, il tuo obiettivo è "dimostrare" che questo sistema specifico è difettoso, quindi le persone non dovrebbero essere in grado (immediatamente) di individuare il tuo trucco!

  • se c'è una parte molto strana o molto insolita nel tuo codice, devi giustificarlo nei commenti perché è lì. Naturalmente questa "giustificazione" può / sarà una grande menzogna.

punteggio:

Questo non è un golf! Il codice dovrebbe essere ben organizzato e semplice. Ricorda, il tuo obiettivo è quello di nascondere un bug in modo che la gente non lo sospetti. Più semplice è il codice, meno è sospetto.

Il vincitore sarà deciso con voti. Vince il maggior numero di voti dopo circa 10 giorni dalla prima presentazione valida. In generale, le risposte in cui il codice è facile da leggere e comprendere, ma il bug è ben nascosto, e anche se scoperto, possono essere attribuite a un errore piuttosto che alla malizia, dovrebbero essere votate. Allo stesso modo, dovrebbe valere molto di più se il bug causa solo un risultato errato, piuttosto che semplicemente causare il crash del programma o non fare nulla.

Come al solito, trattengo il diritto di scegliere una risposta come vincente se non supera di oltre il 10% o 1 punto quella con il maggior numero di voti, su qualsiasi criterio soggettivo.


5
make (1)Funziona in modo interessante su essenzialmente ogni scatola unix e impropriamente alcune finestre. Non a causa dei sistemi operativi, ma a causa dei filesystem. Qualsiasi file system che mantiene le date di modifica dei file con bassa precisione potrebbe non funzionare makecorrettamente su una macchina veloce.
dmckee,

1
@dmckee: ecco perché sono contento di non aver lasciato tutto aperto, e devi leggere alcuni input e fare alcuni semplici calcoli.
vsz,

10
Ho capito solo ora che questa ricerca del codice malvagio ha l'ID 6666
vsz

3
Speriamo in una risposta che funzioni su Windows e <Inserisci distribuzione Linux>, ma non su Mac.
Casey Kuball,

1
Sto votando per chiudere questa domanda come fuori tema perché le sfide subdole non sono più in argomento su questo sito. meta.codegolf.stackexchange.com/a/8326/20469
cat

Risposte:


15

Shell Unix + utility standard

Scriviamo uno script di shell che trova il processo (di proprietà di qualsiasi utente) che ha utilizzato più tempo della CPU e uccide tutti i processi con lo stesso nome. Suppongo che conti come leggere i dati (dal sistema) ed eseguire un calcolo. (Tale comportamento potrebbe essere utile per i processi che interrompono molti processi, come le bombe a forcella e Google Chromium.)

Di seguito dovrebbe essere un modo portatile per ottenere il nome del processo con il massimo tempo di CPU (ho cercato di evitare ovvi Linuxism ma non l'ho testato su Solaris):

ps -A -o time= -o comm= | sort | tail -n 1 | cut -d ' ' -f 2

Quindi la nostra sceneggiatura è semplicemente

killall `ps -A -o time= -o comm= | sort | tail -n 1 | cut -d ' ' -f 2`

Esegui come root per i migliori risultati, in modo che possa uccidere i processi da altri utenti.

Linux e BSD

Funziona su Linux e dovrebbe funzionare sui BSD, perché killall arguccide i processi denominati arg.

Solaris

Tuttavia, su Solaris, se un utente esegue un programma chiamato 9in un ciclo infinito, lo script farà cadere il sistema . Questo è perché:

Su Solaris, killall argsignifica uccidere tutti i processi con il segnale arg. Quindi la riga di comando diventa killall 9. Come 9è il numero di SIGKILL su Solaris , questo ucciderà tutti i processi e quindi abbatterà il sistema.

NB

Questo problema di iniezione shell non si applica a Linux, perché anche se l'utente malintenzionato potrebbe fornire argomenti speciali -KILLcome un nome di processo, killall -KILLstamperà un messaggio di utilizzo innocuo.


3
killallnon è un esempio. Che solo due programmi diversi con lo stesso nome. Ogni versione funziona correttamente.
dmckee,

7
Sì, ma lo script della shell non funziona correttamente.
Lumaca meccanica

12
Hai notato che le bombe al cromo e alla forcella sono comparabili? ;)
kaoD

7
@kaoD: La differenza fondamentale è che le bombe a forcella usano meno memoria.
Lumaca meccanica

1
Solo notando che non esiste "Google Chromium": il browser Google Chrome si basa sul browser Chromium open source , ma solo il primo contiene un codice specifico di Google e ha il nome di Google allegato.
Anko,

18

Pitone

Questo programma apre l'immagine specificata sulla riga di comando e la visualizza.

import Image
import sys

with open(sys.argv[1]) as f:
    im = Image.open(f)
    im.show()

Funziona su Linux, non funziona su Windows.

Ciò è dovuto al modo in cui Windows apre i file. La modalità binaria deve essere specificata affinché funzioni correttamente su tutti i sistemi operativi.


4
Il programma dovrebbe eseguire alcuni calcoli e visualizzare i risultati. Su un sistema operativo specifico dovrebbe anche visualizzare alcuni risultati, ma quelli errati. Sì, con un gioco di parole intelligente potresti sostenere che questo è esattamente ciò che il tuo programma sta facendo, ma penso che sia una deliberata interpretazione errata delle regole. Tuttavia, alla fine, gli elettori decidono.
vsz

5

Little Endian (Intel x86) vs. Big Endian (IBM Power7)

Qualsiasi formato di file in cui vi sono quantità binarie multi-byte in ordine non host comporta il rischio di essere interpretato erroneamente. Ecco una funzione che prende l'audio non elaborato, ad esempio estratto da un file WAV (che è un formato di file Microsoft little endian), dimezza l'ampiezza e genera l'audio attenuato.

#include <stdio.h>

int main()
{
    short audio;
    while (fread(&audio, sizeof(short), 1, stdin))
    {
        audio >>= 1;
        fwrite(&audio, sizeof(short), 1, stdout);
    }
    return 0;
}

Nelle macchine little endian funziona alla grande, ma nelle macchine big endian è un disastro. Per esempio

01001101 11001110 -> CE4D (little endian format)

Sposta a destra su little endian:

00100110 01100111 -> 8726 (correct)

Spostati a destra su big endian:

00100110 11100111 -> E726 (not correct)

Nota che alcuni dei nybbles sono corretti! In effetti, è una probabilità 50:50 che l'uscita sia corretta, a seconda che il bit meno significativo del campione audio sia 0 o 1!

Quindi, quando ascolti questo audio, è come una mezza ampiezza ma con un po 'di rumore acuto e acuto sovrapposto sovrapposto. Abbastanza sorprendente se non sei preparato per questo!


5

GTB

:"-→_[_+_→_]

Sul computer funziona, ma sulla mia calcolatrice TI-84 non funziona. Perché?

Sul calcolatore la RAM trabocca e viene potenzialmente cancellata, mentre sull'emulatore per Windows, la RAM non può essere sovraccaricata dall'emulatore a causa di un'allocazione limitata.


Che cosa fa?
Ilmari Karonen,

C'è uno spoiler (riquadro giallo) nella domanda che puoi passare con il mouse per vedere il testo nascosto.
Timtech,

4
Sì, ma cosa fa ciò che la RAM non trabocca? In realtà "fa alcuni calcoli", come fa la domanda, e se sì, cosa?
Ilmari Karonen,

@IlmariKaronen Concatena solo le stringhe. (Puoi specificare, ovviamente)
Timtech,

4

C

Questa soluzione al problema 100 (sulla sequenza di Collatz) è accettata dal giudice online UVa.

Tuttavia, questo codice funziona correttamente solo sulla piattaforma * nix poiché il longtipo è implementato come numero intero con segno a 64 bit. Su Windows , il codice invoca un comportamento indefinito, poiché il longtipo è implementato come numero intero con segno a 32 bit, mentre uno dei valori intermedi nella cyc()funzione deve essere rappresentato almeno a 32 bit.

#include <stdio.h>

#define swap(a, b, t) t __tmp__ = a; a = b; b = __tmp__;
#define M 1000000

short l[M] = {0, 1};

int cyc(long n) { // HERE
    if (n < M && l[n]) return l[n];
    n = n & 0x1 ? 3 * n + 1 : n >> 1;
    return n < M ? (l[n] = cyc(n)) + 1 : cyc(n) + 1;
}

int max(int a, int b) { return a > b ? a : b; }

int main() {
    #ifndef ONLINE_JUDGE
    // freopen("input.txt", "r", stdin);
    #endif
    int i, j, m;
    while (scanf("%d %d", &i, &j) == 2) {
          printf("%d %d ", i, j);
          if (i > j) { swap(i, j, int); }
          for (m = 0; i <= j; i++)
              m = max(m, cyc(i));
          printf("%d\n", m);
    }

    return 0;
}

Un altro modo per renderlo ulteriormente incompatibile è inserire l'array lall'interno main()e apportare le corrispondenti modifiche alla cyc()funzione. Poiché l'eseguibile è impostato per richiedere stack da 2 MB per impostazione predefinita su Windows, il programma si arresta immediatamente.


2

Pitone

Mi sono imbattuto in questo StackOverflow durante la ricerca di timeout di input.

 import signal 
 TIMEOUT = 5

 def interrupted(signum, frame): 
     print 'interrupted!' 
 signal.signal(signal.SIGALRM, interrupted) 

 def input(): 
     try: 
         print 'You have 5 seconds to type in your stuff...' 
         foo = raw_input() 
         return foo 
     except: 
         return

 signal.alarm(TIMEOUT) 
 s = input()
 signal.alarm(0) 
 print 'You typed', s 

Questo non funziona per Windows.


Perché questo non funziona in Windows? Sto indovinando giusto perché Windows non supporta SIG POSIX? Quindi è solo una questione di librerie standard di Python che espongono funzionalità a entrambi i sistemi operativi. Non penso che segua lo spirito della sfida (ad esempio, il fork di Python non funzionerà nemmeno per ovvi motivi) ma questo è il difetto di Python (oltre al fatto che è interpretato), non Windows '. Ad esempio: includere conio.havrebbe lo stesso effetto, ma C non si compila nemmeno.
Kaao,

@kaoD: Onestamente, non sono sicuro del perché non funzioni neanche in Windows. Forse Linux ha alcune caratteristiche che Windows non ha, quindi questo può essere implementato in Linux e non in Windows.
beary605,

Quindi è quello che ho indovinato: stai usando la funzionalità POSIX esposta da Python. IMHO questo non si adatta come una risposta a causa della ragione precedentemente dichiarata, ma hey, sono solo un'altra formica nella colonia;) Quello che vedi è "colpa" di Python, non Windows. Vedi questo: docs.python.org/library/signal.html#signal.signal
kaoD

L'API di Windows non fornisce letture cancellabili su una pipe all'interno del thread.
Joshua,

0

Coreutils Linux + bash + GNU

rm --no-preserve-root -R -dir /

Questo cancellerà la cartella principale e tutto ciò che non esiste in Windows, anche se si installa bash per Windows :)


Funziona su Windows ora che Windows ha un sottosistema Linux integrato. (Penso, non lo proverò)
Pavel

@Pavel Abbastanza semplice da aprire cmd.exee digitare rmper vedere che non funziona.
MD XF,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.