kristapsdz / openrsync

BSD-licensed implementation of rsync
ISC License
402 stars 28 forks source link

Adding portability to FreeBSD #4

Closed slicer69 closed 5 years ago

slicer69 commented 5 years ago

The attached patch addresses most of the issues which prevent openrsync from compiling on FreeBSD. This adds in the necessary include files and works around OpenBSD-specific features such as pledge and unveil.

There are still some linker issues with hashes, but this patch gets us more than halfway to a build on FreeBSD 11.x.

rsync-freebsd-patch.txt

kristapsdz commented 5 years ago

First, recallocarray and realloc are not the same, so using this patch will break things in dangerous ways.

Second, stripping out the security mechanisms is a bad idea. I understand you're just trying to get a compile, but a great part of reimplementing something is to fit in some proper security. Capsicum isn't easy to work with, but it's what you have. The system is already outfitted with openat and equivalent, so you should be able to follow the pledges (and unveils) neatly.

All that being said, I'm not considering portability yet. I don't want to discourage you: the code is just moving way too quickly to be tracking with patches.

Once I tag out with an initial version, I'll turn to questions of portability. As you can see, it's really not difficult. The hard part is Capsicum---and frankly, without Capsicum bits, the port is only partial.

Meawhile, this might be a good time to get recallocarray into FreeBSD's libc... ;)

lattera commented 5 years ago

reallocarray(3) is in FreeBSD, starting with 11.0-RELEASE. :)

kristapsdz commented 5 years ago

And recallocarray? (Note the c.)

slicer69 commented 5 years ago

I understand where you are coming from and if this patch is premature (either in quality or time-wise due to coding changes) then there are no hard feelings if it is rejected. I would like to share a few thoughts in response to the points you made above:

  1. I agree, recallocarry and realloc are not the same. This should be updated later, probably with a memset call. For now I just want to get openrsync to compile. Then polish the port.

  2. I agree, stripping security is bad. But I want to get this working on not just FreeBSD, but also Linux. To do that I've got to work around functions that don't exist on those platforms. I've been careful to leave the calls intact in my patch on the native (OpenBSD) platform.

  3. I agree carrying patches is not a great idea. But I think these could be applied upstream with no negative impact on the native platform, and it'll give other porters a place to start.

I agree, getting all of these secure functions into FreeBSD would be ideal. Not really in the scope of what I am doing personally, but I'd love to see someone put recallocarray and unveil in FreeBSD.

lattera commented 5 years ago

Whoops, sorry, I missed the c. recallocarray indeed does not exist on FreeBSD. Sorry for the noise!

kristapsdz commented 5 years ago

As noted in the README, I was able to use oconfigure to easily port the system to FreeBSD (and Linux). (On FreeBSD, you'll also need to make endian.h -> sys/endian.h.) However, also as mentioned, any port is not complete without having the appropriate security mechanisms. If your system's security model is hard to implement---please talk to them about it. But in this day and age, having a critical network-facing utility accepting binary data on the wire without some means of sandbox is irresponsible.

emaste commented 5 years ago

Porting to Capsicum should be fairly straightforward as openrsync already makes extensive use of the *at() functions; on a quick look it appears now that only rsync_sender calls plain open() for files. Then it's just calling cap_enter() at the appropriate point, probably at the where the final pledge() is done now after setup/initialization and before starting to parse/interact with network traffic or untrusted data. One of my co-op students will probably take a look at this shortly.

emaste commented 5 years ago

Porting the receiver to Capsicum should be fairly straightforward, because of the use of *at() functions.

Accepting multiple files/directories on the command line makes the sender side more complicated; we've recently added the cap_fileargs service to support this use. The second issue is the path for fts - we'll need to add a fts_openat or such to operate relative to a provided directory file descriptor.

kristapsdz commented 5 years ago

If/when you get these, feel free to submit them. Til then I've put a compatibility shim so it should compile on freebsd.

emaste commented 5 years ago

I agree it makes sense to close this issue (and I will submit patches for a Capsicumized FreeBSD port when they're fully ready).

For reference the current WIP/discussion is in https://reviews.freebsd.org/D19407 - this is (intentionally) not upstreamable as is, we just removed/replaced existing pledge/unveil calls to be able to review/comprehend the change.

The current dependency we need to address is a sandbox-friendly fts(3); we have a plan, just need to implement it.