Skip to content

Implement path sanitization (Parent Directory Accessible without Landlock) #48

@areon546

Description

@areon546

Parent directory accessible under certain conditions. I don't know if this is a general issue or just a specific issue with how I set up the daemon. I am not experienced in this package, just tried some stuff for fun.

Running Ubuntu 25.04

Commands used:
localhost: gokr-rsync --daemon --gokr.listen=localhost:8730 --gokr.modulemap=files=/usr/share/asda/rsync/
localhost: rsync -v --archive --port 8730 rsync://localhost/files/../ adsa - standard rsync binary, see below:

user@device:~$ rsync --version 
rsync  version 3.4.1  protocol version 32
Copyright (C) 1996-2025 by Andrew Tridgell, Wayne Davison, and others.
Web site: https://rsync.samba.org/
[...]

Test log:

test@device:~$ gokr-rsync --daemon --gokr.listen=localhost:8730 --gokr.modulemap=files=/usr/share/asda/rsync/
2025/11/06 20:09:39 rsyncos.go:32: Main(osenv=&{0xc000078020 0xc000078028 0xc000078030 false 0xc0000bd230}, args=["gokr-rsync" "--daemon" "--gokr.listen=localhost:8730" "--gokr.modulemap=files=/usr/share/asda/rsync/"])
2025/11/06 20:09:39 rsyncos.go:32: config file not found, relying on flags
2025/11/06 20:09:39 rsyncos.go:32: gokrazy rsync, pid 2912991
2025/11/06 20:09:39 rsyncos.go:32: environment: unprivileged
2025/11/06 20:09:39 rsyncos.go:32: 1 rsync modules configured in total
2025/11/06 20:09:39 rsyncos.go:32: rsync module "files" with path /usr/share/asda/rsync/ configured
2025/11/06 20:09:39 setting up landlock ACL (paths ro: ["/usr/share/asda/rsync/"], paths rw: [])
2025/11/06 20:09:39 landlock verified: readdir(/sys) = open /sys: permission denied
2025/11/06 20:09:39 rsyncos.go:32: not using systemd socket activation, creating listener
2025/11/06 20:09:39 rsyncos.go:32: rsync daemon listening on rsync://127.0.0.1:8730
2025/11/06 20:09:45 rsyncd.go:574: remote connection from 127.0.0.1:36534
2025/11/06 20:09:45 rsyncd.go:217: client 127.0.0.1:36534 requested rsync module "files"
2025/11/06 20:09:45 rsyncd.go:239: client sent: "--server"
2025/11/06 20:09:45 rsyncd.go:239: client sent: "--sender"
2025/11/06 20:09:45 rsyncd.go:239: client sent: "-vlogDtpr"
2025/11/06 20:09:45 rsyncd.go:239: client sent: "."
2025/11/06 20:09:45 rsyncd.go:239: client sent: "files/../"
2025/11/06 20:09:45 rsyncd.go:239: client sent: ""
2025/11/06 20:09:45 rsyncd.go:246: flags: [--server --sender -vlogDtpr . files/../]
2025/11/06 20:09:45 rsyncd.go:270: remaining: ["." "files/../"]
2025/11/06 20:09:45 rsyncd.go:280: paths: ["files/../"]
2025/11/06 20:09:45 rsyncd.go:296: trimmed paths: ["/../"]
2025/11/06 20:09:45 rsyncd.go:545: exclusion list read (entries: 0)
2025/11/06 20:09:45 do.go:43: SendFileList(modPath="/usr/share/asda/rsync/", paths=["/../"])
2025/11/06 20:09:45 flist.go:334: sendFileList()
2025/11/06 20:09:45 flist.go:349:   path "/../" (local dir "/usr/share/asda/rsync/")
2025/11/06 20:09:45 flist.go:360:   filepath.Walk("/usr/share/asda"), strip="/usr/share/asda/"
2025/11/06 20:09:45 flist.go:361:   prefix=""
2025/11/06 20:09:45 flist.go:140: filepath.WalkFn(path=.)
2025/11/06 20:09:45 flist.go:155: Trim(path=".") = "."
2025/11/06 20:09:45 flist.go:140: filepath.WalkFn(path=rsync)
2025/11/06 20:09:45 flist.go:155: Trim(path="rsync") = "rsync"
2025/11/06 20:09:45 flist.go:140: filepath.WalkFn(path=rsync/asdas)
2025/11/06 20:09:45 flist.go:155: Trim(path="rsync/asdas") = "rsync/asdas"
2025/11/06 20:09:45 flist.go:140: filepath.WalkFn(path=rsync/asdasda)
2025/11/06 20:09:45 flist.go:155: Trim(path="rsync/asdasda") = "rsync/asdasda"
2025/11/06 20:09:45 do.go:51: file list sent
2025/11/06 20:09:45 do.go:70: reading final int32
2025/11/06 20:09:45 rsyncd.go:552: handleConnSender done. stats: &{Read:104 Written:217 Size:8192}

Rather concerned it can read the parent (/usr/share/asda/*). Can also read the grandparent (/usr/share/*), however there is a client side error if trying any directory higher up. Note, the daemon still runs the check and wastes a bunch of time walking the path, wasting server resources. There just occurs a client side error when using the /usr/bin/rsync. See below.

user@device:~$ rsync -v --archive --port 8730 rsync://localhost/files/../../../
receiving file list ... 
unexpected tag 93 [Receiver]
rsync error: error in rsync protocol data stream (code 12) at io.c(1705) [Receiver=3.4.1]

Unrelated, but interestingly, given rsync -v --archive --port 8730 rsync://localhost/files/../../ and rsync -v --archive --port 8730 rsync://localhost/files/../.., the former works whilst the latter fails.

user@device:~$ rsync -v --archive --port 8730 rsync://localhost/files/../..
receiving file list ... 
ERROR: rejecting unrequested file-list name: share
rsync error: requested action not supported (code 4) at flist.c(1000) [Receiver=3.4.1]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions