cifsd-team / ksmbd

ksmbd kernel server(SMB/CIFS server)
156 stars 23 forks source link

"Bad file descriptor" / "no right to write" when creating git commits from Windows client #616

Closed rawhide-kobayashi closed 1 month ago

rawhide-kobayashi commented 1 month ago

Hello, I'm encountering a consistent issue that exists in ksmbd but not in smb with an otherwise identical configuration and filesystem permissions.

ksmbd-tools version: 3.5.2 ksmbd version: 3.5.0 kernel version: Arch Linux 6.6.47-1-lts

Whenever I try to create a git commit in a directory shared by ksmbd, I get this error on git cli:

fatal: cannot update the ref 'HEAD': unable to append to '.git/logs/HEAD': Bad file descriptor

And here is a relevant snippet from ksmbd log.

[16741.388307] ksmbd: file does not exist, so creating
[16741.388309] ksmbd: creating directory
[16741.388531] ksmbd: get query on disk id context
[16741.388536] ksmbd: credits: requested[1] granted[1] total_granted[134]
[16741.388687] ksmbd: RFC1002 header 88 bytes
[16741.388698] ksmbd: SMB2 len 88
[16741.388701] ksmbd: volatile_id = 186
[16741.388706] ksmbd: credits: requested[1] granted[1] total_granted[134]
[16741.388922] ksmbd: RFC1002 header 264 bytes
[16741.388930] ksmbd: SMB2 data length 104 offset 160
[16741.388932] ksmbd: SMB2 len 264
[16741.388938] ksmbd: converted name = test/.git/logs/HEAD
[16741.388941] ksmbd: get query maximal access context
[16741.392307] ksmbd: can not get linux path for test/.git/logs/HEAD, rc = -2
[16741.392313] ksmbd: file does not exist, so creating
[16741.392315] ksmbd: creating regular file
[16741.392489] ksmbd: get query on disk id context
[16741.392494] ksmbd: credits: requested[1] granted[1] total_granted[134]
[16741.392621] ksmbd: RFC1002 header 104 bytes
[16741.392636] ksmbd: SMB2 data length 0 offset 104
[16741.392640] ksmbd: SMB2 len 105
[16741.392643] ksmbd: GOT query info request
[16741.392645] ksmbd: GOT SMB2_O_INFO_FILE
[16741.392650] ksmbd: credits: requested[1] granted[1] total_granted[134]
[16741.392715] ksmbd: RFC1002 header 104 bytes
[16741.392722] ksmbd: SMB2 data length 0 offset 104
[16741.392724] ksmbd: SMB2 len 105
[16741.392726] ksmbd: GOT query info request
[16741.392728] ksmbd: GOT SMB2_O_INFO_FILE
[16741.392730] ksmbd: credits: requested[1] granted[1] total_granted[134]
[16741.392786] ksmbd: RFC1002 header 104 bytes
[16741.392792] ksmbd: SMB2 data length 0 offset 104
[16741.392794] ksmbd: SMB2 len 105
[16741.392796] ksmbd: GOT query info request
[16741.392797] ksmbd: GOT SMB2_O_INFO_FILE
[16741.392800] ksmbd: credits: requested[1] granted[1] total_granted[134]
[16741.392880] ksmbd: RFC1002 header 285 bytes
[16741.392886] ksmbd: SMB2 data length 173 offset 112
[16741.392889] ksmbd: SMB2 len 285
[16741.392891] ksmbd: flags 0
[16741.392893] ksmbd: filename HEAD, offset 0, len 173
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
[16741.392897] ksmbd: no right to write(HEAD)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[16741.392899] ksmbd: Failed to process 9 [-13]
[16741.392902] ksmbd: credits: requested[1] granted[1] total_granted[134]
[16741.392980] ksmbd: RFC1002 header 104 bytes
[16741.392986] ksmbd: SMB2 data length 0 offset 104
[16741.392988] ksmbd: SMB2 len 105
[16741.392990] ksmbd: GOT query info request
[16741.392991] ksmbd: GOT SMB2_O_INFO_FILE
[16741.392993] ksmbd: credits: requested[1] granted[1] total_granted[134]
[16741.393061] ksmbd: RFC1002 header 88 bytes
[16741.393068] ksmbd: SMB2 len 88
[16741.393070] ksmbd: volatile_id = 187
[16741.393074] ksmbd: credits: requested[1] granted[1] total_granted[134]
[16741.393220] ksmbd: RFC1002 header 264 bytes
[16741.393229] ksmbd: SMB2 data length 104 offset 160
[16741.393231] ksmbd: SMB2 len 264
[16741.393235] ksmbd: converted name = test/.git/HEAD.lock
[16741.393239] ksmbd: get query maximal access context
[16741.393246] ksmbd: check permission using windows acl
[16741.393261] ksmbd: get query on disk id context
[16741.393265] ksmbd: credits: requested[1] granted[1] total_granted[134]
[16741.393415] ksmbd: RFC1002 header 192 bytes
[16741.393422] ksmbd: SMB2 data length 48 offset 144
[16741.393425] ksmbd: SMB2 len 192
[16741.393427] ksmbd: converted name = test/.git
[16741.393430] ksmbd: get query maximal access context
[16741.393435] ksmbd: check permission using windows acl
[16741.393447] ksmbd: get query on disk id context
[16741.393451] ksmbd: credits: requested[1] granted[1] total_granted[134]

Here is my ksmbd.conf.

[global]
    server max protocol = SMB3_11
    server min protocol = SMB3_11
    server multi channel support = yes
    bind interfaces only = yes
    interfaces = mac0 eno1

[NAS]
    path = /mnt/NAS
    read only = no
    writeable = yes
    browseable = no
    valid users = knowledge

[Scratch]
    path = /mnt/scratch
    read only = no
    writeable = yes
    browseable = no
    valid users = knowledge

Here is a sample log to replicate my issue from Git CMD on Windows.

Z:\>mkdir test

Z:\>cd test

Z:\test>git init
Initialized empty Git repository in //192.168.10.168/NAS/test/.git/

Z:\test>echo "test" > example.txt

Z:\test>git add example.txt

Z:\test>git commit -m "test"
fatal: cannot update the ref 'HEAD': unable to append to '.git/logs/HEAD': Bad file descriptor

Btw, I can append >> a file just fine via windows cmd. It doesn't error out. I've only encountered a problem with git so far.

rawhide-kobayashi commented 1 month ago

what in the blatantly obvious spambot

namjaejeon commented 1 month ago

Can you check two things ?

  1. please give me wireshark dump file that captured packets on problem situation.
  2. can you check same test against samba ?
rawhide-kobayashi commented 1 month ago

Here are two wireshark logs, for the git commit command as shown in the demo above - one showing the failing transaction with ksmbd, and another showing a successful transaction with samba.

wireshark_cap.zip

namjaejeon commented 1 month ago

What ksmbd are you using ? github-ksmbd or ksmbd in linux kernel ? I would like to give the patch to you to check if problem is fixed or not.

namjaejeon commented 1 month ago

Can you check if your problem is fixed ?

From 910ddff523b59ae9e96af6adb1012da302861f10 Mon Sep 17 00:00:00 2001
From: Namjae Jeon <linkinjeon@kernel.org>
Date: Thu, 29 Aug 2024 08:45:01 +0900
Subject: [PATCH 1/3] ksmbd: allow write with FILE_APPEND_DATA

Windows client write with FILE_APPEND_DATA when using git.
ksmbd should allow write it with this flags.

Z:\test>git commit -m "test"
fatal: cannot update the ref 'HEAD': unable to append to '.git/logs/HEAD': Bad file descriptor

Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
---
 vfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/vfs.c b/vfs.c
index e415211..4428013 100644
--- a/vfs.c
+++ b/vfs.c
@@ -770,7 +770,7 @@ int ksmbd_vfs_write(struct ksmbd_work *work, struct ksmbd_file *fp,
    int err = 0;

    if (work->conn->connection_type) {
-       if (!(fp->daccess & FILE_WRITE_DATA_LE)) {
+       if (!(fp->daccess & (FILE_WRITE_DATA_LE | FILE_APPEND_DATA_LE))) {
            pr_err("no right to write(%pD)\n", fp->filp);
            err = -EACCES;
            goto out;
-- 
2.25.1
rawhide-kobayashi commented 1 month ago

Sorry for the delay, I'll be able to test it on Saturday.

rawhide-kobayashi commented 1 month ago

I built from https://github.com/namjaejeon/ksmbd/commit/910ddff523b59ae9e96af6adb1012da302861f10 and it works!

Z:\test2>git commit -m "test"
[master (root-commit) be059e4] test
 1 file changed, 1 insertion(+)
 create mode 100644 example.txt

Tysm!

namjaejeon commented 1 month ago

@rawhide-kobayashi Thanks for your confirmation!