Buffer overflow vulnerabilities
For the statements below, please state whether they are true or false. Justify each answer.
- "If a server has a buffer overflow vulnerability, that means the server definitely has a bug."
- "Buffer overflow vulnerabilities can be ruled out by making the stack non-executable."
- "Buffer overflow vulnerabilities can be ruled out by making program text read-only."
- "Buffer overflow vulnerabilities can be ruled out with the W XOR X security policy."
- "Buffer overflow vulnerabilities can be eliminated with ASLR (address space layout randomization)."
- "Buffer overflow vulnerabilities are not possible on a 64-bit architecture."
- "If a buffer overflow vulnerability is exploited, this implies that the attacker has changed
%cr3
."
Concurrency Review
Consider the following implementation of a spinlock:
struct Lock {
int locked;
}
int exchange_value(int* ptr, int val) {
int was;
was = *ptr;
*ptr = val;
return was;
}
void acquire(Lock *lock) {
pushcli(); /* disable interrupts */
while (1) {
if (exchange_value(&lock->locked, 1) == 0)
break;
}
}
void release(Lock *lock){
exchange_value(&lock->locked, 0);
popcli(); /* re-enable interrupts */
}
Assume that the machine provides sequential consistency. The functions pushcli()
and popcli()
disable and re-enable interrupts, respectively.
Is the code correct? If the code is correct, explain what invariant is maintained. If the code is not correct, give a problematic interleaving and explain why it is problematic.
Monitors Review
In this problem, you will implement a monitor to help a set of drivers (modeled as threads) synchronize access to a set of five keys and a set of ten cars. Here is the problem setup:
- The relationship between the keys and the cars is that key 0 operates cars 0 and 1, key 1 operates cars 2 and 3, etc. That is, key i works for cars 2i and 2i+1.
- If a key is being used to operate one car, it cannot be used to operate the other.
- A driver requests a particular car (which implies that the driver needs a particular key). However, there may be many more drivers than cars. If a driver wants to go driving but cannot get its desired car or that car's key, it waits until the car and key become available. When a driver finishes driving, it returns its key and notifies any drivers waiting for that key that it is now free.
- You must allow multiple drivers to be out driving at once, and you must not have busy waiting or spin loops.
- We repeat: there could be many, many instances of
driver()
running, each of which you can assume is in its own thread, and all of which use the same monitor,mon
.
Below, fill in the monitor's remaining variable(s) and implement the monitor's take_key()
and return_key()
methods. Follow the coding standards given in class.
typedef enum {FREE, IN_USE} key_status;
class Monitor {
public:
Monitor() { memset(&keys, FREE, sizeof(key_status)*5); }
~Monitor() {}
void take_key(int desired_car);
void return_key(int desired_car);
private:
Mutex mutex;
key_status keys[5];
/* ADD MATERIAL BELOW THIS LINE */
};
void driver(thread_id tid, Monitor* mon, int desired_car) {
/* you should not modify this function */
mon->take_key(desired_car);
drive();
mon->return_key(desired_car);
}
void Monitor::take_key(int desired_car) {
/* FILL IN THIS FUNCTION. Note that the argument refers
to the desired car. */
}
void Monitor::return_key(int desired_car) {
/* FILL IN THIS FUNCTION. Note that the argument refers
to the desired car. */
}