Olivier D is almost correct, but you must set POSIXLY_CORRECT before running unset. POSIX has a notion of Special Built-ins, and bash supports this. unset is one such builtin. Search for SPECIAL_BUILTIN in builtins/*.c in the bash source for a list, it includes set, unset, export, eval and source.
$ unset() { echo muahaha-unset; }
$ unset unset
muahaha-unset
$ POSIXLY_CORRECT=1
$ unset unset
The rogue unset has now been removed from the environment, if you unset command, type, builtin then you should be able to proceed, but unset POSIXLY_CORRECT if you are relying on non-POSIX behaviour or advanced bash features later.
This does not address aliases though, so you must use \unset (or use some form of quoting/escaping on that word) to be sure it works in interactive shell (or always, in case expand_aliases is in effect).
For the paranoid, this should fix everything, I think:
POSIXLY_CORRECT=1
\unset -f help read unset
\unset POSIXLY_CORRECT
re='^([a-z:.\[]+):' # =~ is troublesome to escape
while \read cmd; do
[[ "$cmd" =~ $re ]] && \unset -f ${BASH_REMATCH[1]};
done < <( \help -s "*" )
(while, do, done and [[ are reserved words and don't need precautions. You can't use = in an alias or function name, so no precautions needed for setting POSIXLY_CORRECT.)
Note we are using unset -f to be sure to unset functions, although variables and functions share the same namespace it's possible for both to exist simultaneously (thanks to Etan Reisner) in which case unset-ing twice would also do the trick. You can mark a function readonly, bash does not prevent you unsetting a readonly function up to and including bash-4.2, bash-4.3 does prevent you but it still honours the special builtins when POSIXLY_CORRECT is set.
A readonly POSIXLY_CORRECT is not a real problem, this is not a boolean or flag its presence enables POSIX mode, so if it exists as a readonly you can rely on POSIX features, even if the value is empty or 0. You'll simply need to unset problematic functions a different way than above, perhaps with some cut-and-paste:
\help -s "*" | while IFS=": " read cmd junk; do echo \\unset -f $cmd; done
(and ignore any errors) or engage in some other scriptobatics.
Other notes:
function is a reserved word, it can be aliased but not overridden with a function. (Aliasing function is mildly troublesome because \function is not acceptable as a way of bypassing it)
[[, ]] are reserved words, they can be aliased (which will be ignored) but not overridden with a function (though functions can be so named)
(( is not a valid name for a function, nor an alias
Thanks to commenters below for the extra suggestions.
envcommand before, like this:env -i <SCRIPT.sh>envisn't redefined as a function as well. This is terrifying. I first thought that special characters would help -- calling with full path that includes/, using.to source, and so on. But those can also be used for function names! You can redefine any function you want, but it's hard to get back to calling the original command.#/bin/shif this is not default interactive shell.