microsoft / vscode-cpptools

Official repository for the Microsoft C/C++ extension for VS Code.
Other
5.53k stars 1.56k forks source link

Unable to launch debugger (gdb) with root permissions. #861

Closed weinand closed 5 years ago

weinand commented 7 years ago

From @BlinkFan on July 3, 2017 11:28

Steps to Reproduce:

When needing to debug a program that needs root permission (for eg. needs access to RAW socket) then the debugger cannot be used currently. Two possible options:

Copied from original issue: Microsoft/vscode#30049

pieandcakes commented 7 years ago

@blinkfan When launching gdb and it needs sudo, it will prompt for sudo today. Can you post your launch.json so I can try and duplicate?

BlinkFan commented 7 years ago

@pieandcakes : Perhaps I'm not understanding your answer.

In "launch.json" the only acceptable values for MIMode is "gdb" and "lldb". I cannot replace this with "sudo gdb" for eg. So there is no way for me to specify that I want to run gdb with root privileges.

The "program" parameter also does not allow me to add sudo (although I don't think this would be supported by gdb anyway).

I have also tried creating a bash script that simply invokes "sudo gdb". I then changed "miDebuggerPath" to this bash script - no success. (note - I'm still a bit of a Linux(Ubuntu) newbie)

My launch.json

{ "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", "program": "${workspaceRoot}/my_socket_program", "args": ["-i", "enp0s31f6", "lo"], "stopAtEntry": false, "cwd": "${workspaceRoot}", "environment": [], "externalConsole": true, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] } ] }

pieandcakes commented 7 years ago

@BlinkFan when you launch, if gdb needs sudo permissions, it will prompt you to enter your credentials in the external console window that pops up. Usually, it will try and launch with the same permissions as you have opened VSCode with. You will almost always see this prompt during attach request types but sometimes also on launch. You can try and launch VSCode with sudo and then launch will launch with the same elevated permissions of the user account.

If you create a bash script, you have to pass all the additional parameters through to gdb as we specify command line parameters such as --interpreter=mi to the miDebuggerPath. If your script doesn't do this, it might be why this isn't working.

sepisoad commented 7 years ago

I have the same issue,

I am trying to debug Snort source code which requires root privilege when trying to capture raw packets off the network.

when running VSCode as normal, it does not ask for root password, at least I have never seen such a dialog box for entering my credentials. when running VSCode as root user, the plugin crashes and fails to start gdb.

right now I am using another plugin called 'Native Debug' which works with gdb when running VSCode as root user. But it has less features than the official plugin.

Please fix this issue or let us know how to make it work.

I love VSCode and these days I use it a lot. I don't want to switch to any other IDE. Thanks

bugraaydogar commented 7 years ago

Hi guys,

As a workaround, you can decorate existing gdb binary with a bash script and then use it. Steps are,

Now you need to create a bash script named gdb with following content.

Content of the bash is; #!/bin/sh sudo gdborig $@

Finally, make the script runnable. sudo chmod 0755 gdb

Then you should be OK.

BlinkFan commented 7 years ago

Thank you @bugraaydogar, this works. It's just a little bit of inconvenience, but I don't often need to run the debugger with root permissions.

Would be nice if we could specify any debugger name in "launch.config" (currently only gdb and lldb are supported values). This way you could have the normal "gdb" and then a "gdbsudo" which is the bash script you specify. And then you can just switch out between those in "launch.config" when required.

pieandcakes commented 7 years ago

@BlinkFan You can enable "miDebuggerPath" which will override where it is looking for your executable and you can replace it with a script. the "MIMode" is to tell us which behavior to support since lldb and gdb have slightly different behavior.

harmishhk commented 6 years ago

Workaround by @bugraaydogar works, however I still always get the prompt "Superuser access is required to ... ". Is there any way to avoid this prompt and directly start the debug session? Or save my preference 'y' for this prompt on first use and not ask again every time I start a debug session?

antonio-petricca commented 6 years ago

I solved running Code by this alias:

alias Sc='sudo code-insiders --user-data-dir="~/.vscode-root"'

dannyalan commented 5 years ago

@BlinkFan When launching gdb and it needs sudo, it will prompt for sudo today. Can you post your launch.json so I can try and duplicate?

I'm afraid that when running VS Code under the MS SSH extension it attempts to execute gdb using pkexec without adding the --user flag. This then causes the debugging session to stop instead of requesting the user to be selected.

==== AUTHENTICATING FOR org.freedesktop.policykit.exec ===
Authentication is needed to run '/home/danny/dev/tools/gdb' as the super user
Multiple identities can be used for authentication:
 1.  Software Developer,,, (devel)
 2.  Bill,,, (bill)
 3.  Ben,,, (ben)
 4.  flowerpotmen,,, (flowerpotmen)
 5.  Danny Alan,,, (danny)
Choose identity to authenticate as (1-5): [1] + Stopped (tty input)        /usr/bin/pkexec /home/danny/dev/tools/gdb --interpreter=mi --tty=${DbgTerm} 0</tmp/Microsoft-MIEngine-In-gqup3t0x.tz6 1>/tmp/Microsoft-MIEngine-Out-84u1c4vc.nq0
You have stopped jobs.

No further prompts are thrown and instead thew debugger hangs. Debugging C++ using the atatch method in this way is not possible

cnjsdfcy commented 5 years ago

encountered same problem here like @dannyalan under remote-development scene.

cnjsdfcy commented 5 years ago

hi @dannyalan , maybe I have found the solution about pkexec privilege issue under remote-development/debug scenario . Pls try this setting: sudo sysctl -w kernel.yama.ptrace_scope=0

dannyalan commented 5 years ago

hi @dannyalan , maybe I have found the solution about pkexec privilege issue under remote-development/debug scenario . Pls try this setting: sudo sysctl -w kernel.yama.ptrace_scope=0

Thanks @cnjsdfcy, that totally fixed it. This can be closed off as a Linux issue in that case, not a vscode one.

cnjsdfcy commented 5 years ago

@dannyalan , actually I am doing a mixed python/C++ debug under vscode remote-development from windows to Linux, and following the calls from python into C++ are a little inconvenient since I have to stop at python breakpoints first then switch to gdb and attach it to python process, and then stop in gdb again and back to python and continue the python process, and then, I have to switch back to gdb and continue after which I finally can stop at C++ breakpoints. This involves many clicks which I think should be optimized by vscode debug framework.

EmbeddedBacon commented 5 years ago

@cnjsdfcy , I have been searching for a nice method of debugging code similar, though I am using C. I have tried to setup a launch session to start the Python script, which loads up the c shared object (SO). I could never debug the C SO when launching from the Python script. I would have to pause the Python execution, used 'raw_input("Attach to process now")' during a Python init routine, then I could debug the C SO.

I am curious how you start the debug session with Python and then switch to a C debug session. Would you mind sharing how you accomplish that task a bit? Thanks.

Regards, Mark

tdashroy commented 4 years ago

Ran into this when trying to attach to a process running in WSL (distro is Debian Buster), using VSCode started from WSL.

VSCode would prompt with:

❯ sh /tmp/Microsoft-MIEngine-Cmd-u3m7ylsr.vkh 
Superuser access is required to attach to a process. Attaching as superuser can potentially harm your computer. Do you want to continue? [y/N]

and responding with y resulted in:

[1] + Stopped (tty output)       /usr/bin/sudo "/usr/bin/gdb" --interpreter=mi --tty=${DbgTerm} 0<"/tmp/Microsoft-MIEngine-In-4hka9ol1.alg" 1>"/tmp/Microsoft-MIEngine-Out-nywjhpj2.ql2"
You have stopped jobs.

The debugger looked like it was running (still had the little hover UI with the Pause, Restart, and Stop buttons being clickable), however nothing worked (breakpoints, breaking in, etc).

Tried @bugraaydogar's suggestion of using a shell script to run sudo gdb $@. Set that shell script as the "miDebuggerPath", but was still met with the same result as above.

Stepping back and trying to use gdb from the WSL shell to attach to the process, I was met with a similar outcome. gdb -p <pid> gave me the debugger that said it had attached to the process, but it did not think the program was running:

Attaching to process 2695
ptrace: Operation not permitted.
(gdb) info program
The program being debugged is not being run.

However this time using sudo in front of the command did work (sudo gdb -p <pid>) and properly attached to the process.

At this point I noticed the ptrace: Operation not permitted when I used gdb without sudo. Searching around a little led to the same solution @cnjsdfcy mentioned, setting the Yama module ptrace_scope value to 0 (with sudo sysctl -w kernel.yama.ptrace_scope=0) . Doing this, I am now able to attach to a process running in WSL, using VSCode started from WSL.

Having a workaround is great, but it doesn't seem this issue is resolved. The original Superuser access is required to attach to a process prompt from VSCode can still fail without much information as to why. If more information is needed in order to re-open and investigate this further, I'd be happy to provide what I can.

Some additional context for others who might come across this:

From the Yama docs, setting ptrace_scope to 0 will make it so "a process can PTRACE_ATTACH to any other process running under the same uid, as long as it is dumpable". The same docs also mention the risks of doing this.

The sudo sysctl -w kernel.yama.ptrace_scope=0 will change the value of /proc/sys/kernel/yama/ptrace_scope to 0. This only changes the value for the current boot. I haven't been able to figure out how to get this to persist across boots with Debian in WSL. Looks like generally you just need to add a sysctl.d conf file that contains the line kernel.yama.ptrace_scope = 0 (e.g. echo 'kernel.yama.ptrace_scope = 0' | sudo tee /etc/sysctl.d/10-ptrace.conf), but that's not working for me with WSL Debian.

pieandcakes commented 4 years ago

@tdashroy I think the problem we are running into is that different shells across distros behave differently and one solution doesn't work for another.

The ptrace_scope setting to 0 is our recommended way to get around it but will not work for processes running for different uid values, which we have users doing also.

To add another layer of complexity, we are also sending it through VS Code's protocol runInTerminal request as VS Code launches the terminal window now.

Looks like generally you just need to add a sysctl.d conf file that contains the line kernel.yama.ptrace_scope = 0 (e.g. echo 'kernel.yama.ptrace_scope = 0' | sudo tee /etc/sysctl.d/10-ptrace.conf), but that's not working for me with WSL Debian.

Unfortunately I don't know much about Debian in WSL so I can't comment about how to fix it there. Maybe someone on the WSL repo can comment about it?

Spongman commented 4 years ago

i'm running into this error when attaching to a process urnning in a remote WSL session. i get the process picker, then when i pick the process it gives me the Superuser access is required to attach to a process. Attaching as superuser can potentially harm your computer. Do you want to continue? [y/N] prompt, then when i say y it just says:

Error getting authority: Error initializing authority: Could not connect: No such file or directory
[1] + Done(127)                  /usr/bin/pkexec "/usr/bin/gdb" --interpreter=mi --tty=${DbgTerm} 0<"/tmp/Microsoft-MIEngine-In-r0iskkcz.bjh" 1>"/tmp/Microsoft-MIEngine-Out-5be19882.mt8"
user@machine:~/workspace$ 

and then nothing...

dannyalan commented 4 years ago

I can't help but feel that although this issue is brought in by Linux permissions, the VSCode team should be looking at some kind of cleaner interaction. for users in this case. Running scripts up when VsCode should surely just allow the prompting of sudo permissions when needed is somewhat crazy. @pieandcakes, can you shed some light on a more rounded approach to this?

I hit this issue regularly, as do many devs in the dept I work in. I'm a complete advocate of VsCode C++ dev and I am pushing it as much as I can but it's a hard sell when I have to tell devs not always used to Linux to start setting values in proc.

pieandcakes commented 4 years ago

@dannyalan do you have any suggestions on a different approach? The problem with elevation is because of attaching to processes that may/may not be owned by that user id. We already have to pass pipes for stdin/stdout/stderr to allow for terminal (Integrated and external).

The 'cleanest' interaction is to disable all process security but its the least secure. With the channels allowed by us via the command line, I haven't found any other way to get around it, so any suggestions would be welcome and we can investigate.

FYI @WardenGnaw

dannyalan commented 4 years ago

@pieandcakes, could you not anticipate the issue and query the value of ptrace_scope when initialising the extension? If it is expected to cause problems prompt the user to authorise the running of a script that would set ptrace_scope to 0 until the next reboot? You could potentially raise a notification that would drive the behaviour through the command menu maybe? At least it'll be a middle ground to having the user have to identify the issue by googling the problem yet again and eventually finding the magic command to set in their terminal.

It's worth noting that CLion have this in their docs. Maybe even having a similar statement in the extension docs would help too if dev work on this is not accepted. https://www.jetbrains.com/help/clion/attaching-to-local-process.html?gclid=Cj0KCQjwl4v4BRDaARIsAFjATPmIqWcm8LaGntjAuprlsg5ZRXudp90jof16KFBT53jwunZ_JoPbxN0aAi6gEALw_wcB&gclsrc=aw.ds

pieandcakes commented 4 years ago

@WardenGnaw to determine what to do in this situation. We have the error on the VS side today.

lucascoelhof commented 4 years ago

As an additional information, I have here Ubuntu 18.04 WSL, and I ran the suggested command on WSL (sudo sysctl -w kernel.yama.ptrace_scope=0) and I did not get the prompt. However, the debugger did not stop at the breakpoints. When I tried to stop the process, I've got this error popup:

Unable to open 'nanosleep.c': Unable to read file 'vscode-remote://wsl+ubuntu-18.04/build/glibc-2ORdQG/glibc-2.27/sysdeps/unix/sysv/linux/nanosleep.c' (Error: Unable to resolve non-existing file 'vscode-remote://wsl+ubuntu-18.04/build/glibc-2ORdQG/glibc-2.27/sysdeps/unix/sysv/linux/nanosleep.c').

A button named "Create File" also appears on this error popup, but when I click on it, another error appears.

Unable to write file 'vscode-remote://wsl+ubuntu-18.04/build/glibc-2ORdQG/glibc-2.27/sysdeps/unix/sysv/linux/nanosleep.c' (NoPermissions (FileSystemError): Error: EACCES: permission denied, mkdir '/build')

I tried installing libc source code but it did not work. The "nanosleep.c" file can be found in my WSL at /usr/src/glibc/glibc-2.27/sysdeps/unix/sysv/linux/nanosleep.c

I then created a folder on / with the name build, and gave permission to my user to access and modify it. Then, VS Code created a empty file called nanosleep.c. The image below shows the folders created and the empty file: image It still did not stop at the breakpoints.

Hope that this will help solving the problem.

WardenGnaw commented 4 years ago

@dannyalan I have a pending PR to update the docs: https://github.com/microsoft/vscode-docs/pull/3844/files

You could potentially raise a notification that would drive the behaviour through the command menu maybe?

I'll take a look where we add this notification.

@lucascoelhof The nanosleep.c issue is due to https://github.com/microsoft/vscode-cpptools/issues/5637#issuecomment-655338280. You can use sourceFileMap to point it to glibc sources. Are you also attaching to launching a program to WSL?

Sneirox commented 3 years ago

How to launch my app from vc in sudo mode ???????

icehong commented 3 years ago

Got the same issue with Remote-WSL plugin.

image

$ cat /proc/version Linux version 5.4.72-microsoft-standard-WSL2 (oe-user@oe-host) (gcc version 8.2.0 (GCC)) #1 SMP Wed Oct 28 23:40:43 UTC 2020 $ lsb_release -d Description: Ubuntu 20.04.2 LTS $ cat /proc/sys/kernel/yama/ptrace_scope cat: /proc/sys/kernel/yama/ptrace_scope: No such file or directory $ sudo sysctl -w kernel.yama.ptrace_scope=0 sysctl: cannot stat /proc/sys/kernel/yama/ptrace_scope: No such file or directory $

"version": "0.2.0",
"configurations": [
    {
        "name": "(gdb) Attach",
        "type": "cppdbg",
        "request": "attach",
        "program": "/usr/lib/postgresql/13/bin/postgres",
        "processId": "${command:pickProcess}",
        "MIMode": "gdb",
        "setupCommands": [
            {
                "description": "Enable pretty-printing for gdb",
                "text": "-enable-pretty-printing",
                "ignoreFailures": true
            }
        ]
    },
ashesman commented 2 years ago

+1 for me to be able to run gdb with sudo from vs code launch.

An easy solution would be to make "sudo": true in launch.json work for other languages as it does for python.

szcnshow commented 2 years ago

I enabled the root account and login SSH with root

justdoGIT commented 2 years ago

Hi guys,

As a workaround, you can decorate existing gdb binary with a bash script and then use it. Steps are,

  • cd /usr/bin
  • sudo mv gdb gdborig

Now you need to create a bash script named gdb with following content.

  • sudo vim gdb

Content of the bash is; #!/bin/sh sudo gdborig $@

Finally, make the script runnable. sudo chmod 0755 gdb

Then you should be OK.

Hi,

I tried to create the script as mentioned above but for this script as well, I got the same error as before:

Authentication is needed to run `/home/kk/workspace/multimedia-server/.vscode/gdb' as the super user
Authenticating as: kk,,, (kk)
Password: [1] + Stopped (tty output)       /usr/bin/pkexec "/home/kk/workspace/multimedia-server/.vscode/gdb" --interpreter=mi --tty=${DbgTerm} 0<"/tmp/Microsoft-MIEngine-In-kat1enyd.c4d" 1>"/tmp/Microsoft-MIEngine-Out-sxbiilqy.ble"
You have stopped jobs.

I was not able to provide my sudo password due to external terminal switch , I guess ? Also, I am using gdb attach to attach to the pid of the process. Previously, I tried debugging using gdb launch but then my program code is creating a fork() of itself and then exiting itself. Meanwhile, the child process with the same pid of parent, calls setsid() immediately after the main process gets exited to have the same process group IDs as the process ID. Due to this behavior gdb launch is exiting at a point where starting process exits. Hence, I switched to gdb attach. If anyone knows a workaround for the above problem, please let me know.

Also, to mention, I did not change the name of my original gdb but I used miDebuggerPath to pass the gdb script with sudo privilege. in launch.json . Now, the only two options left are : Either use the command mentioned below which has already been discussed in the thread and has its own security issues:

$  sudo sysctl -w kernel.yama.ptrace_scope=0

or run vscode in privileged mode which is also not expected normally. I am sharing my launch.json file for better inputs and suggestions. Here I have used "Tasks Shell Input" extension to get the pid of the target process and pass it as a key : value pair in launch.json

{
    "configurations": 
    [
        {
            "name": "(gdb) Attach",
            "type": "cppdbg",
            "request": "attach",
            "program": "${workspaceFolder}/source/multimedia-serv",
            "processId": "${input:processID}",
            "miDebuggerPath": "${workspaceFolder}/.vscode/gdb",
            "MIMode": "gdb",
            "setupCommands": 
            [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description":  "Set Disassembly Flavor to Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ]
        }
    ],
    "inputs":
    [
        {
            "id": "processID",
            "type": "command",
            "command": "shellCommand.execute",
            "args": 
            {
                "command": "pgrep multimedia-serv",
                "useFirstResult": true
            }
        }
    ]
}

Waiting for the inputs.

qiangyi1989 commented 2 years ago

When I was debugging C / C + + program, I encountered a similar problem.

Superuser access is required to attach to a process. Attaching as superuser can potentially harm your computer. Do you want to continue? [y/N]

==== AUTHENTICATING FOR org.freedesktop.policykit.exec === Authentication is needed to run `/usr/bin/gdb' as the super user Authenticating as: narwhal,,, (narwhal) Password: [1] + Stopped (tty output) /usr/bin/pkexec "/usr/bin/gdb" --interpreter=mi --tty=${DbgTerm} 0<"/tmp/Microsoft-MIEngine-In-jq3xeuls.opj" 1>"/tmp/Microsoft-MIEngine-Out-cqs0ub2g.t9b" You have stopped jobs.

Almost the same as the following question.

It provides a solution. It works for me.

https://github.com/microsoft/vscode-remote-release/issues/2053

I tried this method before, but it didn't work for me.

Tried @bugraaydogar's suggestion of using a shell script to run sudo gdb $@. Set that shell script as the "miDebuggerPath", but was still met with the same result as above.

rhklite commented 2 years ago

hi @dannyalan , maybe I have found the solution about pkexec privilege issue under remote-development/debug scenario . Pls try this setting: sudo sysctl -w kernel.yama.ptrace_scope=0

This work!

I had to set this parameter in the host machine, not the container. For me, the container would not allow this setting change as it shared the kernel with the host machine, and the container did not have privilege to change that.

BenYao21 commented 1 year ago

Hi guys,

As a workaround, you can decorate existing gdb binary with a bash script and then use it. Steps are,

  • cd /usr/bin
  • sudo mv gdb gdborig

Now you need to create a bash script named gdb with following content.

  • sudo vim gdb

Content of the bash is; #!/bin/sh sudo gdborig $@

Finally, make the script runnable. sudo chmod 0755 gdb

Then you should be OK.

Hey dude,

I found your solution working. But it seems that I need to add password to enable sudo mode. I am not familiar with bash. How to edit this script to enable it?

rustyx commented 7 months ago

In case you're debugging inside Docker, use docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined flags.