# Underhanded contest: The OS war [closed]

We all know how the discussion about which is the best operating system caused a lot of flame-wars. Your goal is now, to provide decisive "proof" that your favorite operating system is better... ah, no, much better, to provide decisive "proof" that another operating system is bad.

The task: Write a program, that does some calculations, and it works correctly on at least one OS and incorrectly on at least another one.

• the program should do at least some calculations, so it has to read some simple input (preferably on the standard input, or if from files if you want, but misusing little endian/big endian would not only be cheap, but also obvious), and provide some output depending on the input. The calculations should be meaningful and justified, for example solving a real life or a mathematical problem.
• you should specify both operating systems, stating on which one it will work correctly, and on which one it won't. Both operating systems should be well known, and from roughly the same time (so no DOS 1.0 versus a modern OS). It is advised to provide a short description about the cause of the difference (especially if you suspect many people would not realize it) in spoiler tags.

like this

• the cause of the difference has to be subtle, so no #ifdef _WIN32 or similar, please! Remember, your goal is to "prove" that this specific system is bad, so people should not be able to (immediately) spot your trick!

• if there is a very strange or very unusual part in your code, you have to justify it in comments why it is there. Of course, this "justification" can/will be a big lie.

Scoring:

This is not a golf! The code should be well organized, and kept simple. Remember, your goal is to hide a bug into it so that people won't suspect it. The simpler the code, the less suspicious it is.

The winner will be decided by votes. The most votes after approximately 10 days after the first valid submission wins. Generally, answers where the code is easy to read and understand, yet the bug is well hidden, and even if discovered, can be attributed to a mistake rather than malice, should be voted up. Similarly, it should be worth much more if the bug just causes an incorrect result, rather than just causing the program to crash or to not do anything.

As usual, I withhold the right to choose an answer as a winner if it is not more than either 10% or 1 point below the one with the most votes, on any subjective criteria.

• Interestingly make (1) works properly on essentially every unix box and improperly some windows boxes. Not because of the OSes, but because of the filesystems. Any filesystem that keeps file modification dates to low precision may fail to make properly on a fast machine. – dmckee --- ex-moderator kitten Jul 18 '12 at 17:11
• @dmckee: this is why I'm glad that I did not leave everything open, and you have to read in some input and do some simple calculations. – vsz Jul 18 '12 at 17:58
• I only figured it now, that this quest for evil code has the Id of 6666 – vsz Jul 19 '12 at 15:46
• Here's to hoping for an answer that works on Windows and <Insert Linux Distribution>, but not on Mac. – Casey Kuball Jul 26 '12 at 2:03
• I'm voting to close this question as off-topic because underhanded challenges are no longer on-topic on this site. meta.codegolf.stackexchange.com/a/8326/20469 – cat Apr 18 '16 at 12:42

# Unix shell + standard utilities

Let's write a shell script that finds the process (owned by any user) that has used the most CPU time, and kills all processes with the same name. I suppose that counts as reading in data (from the system) and performing a calculation. (That behavior could be useful for processes that fork off many processes, such as fork bombs and Google Chromium.)

The following should be a portable way to get the name of the process with the greatest CPU time (I tried to avoid obvious Linuxisms but haven't tested it on Solaris):

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

So our script is simply

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

Run as root for best results, so that it can kill processes from other users.

## Linux and BSD

This works on Linux and should work on the BSDs, because killall arg kills processes named arg.

## Solaris

However, on Solaris, if a user happens to be running a program named 9 in an infinite loop, the script will bring down the system. This is because:

On Solaris, killall arg means to kill all processes with the signal arg. So the command line becomes killall 9. As 9 is the number for SIGKILL on Solaris, this will kill all processes and thereby bring down the system.

N.B.

This shell injection issue doesn't apply on Linux, because even though the malicious user could supply some special argument like -KILL as a process name, killall -KILL will harmlessly print a usage message.

• killall is not an example. That just two different programs with the same name. Each version is working properly. – dmckee --- ex-moderator kitten Aug 1 '12 at 13:34
• Yes, but the shell script is not working properly. – Mechanical snail Aug 1 '12 at 13:53
• Did you notice how Chromium and fork bombs are comparable? ;) – kaoD Mar 8 '13 at 2:30
• @kaoD: The key difference is that fork bombs use less memory. – Mechanical snail Mar 30 '14 at 10:09
• Just noting that there's no such thing as "Google Chromium": The Google Chrome browser is based on the open-source Chromium browser, but only the former contains Google-specific code and has Google's name attached. – Anko Sep 8 '14 at 11:05

# Python

This program opens the image specified on the command line and displays it.

import Image
import sys

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

Works on linux, does not work on windows.

This is due to the way windows opens files. Binary mode must be specified for this to work properly on all operating systems.

• The program should do some calculations and display the results. On a specific operating system it should also display some results, but incorrect ones. Yes, with some clever wordplay you could argue that this is exactly what your program is doing, but I think it's a deliberate misinterpretation of the rules. However, ultimately, the voters decide. – vsz Jul 19 '12 at 18:42

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

Any file format where there are multi-byte binary quantities in non-host order runs the risk of being misinterpreted. Here's a function which takes raw audio, say extracted from a WAV file (which is a Microsoft little endian file format), halves the amplitude and outputs the attenuated audio.

#include <stdio.h>

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

In little endian machines, this works great, but in big endian machines, it's a disaster. E.g.

01001101 11001110 -> CE4D (little endian format)

Shift right on little endian:

00100110 01100111 -> 8726 (correct)

Shift right on big endian:

00100110 11100111 -> E726 (not correct)

Note that some of the nybbles are correct! In fact, it's a 50:50 chance that the output will be correct, depending on whether the least significant bit of the sound sample is 0 or 1!

So when you listen to this audio, it's like half amplitude but with some jarring loud high pitched noise overlaid. Quite startling if you're not prepared for it!

## GTB

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

On the computer it works, but on my TI-84 calculator it doesn't. Why?

On the calculator RAM overflows and is potentially cleared, while on the emulator for Windows, RAM cannot be overflown by the emulator because of limited allocation.

• What does it do? – Ilmari Karonen Jan 24 '14 at 16:12
• There is a spoiler (yellow box) in the question that you can mouse over to see the hidden text. – Timtech Jan 24 '14 at 19:27
• Yes, but what does it do what RAM doesn't overflow? Does it actually "do some calculations", like the question asks for, and if so, what? – Ilmari Karonen Jan 24 '14 at 19:31
• @IlmariKaronen It just concatenates the strings. (You can specify, of course) – Timtech Jan 24 '14 at 20:19

## C

This solution to problem 100 (about Collatz sequence) is accepted by UVa Online Judge.

However, this code only works correctly on *nix platform since long type is implemented as 64-bit signed integer. On Windows, the code invokes undefined behavior, since long type is implemented as 32-bit signed integer, while one of the intermediate value in cyc() function needs at least 32-bit to represent.

#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;
}

Another way to make this further incompatible is to put the array l inside main() and make corresponding changes to cyc() function. Since the executable is set to request for 2 MB stack by default on Windows, the program crashes right away.

## Python

I came across this on StackOverflow when looking for input timeouts.

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

This does not work for Windows.

• Why is this not working in Windows? Am I right guessing it's because Windows doesn't support POSIX SIGs? Then it's just a matter of Python's standard libraries exposing functionality to both OSes. I don't think it follows the spirit of the challenge (e.g. Python's fork won't work either for obvious reasons) but that's Python's flaw (plus the fact that it's interpreted), not Windows'. E.g.: including conio.h would have the same effect, but C won't even compile. – kaoD Jul 19 '12 at 15:35
• @kaoD: Honestly, I'm not sure why it doesn't work in Windows either. Maybe Linux has some features in it that Windows doesn't, so this is able to be implemented into Linux and not Windows. – beary605 Jul 19 '12 at 15:39
• Then it's what I guessed: you're using POSIX functionality exposed by Python. IMHO this doesn't fit as an answer because of the previously stated reason, but hey, I'm just another ant in the colony ;) What you see is Python's "fault", not Windows. See this: docs.python.org/library/signal.html#signal.signal – kaoD Jul 19 '12 at 15:43
• The Windows API does not provide cancellable read on a pipe from within the thread. – Joshua Nov 20 '16 at 17:32

## Linux + bash + GNU coreutils

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

This will erase the root folder and everything in it which doesn't exist in Windows, even if you install bash for Windows :)

• This works on Windows now that Windows has a Linux subsystem built in. (I think, won't try it) – Pavel Jan 8 '17 at 9:39
• @Pavel Pretty simple to open up cmd.exe and type rm to see that it doesn't work. – MD XF Dec 30 '17 at 5:43