Skip to main content
linked to the answer about POSIX special builtins rather than the comment
Source Link
Eliah Kagan
  • 4.2k
  • 2
  • 27
  • 39

can you still recover if all three functions are marked readonly?

Yes, usually you can, though that does not mean you should.

Just as you can unset readonly variables by attaching a debugger and calling unbind_variable as shown in anishsane's answer to that question, you can also unset readonly functions passing their names to unbind_func using a debugger.

This is not a reasonable approach when they aren't readonly (if it indeed ever is). In that situation you should use cuonglm's solutioncuonglm's solution, which takes advantage of how unset is treated in POSIX mode. That solution is something you might actually use in real life.

Since there's no actual guarantee that your shell will behave reasonably after you circumvent readonly with a debugger, I suggest avoiding it whenever a more reasonable alternative, like quitting and restarting your shell or replacing your shell with a new one using exec, is available.

With that said, here's anishsane's method adapted to unset functions instead of a variable:

cat <<EOF | sudo gdb
attach $$
call unbind_func("unset")
call unbind_func("builtin")
call unbind_func("command")
detach
EOF

Note that $$ is expanded into the shell's process ID, because no part of EOF in <<EOF is quoted.

I tested this on Bash 4.3.48(1)-release on Ubuntu 16.04 LTS, and it worked. You need gdb for this, though it could be adapted to other debuggers. As anishsane commented, piping from cat is intended to avoid a deadlock where the process that gives input to gdb is the one that gdb has stopped. I believe it achieves that goal, because in a pipeline of two or more commands, Bash runs each command in a subshell. But I am unsure if it is the most robust way. Ultimately, however, there's no actual guarantee that this works anyway, since it's entirely reasonable for Bash to assume readonly variables and functions won't change. In practice, my guess is that this does virtually always work.

To use this technique as written, you need sudo installed and you need to be able to sudo to root. You can, of course, replace it with another privilege-elevation method. Depending on what OS you are running and how it is configured, you might be able to omit sudo altogether and run gdb as yourself instead of root. For example, the Linux kernel will consult the value of /proc/sys/kernel/yama/ptrace_scope, which you can set through sysctl and may read or (as root) write, to determine what processes may debug other processes. If the value is 1, then only a process's direct parent--or any process running as root--may debug it. Most recent GNU/Linux systems have it set to 1, which is why I included sudo.

That description of Linux kernel behavior is somewhat oversimplified, in that other ptrace_scope values are allowed and in that the relationship required by 1 can be adjusted. See the relevant documentation for full details.

can you still recover if all three functions are marked readonly?

Yes, usually you can, though that does not mean you should.

Just as you can unset readonly variables by attaching a debugger and calling unbind_variable as shown in anishsane's answer to that question, you can also unset readonly functions passing their names to unbind_func using a debugger.

This is not a reasonable approach when they aren't readonly (if it indeed ever is). In that situation you should use cuonglm's solution, which takes advantage of how unset is treated in POSIX mode. That solution is something you might actually use in real life.

Since there's no actual guarantee that your shell will behave reasonably after you circumvent readonly with a debugger, I suggest avoiding it whenever a more reasonable alternative, like quitting and restarting your shell or replacing your shell with a new one using exec, is available.

With that said, here's anishsane's method adapted to unset functions instead of a variable:

cat <<EOF | sudo gdb
attach $$
call unbind_func("unset")
call unbind_func("builtin")
call unbind_func("command")
detach
EOF

Note that $$ is expanded into the shell's process ID, because no part of EOF in <<EOF is quoted.

I tested this on Bash 4.3.48(1)-release on Ubuntu 16.04 LTS, and it worked. You need gdb for this, though it could be adapted to other debuggers. As anishsane commented, piping from cat is intended to avoid a deadlock where the process that gives input to gdb is the one that gdb has stopped. I believe it achieves that goal, because in a pipeline of two or more commands, Bash runs each command in a subshell. But I am unsure if it is the most robust way. Ultimately, however, there's no actual guarantee that this works anyway, since it's entirely reasonable for Bash to assume readonly variables and functions won't change. In practice, my guess is that this does virtually always work.

To use this technique as written, you need sudo installed and you need to be able to sudo to root. You can, of course, replace it with another privilege-elevation method. Depending on what OS you are running and how it is configured, you might be able to omit sudo altogether and run gdb as yourself instead of root. For example, the Linux kernel will consult the value of /proc/sys/kernel/yama/ptrace_scope, which you can set through sysctl and may read or (as root) write, to determine what processes may debug other processes. If the value is 1, then only a process's direct parent--or any process running as root--may debug it. Most recent GNU/Linux systems have it set to 1, which is why I included sudo.

That description of Linux kernel behavior is somewhat oversimplified, in that other ptrace_scope values are allowed and in that the relationship required by 1 can be adjusted. See the relevant documentation for full details.

can you still recover if all three functions are marked readonly?

Yes, usually you can, though that does not mean you should.

Just as you can unset readonly variables by attaching a debugger and calling unbind_variable as shown in anishsane's answer to that question, you can also unset readonly functions passing their names to unbind_func using a debugger.

This is not a reasonable approach when they aren't readonly (if it indeed ever is). In that situation you should use cuonglm's solution, which takes advantage of how unset is treated in POSIX mode. That solution is something you might actually use in real life.

Since there's no actual guarantee that your shell will behave reasonably after you circumvent readonly with a debugger, I suggest avoiding it whenever a more reasonable alternative, like quitting and restarting your shell or replacing your shell with a new one using exec, is available.

With that said, here's anishsane's method adapted to unset functions instead of a variable:

cat <<EOF | sudo gdb
attach $$
call unbind_func("unset")
call unbind_func("builtin")
call unbind_func("command")
detach
EOF

Note that $$ is expanded into the shell's process ID, because no part of EOF in <<EOF is quoted.

I tested this on Bash 4.3.48(1)-release on Ubuntu 16.04 LTS, and it worked. You need gdb for this, though it could be adapted to other debuggers. As anishsane commented, piping from cat is intended to avoid a deadlock where the process that gives input to gdb is the one that gdb has stopped. I believe it achieves that goal, because in a pipeline of two or more commands, Bash runs each command in a subshell. But I am unsure if it is the most robust way. Ultimately, however, there's no actual guarantee that this works anyway, since it's entirely reasonable for Bash to assume readonly variables and functions won't change. In practice, my guess is that this does virtually always work.

To use this technique as written, you need sudo installed and you need to be able to sudo to root. You can, of course, replace it with another privilege-elevation method. Depending on what OS you are running and how it is configured, you might be able to omit sudo altogether and run gdb as yourself instead of root. For example, the Linux kernel will consult the value of /proc/sys/kernel/yama/ptrace_scope, which you can set through sysctl and may read or (as root) write, to determine what processes may debug other processes. If the value is 1, then only a process's direct parent--or any process running as root--may debug it. Most recent GNU/Linux systems have it set to 1, which is why I included sudo.

That description of Linux kernel behavior is somewhat oversimplified, in that other ptrace_scope values are allowed and in that the relationship required by 1 can be adjusted. See the relevant documentation for full details.

added 14 characters in body
Source Link
Eliah Kagan
  • 4.2k
  • 2
  • 27
  • 39

can you still recover if all three functions are marked readonly?

Yes, usually you can, though that does not mean you should.

Just as you can unset readonly variables by attaching a debugger and calling unbind_variable as shown in anishsane's answer to that question, you can also unset readonly functions passing their names to unbind_func using a debugger.

This is not a reasonable approach when they aren't readonly (if it indeed ever is). In that situation you should use cuonglm's solution, which takes advantage of how unset is treated in POSIX mode. That solution is something you might actually use in real life.

Since there's no actual guarantee that your shell will behave reasonably after you circumvent readonly with a debugger, I suggest avoiding it whenever a more reasonable alternative, like quitting and restarting your shell or replacing your shell with a new one using exec, is available.

With that said, here's anishsane's method adapted to unset functions instead of a variable:

cat <<EOF | sudo gdb
attach $$
call unbind_func("unset")
call unbind_func("builtin")
call unbind_func("command")
detach
EOF

Note that $$ is expanded into the shell's process ID, because no part of EOF in <<EOF is quoted.

I tested this on Bash 4.3.48(1)-release on Ubuntu 16.04 LTS, and it worked. You need gdb for this, though it could be adapted to other debuggers. As anishsane commented, piping from cat is intended to avoid a deadlock where the process that gives input to gdb is the one that gdb has stopped. I believe it achieves that goal, because in a pipeline of two or more commands, Bash runs each command in a subshell. But I am unsure if it is the most robust way. Ultimately, however, there's no actual guarantee that this works anyway, since it's entirely reasonable for Bash to assume readonly variables and functions won't change. In practice, my guess is that this does virtually always work.

To use this technique as written, you need sudo installed and you need to be able to sudo to root. You can, of course, replace it with another privilege-elevation method. Depending on what OS you are running and how it is configured, you might be able to omit sudo altogether and run gdb as yourself instead of root. For example, the Linux kernel will consult the value of /proc/sys/kernel/yama/ptrace_scope, which you can set through sysctl and may read or (as root) write, to determine what processes may debug other processes. If the value is 1, then only a process's direct parent--or any process running as root--may debug it. Most recent GNU/Linux systems have it set to 1, which is why I included sudo.

That description of Linux kernel behavior is somewhat oversimplified, in that other ptrace_scope values are allowed and in that the relationship required by 1 can be adjusted. See the relevant documentation for full details.

can you still recover if all three functions are marked readonly?

Yes, usually you can, though that does not mean you should.

Just as you can unset readonly variables by attaching a debugger and calling unbind_variable as shown in anishsane's answer to that question, you can also unset readonly functions passing their names to unbind_func using a debugger.

This is not a reasonable approach when they aren't readonly (if it indeed ever is). In that situation you should use cuonglm's solution, which takes advantage of how unset is treated in POSIX mode. That solution is something you might actually use in real life.

Since there's no actual guarantee that your shell will behave reasonably after you circumvent readonly with a debugger, I suggest avoiding it whenever a more reasonable alternative, like quitting and restarting your shell or replacing your shell with a new one using exec, is available.

With that said, here's anishsane's method adapted to unset functions instead of a variable:

cat <<EOF | sudo gdb
attach $$
call unbind_func("unset")
call unbind_func("builtin")
call unbind_func("command")
detach
EOF

Note that $$ is expanded into the shell's process ID, because no part of EOF in <<EOF is quoted.

I tested this on Bash 4.3.48(1)-release on Ubuntu 16.04 LTS, and it worked. You need gdb for this, though it could be adapted to other debuggers. As anishsane commented, piping from cat is intended to avoid a deadlock where the process that gives input to gdb is the one that gdb has stopped. I believe it achieves that goal, because in a pipeline of two or more commands, Bash runs each command in a subshell. But I am unsure if it is the most robust way. Ultimately, however, there's no actual guarantee that this works anyway, since it's entirely reasonable for Bash to assume readonly variables won't change. In practice, my guess is that this does virtually always work.

To use this technique as written, you need sudo installed and you need to be able to sudo to root. You can, of course, replace it with another privilege-elevation method. Depending on what OS you are running and how it is configured, you might be able to omit sudo altogether and run gdb as yourself instead of root. For example, the Linux kernel will consult the value of /proc/sys/kernel/yama/ptrace_scope, which you can set through sysctl and may read or (as root) write, to determine what processes may debug other processes. If the value is 1, then only a process's direct parent--or any process running as root--may debug it. Most recent GNU/Linux systems have it set to 1, which is why I included sudo.

That description of Linux kernel behavior is somewhat oversimplified, in that other ptrace_scope values are allowed and in that the relationship required by 1 can be adjusted. See the relevant documentation for full details.

can you still recover if all three functions are marked readonly?

Yes, usually you can, though that does not mean you should.

Just as you can unset readonly variables by attaching a debugger and calling unbind_variable as shown in anishsane's answer to that question, you can also unset readonly functions passing their names to unbind_func using a debugger.

This is not a reasonable approach when they aren't readonly (if it indeed ever is). In that situation you should use cuonglm's solution, which takes advantage of how unset is treated in POSIX mode. That solution is something you might actually use in real life.

Since there's no actual guarantee that your shell will behave reasonably after you circumvent readonly with a debugger, I suggest avoiding it whenever a more reasonable alternative, like quitting and restarting your shell or replacing your shell with a new one using exec, is available.

With that said, here's anishsane's method adapted to unset functions instead of a variable:

cat <<EOF | sudo gdb
attach $$
call unbind_func("unset")
call unbind_func("builtin")
call unbind_func("command")
detach
EOF

Note that $$ is expanded into the shell's process ID, because no part of EOF in <<EOF is quoted.

I tested this on Bash 4.3.48(1)-release on Ubuntu 16.04 LTS, and it worked. You need gdb for this, though it could be adapted to other debuggers. As anishsane commented, piping from cat is intended to avoid a deadlock where the process that gives input to gdb is the one that gdb has stopped. I believe it achieves that goal, because in a pipeline of two or more commands, Bash runs each command in a subshell. But I am unsure if it is the most robust way. Ultimately, however, there's no actual guarantee that this works anyway, since it's entirely reasonable for Bash to assume readonly variables and functions won't change. In practice, my guess is that this does virtually always work.

To use this technique as written, you need sudo installed and you need to be able to sudo to root. You can, of course, replace it with another privilege-elevation method. Depending on what OS you are running and how it is configured, you might be able to omit sudo altogether and run gdb as yourself instead of root. For example, the Linux kernel will consult the value of /proc/sys/kernel/yama/ptrace_scope, which you can set through sysctl and may read or (as root) write, to determine what processes may debug other processes. If the value is 1, then only a process's direct parent--or any process running as root--may debug it. Most recent GNU/Linux systems have it set to 1, which is why I included sudo.

That description of Linux kernel behavior is somewhat oversimplified, in that other ptrace_scope values are allowed and in that the relationship required by 1 can be adjusted. See the relevant documentation for full details.

bolded the "warning"; added a disclaimer about my approximate description of ptrace_scope and linked to the official full details
Source Link
Eliah Kagan
  • 4.2k
  • 2
  • 27
  • 39

can you still recover if all three functions are marked readonly?

Yes, usually you can, though that does not mean you should.

Just as you can unset readonly variables by attaching a debugger and calling unbind_variable as shown in anishsane's answer to that question, you can also unset readonly functions passing their names to unbind_func using a debugger.

This is not a reasonable approach when they aren't readonly (if it indeed ever is). In that situation you should use cuonglm's solution, which takes advantage of how unset is treated in POSIX mode.In that situation you should use cuonglm's solution, which takes advantage of how unset is treated in POSIX mode. That solution is something you might actually use in real life.

Since there's no actual guarantee that your shell will behave reasonably after you circumvent readonly with a debugger, I suggest avoiding it whenever a more reasonable alternative, like quitting and restarting your shell or replacing your shell with a new one using exec, is available.

With that said, here's anishsane's method adapted to unset functions instead of a variable:

cat <<EOF | sudo gdb
attach $$
call unbind_func("unset")
call unbind_func("builtin")
call unbind_func("command")
detach
EOF

Note that $$ is expanded into the shell's process ID, because no part of EOF in <<EOF is quoted.

I tested this on Bash 4.3.48(1)-release on Ubuntu 16.04 LTS, and it worked. You need gdb for this, though it could be adapted to other debuggers. As anishsane commented, piping from cat is intended to avoid a deadlock where the process that gives input to gdb is the one that gdb has stopped. I believe it achieves that goal, because in a pipeline of two or more commands, Bash runs each command in a subshell. But I am unsure if it is the most robust way. Ultimately, however, there's no actual guarantee that this works anyway, since it's entirely reasonable for Bash to assume readonly variables won't change. In practice, my guess is that this does virtually always work.

To use this methodtechnique as written, you need sudo installed and you need to be able to sudo to root. You can, of course, replace it with another privilege-elevation method. Depending on what OS you are running and how it is configured, you might be able to omit sudo altogether and run gdb as yourself instead of root. For example, the Linux kernel will consult the value of /proc/sys/kernel/yama/ptrace_scope, which you can set through sysctl and may read or (as root) write, to determine what processes may debug other processes. If the value is 1, then only a process's direct parent--or any process running as root--may debug it. Most recent GNU/Linux systems have it set to 1, which is why I included sudo.

That description of Linux kernel behavior is somewhat oversimplified, in that other ptrace_scope values are allowed and in that the relationship required by 1 can be adjusted. See the relevant documentation for full details.

can you still recover if all three functions are marked readonly?

Yes, usually you can, though that does not mean you should.

Just as you can unset readonly variables by attaching a debugger and calling unbind_variable as shown in anishsane's answer to that question, you can also unset readonly functions passing their names to unbind_func using a debugger.

This is not a reasonable approach when they aren't readonly (if it indeed ever is). In that situation you should use cuonglm's solution, which takes advantage of how unset is treated in POSIX mode. That solution is something you might actually use in real life.

Since there's no actual guarantee that your shell will behave reasonably after you circumvent readonly with a debugger, I suggest avoiding it whenever a more reasonable alternative, like quitting and restarting your shell or replacing your shell with a new one using exec, is available.

With that said, here's anishsane's method adapted to unset functions instead of a variable:

cat <<EOF | sudo gdb
attach $$
call unbind_func("unset")
call unbind_func("builtin")
call unbind_func("command")
detach
EOF

Note that $$ is expanded into the shell's process ID, because no part of EOF in <<EOF is quoted.

I tested this on Bash 4.3.48(1)-release on Ubuntu 16.04 LTS, and it worked. You need gdb for this, though it could be adapted to other debuggers. As anishsane commented, piping from cat is intended to avoid a deadlock where the process that gives input to gdb is the one that gdb has stopped. I believe it achieves that goal, because in a pipeline of two or more commands, Bash runs each command in a subshell. But I am unsure if it is the most robust way. Ultimately, however, there's no actual guarantee that this works anyway, since it's entirely reasonable for Bash to assume readonly variables won't change. In practice, my guess is that this does virtually always work.

To use this method as written, you need sudo installed and you need to be able to sudo to root. You can replace it with another method. Depending on what OS you are running and how it is configured, you might be able to omit sudo altogether and run gdb as yourself instead of root. For example, the Linux kernel will consult the value of /proc/sys/kernel/yama/ptrace_scope, which you can set through sysctl and may read or (as root) write, to determine what processes may debug other processes. If the value is 1, then only a process's direct parent--or any process running as root--may debug it. Most recent GNU/Linux systems have it set to 1, which is why I included sudo.

can you still recover if all three functions are marked readonly?

Yes, usually you can, though that does not mean you should.

Just as you can unset readonly variables by attaching a debugger and calling unbind_variable as shown in anishsane's answer to that question, you can also unset readonly functions passing their names to unbind_func using a debugger.

This is not a reasonable approach when they aren't readonly (if it indeed ever is). In that situation you should use cuonglm's solution, which takes advantage of how unset is treated in POSIX mode. That solution is something you might actually use in real life.

Since there's no actual guarantee that your shell will behave reasonably after you circumvent readonly with a debugger, I suggest avoiding it whenever a more reasonable alternative, like quitting and restarting your shell or replacing your shell with a new one using exec, is available.

With that said, here's anishsane's method adapted to unset functions instead of a variable:

cat <<EOF | sudo gdb
attach $$
call unbind_func("unset")
call unbind_func("builtin")
call unbind_func("command")
detach
EOF

Note that $$ is expanded into the shell's process ID, because no part of EOF in <<EOF is quoted.

I tested this on Bash 4.3.48(1)-release on Ubuntu 16.04 LTS, and it worked. You need gdb for this, though it could be adapted to other debuggers. As anishsane commented, piping from cat is intended to avoid a deadlock where the process that gives input to gdb is the one that gdb has stopped. I believe it achieves that goal, because in a pipeline of two or more commands, Bash runs each command in a subshell. But I am unsure if it is the most robust way. Ultimately, however, there's no actual guarantee that this works anyway, since it's entirely reasonable for Bash to assume readonly variables won't change. In practice, my guess is that this does virtually always work.

To use this technique as written, you need sudo installed and you need to be able to sudo to root. You can, of course, replace it with another privilege-elevation method. Depending on what OS you are running and how it is configured, you might be able to omit sudo altogether and run gdb as yourself instead of root. For example, the Linux kernel will consult the value of /proc/sys/kernel/yama/ptrace_scope, which you can set through sysctl and may read or (as root) write, to determine what processes may debug other processes. If the value is 1, then only a process's direct parent--or any process running as root--may debug it. Most recent GNU/Linux systems have it set to 1, which is why I included sudo.

That description of Linux kernel behavior is somewhat oversimplified, in that other ptrace_scope values are allowed and in that the relationship required by 1 can be adjusted. See the relevant documentation for full details.

added explanation about why parameter expansion occurs in the here document
Source Link
Eliah Kagan
  • 4.2k
  • 2
  • 27
  • 39
Loading
Source Link
Eliah Kagan
  • 4.2k
  • 2
  • 27
  • 39
Loading