{"thread":{"id":"63849","subject":"[BUG?] git-daemon 2.49.0 in F40 no longer exports user directories","startedAt":"2025-07-25T16:11:11Z","lastAt":"2025-07-27T09:14:56Z","messageCount":5,"participants":["Russell King (Oracle)","Jeff King","Todd Zullinger"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"522754","messageId":"aIOslkzu-x8K9o_C@shell.armlinux.org.uk","threadId":"63849","inReplyTo":null,"subject":"[BUG?] git-daemon 2.49.0 in F40 no longer exports user directories","fromName":"Russell King (Oracle)","fromEmail":"linux@armlinux.org.uk","sentAt":"2025-07-25T16:11:02Z","receivedAt":"2025-07-25T16:11:11Z","isPatch":false,"sender":{"key":"linux@armlinux.org.uk","avatar":null},"body":"Hi,\n\nWhile I've been away on holiday over the last three weeks, my co-admin\nupdated ZenIV to Fedora 40, and now I find that git-daemon no longer\nexports my \"public_git\" directory. My attempts at debugging this have\nfailed - I tried adding strace to the git@.service but I get nothing.\nThis is a regression.\n\nHaving spent quite a while trying to get to the bottom of this and\nfailing, I'm reaching out for some help - especially given the\nproximity of the kernel merge window opening this weekend.\n\nThe log indicates:\n\nJul 25 16:56:55 ZenIV git-daemon[4046439]: [4046439] Extended attribute \"host\": git.armlinux.org.uk\nJul 25 16:56:55 ZenIV git-daemon[4046439]: [4046439] Extended attribute \"protocol\": version=2\nJul 25 16:56:55 ZenIV git-daemon[4046439]: [4046439] Request upload-pack for '~rmk/linux-arm.git/'\nJul 25 16:56:55 ZenIV git-daemon[4046439]: [4046439] userpath <public_git>, request <~rmk/linux-arm.git/>, namlen 4, restlen 15, slash </linux-arm.git/>\nJul 25 16:56:55 ZenIV git-daemon[4046439]: [4046439] '~rmk/public_git/linux-arm.git': not in directory list\n\nIt seems to detect that it's a user path, and adds the \"public_git\"\n--user-path to it, but it seems to fail to translate ~rmk into\n/home/rmk.\n\n/etc/gitconfig contains:\n\n[safe]\n        directory = /var/lib/git/git.armlinux.org.uk/*\n        directory = /home/rmk/public_git/*\n\nand /lib/systemd/system/git@.service contains:\n\n[Unit]\nDescription=Git Repositories Server Daemon\nDocumentation=man:git-daemon(1)\n\n[Service]\nUser=nobody\nExecStart=-/usr/libexec/git-core/git-daemon --base-path=/var/lib/git --export-all \\\n          --user-path=public_git --inetd --log-destination=stderr --verbose\nStandardInput=socket\nStandardError=journal\n\nAny ideas what is necessary to fix it?\n\nThanks.\n\n-- \nRMK's Patch system: https://www.armlinux.org.uk/developer/patches/\nFTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!\n"},{"id":"522784","messageId":"20250726075136.GA3032762@coredump.intra.peff.net","threadId":"63849","inReplyTo":"aIOslkzu-x8K9o_C@shell.armlinux.org.uk","subject":"Re: [BUG?] git-daemon 2.49.0 in F40 no longer exports user directories","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2025-07-26T07:51:36Z","receivedAt":"2025-07-26T07:51:46Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Jul 25, 2025 at 05:11:02PM +0100, Russell King (Oracle) wrote:\n\n> While I've been away on holiday over the last three weeks, my co-admin\n> updated ZenIV to Fedora 40, and now I find that git-daemon no longer\n> exports my \"public_git\" directory. My attempts at debugging this have\n> failed - I tried adding strace to the git@.service but I get nothing.\n> This is a regression.\n\nI'm not aware of anything changing here recently, and ~user expansion\ndoes seem to work for me. E.g. using v2.49.0 and running:\n\n  git daemon --base-path=/tmp/foo --export-all --user-path=public_git \\\n\t--verbose --log-destination=stderr\n\nand then running:\n\n  mkdir ~peff/public_git\n  git init --bare ~peff/public_git/repo.git\n  git -C ~peff/public_git/repo.git --work-tree=. commit --allow-empty -m foo\n\n  git ls-remote git://localhost/~peff/repo.git\n\nworks. I get a similar log message to you here:\n\n> Jul 25 16:56:55 ZenIV git-daemon[4046439]: [4046439] userpath <public_git>, request <~rmk/linux-arm.git/>, namlen 4, restlen 15, slash </linux-arm.git/>\n\nThat is, even though we print ~peff (or ~rmk), I think we still look for\nrepos in /home/peff. E.g., if I strace and substitute \"none.git\" (to\nmake the trace smaller, since we won't find a repo), I see it looking\nat:\n\n  \n  newfstatat(AT_FDCWD, \"/home/peff/public_git/none.git/.git\", 0x7ffc1cf9c8d0, 0) = -1 ENOENT (No such file or directory)\n  newfstatat(AT_FDCWD, \"/home/peff/public_git/none.git\", 0x7ffc1cf9c8d0, 0) = -1 ENOENT (No such file or directory)\n  newfstatat(AT_FDCWD, \"/home/peff/public_git/none.git.git/.git\", 0x7ffc1cf9c8d0, 0) = -1 ENOENT (No such file or directory)\n  newfstatat(AT_FDCWD, \"/home/peff/public_git/none.git.git\", 0x7ffc1cf9c8d0, 0) = -1 ENOENT (No such file or directory)\n\nIf you strace, do you see similar stat calls?\n\n\nBut of course I don't get this log line:\n\n> Jul 25 16:56:55 ZenIV git-daemon[4046439]: [4046439] '~rmk/public_git/linux-arm.git': not in directory list\n\nwhich isn't too surprising since things succeed for me. But the \"not in\ndirectory list\" part is interesting. If we could not find the repo on\ndisk, we get something more like:\n\n  '~peff/public_git/none.git' does not appear to be a git repository\n\nLooking through daemon.c:path_ok(), if we see the user-path expansion\nbut not \"does not appear to be a git repository\", then we're getting\nhung up on this code:\n\n          if ( ok_paths && *ok_paths ) {\n                  const char **pp;\n                  int pathlen = strlen(path);\n  \n                  /* The validation is done on the paths after enter_repo\n                   * appends optional {.git,.git/.git} and friends, but\n                   * it does not use getcwd().  So if your /pub is\n                   * a symlink to /mnt/pub, you can include /pub and\n                   * do not have to say /mnt/pub.\n                   * Do not say /pub/.\n                   */\n                  for ( pp = ok_paths ; *pp ; pp++ ) {\n                          int len = strlen(*pp);\n                          if (len <= pathlen &&\n                              !memcmp(*pp, path, len) &&\n                              (path[len] == '\\0' ||\n                               (!strict_paths && path[len] == '/')))\n                                  return path;\n                  }\n          }\n          else {\n                  /* be backwards compatible */\n                  if (!strict_paths)\n                          return path;\n          }\n\nMy command line does not set --strict-paths, and neither does yours. So\npresumably you are stuck on the ok_paths. But those come from non-option\npaths on the git-daemon command line. My invocation does not pass any,\nand from what you wrote here:\n\n> and /lib/systemd/system/git@.service contains:\n> \n> [Unit]\n> Description=Git Repositories Server Daemon\n> Documentation=man:git-daemon(1)\n> \n> [Service]\n> User=nobody\n> ExecStart=-/usr/libexec/git-core/git-daemon --base-path=/var/lib/git --export-all \\\n>           --user-path=public_git --inetd --log-destination=stderr --verbose\n> StandardInput=socket\n> StandardError=journal\n\nneither do you. Is it possible that when invoking git-daemon, systemd is\nadding more arguments? Can you check with systemd logs or via strace (or\nmaybe even ps, though I guess the process is short-lived in inetd mode)?\n\nI'm not very familiar with systemd, but IIRC @-services are just\ntemplates that expect an argument. And in this case the argument is\nfilled in when the git.socket service runs the git@ unit for a single\nconnection. But I think that argument is only expanded by a\n%-placeholder, not shoved onto the ExecStart line.\n\nSo I dunno. I am just guessing at the systemd connection.  But it seems\nlike somehow an extra argument is ending up in your git-daemon\ninvocation.\n\n-Peff\n\nPS My invocation above is obviously not running in --inetd mode like\n   yours is, but I don't think that's the culprit. If I put this into\n   /tmp/proxy:\n\n     #!/bin/sh\n     exec git daemon --base-path=/tmp/foo --export-all --inetd \\\n\t--user-path=public_git --log-destination=stderr --verbose\n\n  and then invoke it directly:\n\n    git -c core.gitproxy=/tmp/proxy ls-remote git://localhost/~peff/repo.git\n\n  it works the same.\n\n  I also tried taking the FC40 git@.service and git.socket files and\n  sticking them in my systemd setup, and it also seems to work. So I am\n  all out of guesses.\n"},{"id":"522791","messageId":"aITd13mTx8t1dQbO@teonanacatl.net","threadId":"63849","inReplyTo":"20250726075136.GA3032762@coredump.intra.peff.net","subject":"Re: [BUG?] git-daemon 2.49.0 in F40 no longer exports user directories","fromName":"Todd Zullinger","fromEmail":"tmz@pobox.com","sentAt":"2025-07-26T13:53:27Z","receivedAt":"2025-07-26T13:53:30Z","isPatch":false,"sender":{"key":"tmz@pobox.com","avatar":"https://avatars.githubusercontent.com/u/806319?v=4"},"body":"Jeff King wrote:\n> On Fri, Jul 25, 2025 at 05:11:02PM +0100, Russell King (Oracle) wrote:\n> \n>> While I've been away on holiday over the last three weeks, my co-admin\n>> updated ZenIV to Fedora 40, and now I find that git-daemon no longer\n\nWhile this isn't relevant to the issue, it seems worth\nnoting that Fedora 40 went EOL a couple of months ago, so it\nno longer receives any security updates.  That's not ideal\nif this system is not entirely internal. :)\n\n>> exports my \"public_git\" directory. My attempts at debugging this have\n>> failed - I tried adding strace to the git@.service but I get nothing.\n>> This is a regression.\n> \n> I'm not aware of anything changing here recently, and ~user expansion\n> does seem to work for me. E.g. using v2.49.0 and running:\n> \n>   git daemon --base-path=/tmp/foo --export-all --user-path=public_git \\\n> \t--verbose --log-destination=stderr\n> \n> and then running:\n> \n>   mkdir ~peff/public_git\n>   git init --bare ~peff/public_git/repo.git\n>   git -C ~peff/public_git/repo.git --work-tree=. commit --allow-empty -m foo\n> \n>   git ls-remote git://localhost/~peff/repo.git\n> \n> works. I get a similar log message to you here:\n\nI was curious, so I took Peff's recipe and gave it a try. \n\n    sudo dnf -y install git-daemon\n    sudo systemctl enable --now git.socket\n    mkdir ~/public_git\n    git init --bare ~/public_git/repo.git\n    git -C ~/public_git/repo.git --work-tree=. commit --allow-empty -m foo\n    sudo git config --system --add safe.directory ~/public_git/\\*\n    git ls-remote git://localhost/~test/repo.git\n\nAnd that fails as it does for Russell.  I suspected SELinux,\nwhich is enabled by default on Fedora.  With luck, you have\nnot already ruled that out.\n\nTwo things were needed with respect to SELinux and one other\nfor basic permissions.\n\nFirst, ensure the permissions on the home directory allow\naccess by others, as git-daemon will be running as nobody.\nBy default ~/ isn't searchable by others.  (This isn't\nlikely the trouble in your case, but only because you'd\nprobably changed it well before the OS upgrade.)\n\n    # ensure ~ is searchable; git-daemon runs as nobody\n    chmod -c o=x ~\n\nThe permissions on ~/public_git and the subdirectories were\nalready okay, but if you set a strict umask, it might be\nworth ensuring they're okay (also unlikely for you as this\nworked before an upgrade).\n\nThen ensure the SELinux context type is correct.  It should\nbe git_user_content_t.  You can add -n to the restorecon\ncall to see what it would change.\n\n    # The -F isn't strictly required, I just like setting\n    # the user, role, range portion as well as the type.\n    restorecon -FRv ~/public_git/\n\nThis is close, but still not enough as SELinux doesn't allow\ngit-daemon to search user home directories by default.\nThere is a boolean to enable that so you don't have to\ncreate any custom policy.  But for reference, audit2allow\ntells you just that:\n\n    $ sudo ausearch -ts recent -m AVC | audit2allow\n    [... needless blank lines elided ...]\n    #============= git_system_t ==============\n\n    #!!!! This avc can be allowed using the boolean 'git_system_enable_homedirs'\n    allow git_system_t user_home_dir_t:dir search;\n\nEnable the boolean:\n\n    sudo setsebool -P git_system_enable_homedirs=1\n\nAnd `git ls-remote git://localhost/~test/repo.git` now\nreturns successfully.  It's empty in this case, but I cloned\na repo with content into ~/public_git and confirmed it\nworked as expected.\n\nWith luck, it's SELinux biting you (or, less likely) a\npermission on ~ or ~/public_git and this will help.\n\nIt does seem like the git-daemon package in Fedora could use\na README-SELinux.md which explains this stuff, like the cgit\npackage.  That might have helped you or others in getting\nstarted.\n\n-- \nTodd\n"},{"id":"522822","messageId":"20250727064542.GA3091411@coredump.intra.peff.net","threadId":"63849","inReplyTo":"aITd13mTx8t1dQbO@teonanacatl.net","subject":"Re: [BUG?] git-daemon 2.49.0 in F40 no longer exports user directories","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2025-07-27T06:45:42Z","receivedAt":"2025-07-27T06:45:46Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Jul 26, 2025 at 09:53:27AM -0400, Todd Zullinger wrote:\n\n> I was curious, so I took Peff's recipe and gave it a try. \n> \n>     sudo dnf -y install git-daemon\n>     sudo systemctl enable --now git.socket\n>     mkdir ~/public_git\n>     git init --bare ~/public_git/repo.git\n>     git -C ~/public_git/repo.git --work-tree=. commit --allow-empty -m foo\n>     sudo git config --system --add safe.directory ~/public_git/\\*\n>     git ls-remote git://localhost/~test/repo.git\n> \n> And that fails as it does for Russell.  I suspected SELinux,\n> which is enabled by default on Fedora.  With luck, you have\n> not already ruled that out.\n\nInteresting. That would explain why I didn't see the problem on my\nDebian system.\n\nI am still puzzled why Russell would see the message he does, though.\nFrom my read of the code, seeing \"not in directory list\" but not seeing\n\"...does not appear to be a git repository\" implies that enter_repo()\nsucceeds, but ok_paths is non-empty and forbids it.\n\nProbably not that important if your suggestions here solve his problem.\nBut of course if you can easily satisfy my curiosity by running through\na debugger, I'd be happy. ;)\n\nIt might just be that I'm mis-reading the code.\n\n-Peff\n"},{"id":"522823","messageId":"aIXuCv7hRyJq-Twm@shell.armlinux.org.uk","threadId":"63849","inReplyTo":"20250727064542.GA3091411@coredump.intra.peff.net","subject":"Re: [BUG?] git-daemon 2.49.0 in F40 no longer exports user directories","fromName":"Russell King (Oracle)","fromEmail":"linux@armlinux.org.uk","sentAt":"2025-07-27T09:14:50Z","receivedAt":"2025-07-27T09:14:56Z","isPatch":false,"sender":{"key":"linux@armlinux.org.uk","avatar":null},"body":"On Sun, Jul 27, 2025 at 02:45:42AM -0400, Jeff King wrote:\n> On Sat, Jul 26, 2025 at 09:53:27AM -0400, Todd Zullinger wrote:\n> \n> > I was curious, so I took Peff's recipe and gave it a try. \n> > \n> >     sudo dnf -y install git-daemon\n> >     sudo systemctl enable --now git.socket\n> >     mkdir ~/public_git\n> >     git init --bare ~/public_git/repo.git\n> >     git -C ~/public_git/repo.git --work-tree=. commit --allow-empty -m foo\n> >     sudo git config --system --add safe.directory ~/public_git/\\*\n> >     git ls-remote git://localhost/~test/repo.git\n> > \n> > And that fails as it does for Russell.  I suspected SELinux,\n> > which is enabled by default on Fedora.  With luck, you have\n> > not already ruled that out.\n> \n> Interesting. That would explain why I didn't see the problem on my\n> Debian system.\n> \n> I am still puzzled why Russell would see the message he does, though.\n> From my read of the code, seeing \"not in directory list\" but not seeing\n> \"...does not appear to be a git repository\" implies that enter_repo()\n> succeeds, but ok_paths is non-empty and forbids it.\n\nYes, I had an override in systemd that I'd forgotten about to work\naround a previous issue (because the previous version we had on the\nmachine required the paths on the end of the git-daemon command line.)\n\nI wonder if there was a bug - --export-all broke, and then required the\ndirectories to be listed, and now it's been \"fixed\" and now the listed\ndirectories become a list of those to exclude?\n\nThe override.conf had something like:\n\nExecStart=-/usr/libexec/git-core/git-daemon --export-all \\\n  --user-path=public_git --inetd --log-destination=stderr --verbose \\\n    --interpolated-path='/var/lib/git/%%H%%D' \\\n    /var/lib/git/git.armlinux.org.uk \\\n    /home/rmk/public_git\n\nI can't remember exactly now as I've deleted the last two paths, and\nadded --base-path=/var/lib/git - and now it's working.\n\n-- \nRMK's Patch system: https://www.armlinux.org.uk/developer/patches/\nFTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!\n"}]}