Skip to content
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

FUSE ioctl returns error even if returning 0 from ioctl handler #213

Closed
felfert opened this issue Feb 12, 2019 · 0 comments
Closed

FUSE ioctl returns error even if returning 0 from ioctl handler #213

felfert opened this issue Feb 12, 2019 · 0 comments

Comments

@felfert
Copy link
Contributor

felfert commented Feb 12, 2019

Bug Report

I am currently implementing ioctl functionality in a proprietary fuse driver.
My ioctl_handler gets called and works as expected, however despite returning 0
from the ioctl handler, the calling DeviceIoControl(...) always returns false with
GetLastError() returning 1 (Incorrect function)

How to Reproduce

  • I prepared a modified passthrough-fuse, adding a similar ROT13 ioctl like
    in memfs. This is available here:
    passthrough-fuse.c
  • I also wrote a small client program for manual testing:
#include <windows.h>
#include <string>
#include <iostream>

#define FSP_FUSE_DEVICE_TYPE            (0x8000 | 'W' | 'F' * 0x100) /* DeviceIoControl -> ioctl */
#define FSP_FUSE_CTLCODE_FROM_IOCTL(cmd) \
    (FSP_FUSE_DEVICE_TYPE << 16) | (((cmd) & 0x0fff) << 2)

using namespace std;

static string emsg(DWORD ecode) {
    LPVOID lpMsgBuf = 0;
    if (0 == ::FormatMessageA(
            FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL, ecode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&lpMsgBuf, 0, NULL)) {
        return string("Unknown error");
    }
    string ret(static_cast<LPCSTR>(lpMsgBuf));
    ::LocalFree(lpMsgBuf);
    while (ret.size() && (ret[ret.size()-1] == '\n' || ret[ret.size()-1] == '\r')) {
        ret.erase(ret.size()-1);
    }
    if (ret.size() && ret[ret.size()-1] == '.') {
        ret.erase(ret.size()-1);
    }
    return ret;
}

int main(int argc, char **argv) {
    if (argc < 3) {
        cerr << "Usage: bioctl <fuse|memfs> <path>" << endl;
        return 1;
    }
	if (strcmp("fuse", argv[1]) && strcmp("memfs", argv[1])) {
		cerr << "FS-type must be fuse or memfs" << endl;
		return 1;
	}
    HANDLE h = ::CreateFileA(argv[2], GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING,
            FILE_FLAG_BACKUP_SEMANTICS, 0);
    if (INVALID_HANDLE_VALUE == h) {
        cerr << "CreateFileA(" << argv[2] << ") returned an invalid handle" << endl;
        return 1;
    }
	CHAR Buffer[26];
    DWORD BytesTransferred = 0;
	DWORD ccode;
	if (strcmp("fuse", argv[1])) {
		ccode = CTL_CODE(0x8000 + 'M', 'R', METHOD_BUFFERED, FILE_ANY_ACCESS);
	} else {
		ccode = FSP_FUSE_CTLCODE_FROM_IOCTL('f');
	}
    cout << "calling DeviceIoControl with code=0x" << hex << ccode << endl;
    if (!::DeviceIoControl(h, ccode, (LPVOID)"ABCDEFghijklmNOPQRStuvwxyz", 26,
                Buffer, sizeof(Buffer), &BytesTransferred, 0)) {
        DWORD err = GetLastError();
        cerr << "DeviceIoControl failed: " << emsg(err) << " (0x" << err << ")" << endl;
        return 1;
    }
    CloseHandle(h);
    if (BytesTransferred != 26) {
        cerr << "BytesTransferred != 26 (" << BytesTransferred << ")" << endl;
    }
    if (memcmp("NOPQRStuvwxyzABCDEFghijklm", Buffer, 26)) {
        cerr << "Buffer did not contain \"NOPQRStuvwxyzABCDEFghijklm\"" << endl;
    }
    return 0;
}
  • To demonstrate the bug, first run the modified passthrough-fuse.exe, then invoke
    the above program like this
.\bioctl.exe fuse <SomePathBelowTheFuseMountedDrive> 

Behaviors

The above program will print

calling DeviceIoControl with code=0xc6570198
DeviceIoControl failed: Incorrect function (0x1)

Environment

  • OS version and build:
    Output of diag.bat attached:
    diag.bat.log

  • WinFsp version and build:
    1.4.19016

billziss-gh added a commit that referenced this issue Feb 12, 2019
Fix #213 and a typo in macro FSP_FUSE_CTLCODE_FROM_IOCTL
Noire001 pushed a commit to Noire001/winfsp that referenced this issue Sep 25, 2022
Noire001 pushed a commit to Noire001/winfsp that referenced this issue Sep 25, 2022
Fix winfsp#213 and a typo in macro FSP_FUSE_CTLCODE_FROM_IOCTL
Noire001 pushed a commit to Noire001/winfsp that referenced this issue Sep 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant