Skip to content

Error creating/writing public key file on network drive "Bad file descriptor" -- tested on 9.5.0.0 and 9.8.1.0 #2298

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
3 tasks done
Saxomania opened this issue Nov 7, 2024 · 3 comments · Fixed by PowerShell/openssh-portable#764
Assignees
Milestone

Comments

@Saxomania
Copy link

Prerequisites

  • Write a descriptive title.
  • Make sure you are able to repro it on the latest version
  • Search the existing issues.

Steps to reproduce

Windows: creating pub/priv key file works on default folder (if you dont enter any path) and for example on D drive (just a local volume) will work but will not work on a mapped network share.

Write rights are there so this should not be problem otherwise it couldnt write into my userprofile folder as well

Expected behavior

ssh-keygen -t ed25519 -C "Test"
Generating public/private ed25519 key pair.
Enter file in which to save the key (C:\Users\username/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\Users\username/.ssh/id_ed25519
Your public key has been saved in C:\Users\username/.ssh/id_ed25519.pub

Actual behavior

ssh-keygen -t ed25519 -C "Test"
Generating public/private ed25519 key pair.
Enter file in which to save the key (C:\Users\username/.ssh/id_ed25519): Q:\documents\key
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in q:\documents\key
Unable to save public key to Q:\\documents\\key.pub: Bad file descriptor

Error details

Q is my mapped home drive on a network share
Documents is a folder inside it and its accessible 

an extract of "set" shows following variables:

HOMEDRIVE=Q:
HOMEPATH=\
HOMESHARE=\\server.domain.de\share\somefoldername\username

Environment data

PS Q:\> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.19041.5007
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.19041.5007
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Version

9.8.1.0

Visuals

No response

@mgkuhn
Copy link

mgkuhn commented Nov 8, 2024

I can reproduce this.

Creates and leaves an empty key.pub file on the intended network folder.

I suspect the problem is that this fdopen() call fails if path is on a network drive:

        int fd, oerrno;
        FILE *f = NULL;
        int r = SSH_ERR_INTERNAL_ERROR;

        if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
                return SSH_ERR_SYSTEM_ERROR;
        if ((f = fdopen(fd, "w")) == NULL) {
                r = SSH_ERR_SYSTEM_ERROR;
                close(fd);
                goto fail;
        }

May be too much paranoid Unix-specific file-opening trickery for Windows libc to handle on a network drive?

@mgkuhn
Copy link

mgkuhn commented Nov 8, 2024

It looks like this has previously been noted elsewhere, judging from e.g. this comment in auth2-pubkeyfile.c:

#ifdef WINDOWS
        /* Windows POSIX adapter does not support fdopen() on open(file)*/
        if ((f = fopen(file, "r")) == NULL) {
[...]
#else  /* !WINDOWS */
        if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) {

I guess the thing to do is to review all uses of fdopen() after open(), and then introduce a proper abstraction for what they actually try to achieve.

@mgkuhn
Copy link

mgkuhn commented Nov 8, 2024

I don't really understand why upstream isn't simply using

        if ((f = fopen(fd, "w")) == NULL)
                return SSH_ERR_SYSTEM_ERROR;

here.

It's not about the flags bits, because according to the Linux fopen() man page and the POSIX standard:

The file descriptor associated with the stream is opened as if by a call to open(2) with the following flags:
| w │ O_WRONLY | O_CREAT | O_TRUNC |

I suspect this is merely done to mask out u+x,go+wx permissions.

@StevenBucher98 StevenBucher98 added this to the vNext milestone Nov 11, 2024
@tgauth tgauth added 2 - In progress Implementation is underway and removed 0 - Backlog labels Nov 15, 2024
@tgauth tgauth added 3 - In Review Implementation complete and removed 2 - In progress Implementation is underway labels Nov 15, 2024
@tgauth tgauth removed the 3 - In Review Implementation complete label Dec 10, 2024
@tgauth tgauth modified the milestones: vNext, V9.8.2.0 Apr 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants