From the sounds of it you want at least -O0, the default, and:
-fmudflap -fmudflapth -fmudflapir
For front-ends that support it (C and C++), instrument all risky
pointer/array dereferencing
operations, some standard library
string/heap functions, and some other
associated constructs with
range/validity tests. Modules so
instrumented should be immune to
buffer overflows, invalid heap use,
and some other classes of C/C++
programming errors. The
instrumentation relies on a separate
runtime library (libmudflap), which
will be linked into a program if
-fmudflap is given at link time. Run-time behavior of the instrumented
program is controlled by the
MUDFLAP_OPTIONS environment variable.
See env MUDFLAP_OPTIONS=-help a.out
for its options.
Here is a list of security features used in ubuntu: https://wiki.ubuntu.com/Security/Features You don't have to worry about NX bits, the address of g() will always be in a executable region of memory because it is within the TEXT memory segment. NX bits only come into play if you are trying to execute shellcode on the stack or heap, which is not required for this assignment.
Disables ASLR, SSP/Propolice and Ubuntu's NoneXec (which was placed in 9.10, and fairly simple to work around see the mprotect(2) technique to map pages as executable and jmp) should help a little, however these "security features" are by no means infallible. Without the `-z execstack' flag, pages have non-executable stack markings.
You don't need to disable ASLR in order to do a buffer overflow! Although ASLR is enabled (kernel_randomize_va_space = 2), it will not take effect unless the compiled executable is PIE. So unless you compiled your file with -fPIC -pie flag, ASLR will not take effect.
I think only disabling the canaries with -fno-stack-protector is enough.
If you want to check if ASLR is working or not (Position independent code must be set), use: