aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
...
* pfinet: Factorize preparing the route requestSamuel Thibault2022-08-291-71/+57
|
* pfinet: Add SIOCADDRT and SIOCDELRT equivalent iioctlsDamien Zammit2022-08-294-101/+317
| | | | | | | | | | | | | | | | | | | | | | | | Using a new client side <net/route.h> I was able to clean up the existing options.c in pfinet and add two new ioctls for adding/deleting network routes. /* move to bits/ioctl.h */ struct ifrtreq { char ifname[IFNAMSIZ]; in_addr_t rt_dest; in_addr_t rt_mask; in_addr_t rt_gateway; int rt_flags; int rt_metric; int rt_mtu; int rt_window; int rt_irtt; int rt_tos; int rt_class; }; Message-Id: <20220829102952.369798-1-damien@zamaudio.com>
* Fix types of read write and readables methodsEtienne Brateau2022-08-2936-97/+97
| | | | Message-Id: <20220829193617.13481-1-etienne.brateau@gmail.com>
* Fix missing includeEtienne Brateau2022-08-291-0/+1
|
* Add missing included headerEtienne Brateau2022-08-281-0/+1
| | | | | Build was broken since 6d3b4cea78b22a6562eef4256cfcc40a8d372194 Message-Id: <20220827224239.54097-1-etienne.brateau@gmail.com>
* file_exec: Homogeneize adding the gratuitous send rightSamuel Thibault2022-08-233-7/+14
|
* Fix spurious EINTR while exec() within fakerootSamuel Thibault2022-08-231-0/+8
| | | | | | | | | | | | | | | | | | | | | | | The scenario is: - process running inside fakeroot exec()s - fakeroot forwards the exec call - exec starts thrashing the previous process, and notably close its ports - the send port that pointed to fakeroot is thus closed - fakeroot thus receives a no-senders notification - its libports thus interrupts the current RPC on it, i.e. the exec(), because it thinks that the caller is no more, but that was exactly the point of the exec()... - exec tries to interrupt its own RPCs, at best the execution will fail, at worse the process is already thrashed and there's nothing better than burying it for good. The symptom is processes running inside fakeroot seeming randomly crashing with SIGKILL. Making fakeroot keep a send right avoids the no-senders notification, thus the whole interruption (which was meaningless).
* storeio: Fix uninitialized err variableSamuel Thibault2022-08-231-4/+3
|
* Add trivfs_startup_debug() for easier translator developmentLuca Dariz2022-08-223-9/+117
| | | | | | | | | | Basically it is an automation of this: http://walfield.org/pub/people/neal/papers/hurd-misc/manual-bootstrap.txt To launch a storeio translator on FILE: $ storeio -d FILE -T TYPE ARG Message-Id: <20170126213616.26846-1-luca.dariz@gmail.com>
* term: Prevent new master while some slaves are still thereSamuel Thibault2022-08-222-1/+3
| | | | | | The previous master may have gone before all previous slaves have gone. If a slave gets stuck, TTY_OPEN will kept set, and there would be no reset performed in open_hook, thus leaking tty state and data.
* Note how we will be able to keep only one pci-arbiter translatorSamuel Thibault2022-08-201-0/+2
|
* Implement mapping for ROM filesJoan Lledó2022-08-156-27/+98
| | | | | | | | | | | | | | | | | | | | | | | | | | | * pci-arbiter/device_map.h: * pci-arbiter/device_map.c: * New function: device_map_rom * Copies the whole rom in the arbiter space. * pci-arbiter/pcifs.h: * struct pcifs_dirent: * New field to store the mapping address for each device rom. o pci-arbiter/func_files.h: * pci-arbiter/func_files.c: * read_rom_file: * Retrieves the rom contents from the local space instead of libpciaccess. * pci-arbiter/netfs_impl.c: * netfs_attempt_read:get_filemap_region * Update call to read_rom_file. * get_filemap_region: * Uses the old code at netfs_get_filemap to get a proxy to the device memory region. * get_filemap_rom: * Returns a proxy to the locally mapped device rom. * netfs_get_filemap: * Checks the requested file to map and calls get_filemap_rom, get_filemap_region or returns en error. Message-Id: <20220815161520.6059-2-jlledom@mailfence.com>
* Drop ip_mreqn structureSamuel Thibault2022-08-131-7/+0
| | | | This is to be defined in the glibc header.
* pfinet: Increase default max buffer size to 256k, like on LinuxSamuel Thibault2022-08-131-2/+2
|
* Rename proc_complete_reauthentication to proc_reauthenticate_completeSamuel Thibault2022-08-107-16/+16
| | | | For coherency with the existing RPCs
* Keep proc_setowner_request for backward compatibilitySamuel Thibault2022-08-101-1/+6
| | | | So that existing callers can still compile, and just get MIG_BAD_ID.
* Fix including notify_S.h and running ports_notify_server_routineSamuel Thibault2022-08-102-3/+3
|
* Make proc_reauthenticate () recreate proc portSergey Bugaev2022-08-107-59/+167
| | | | And add proc_complete_reauthentication ()
* libnetfs, libtrivs: Shield S_file_exec_paths () from cancellationSergey Bugaev2022-08-102-2/+6
| | | | | | | | | | | | | | | | | | | | | | | Here's the sequence of events that leads to a bug: * A task calls file_exec_paths () on itself, holding the only send right to the protid, passing EXEC_NEWTASK (or EXEC_SECURE, which implies it). * S_file_exec_paths () calls exec_exec_paths () * The exec server sets up a new task and calls proc_reassign () or proc_reauthenticate_reassign (). * The proc server destroys the old task, and the only send right to the protid with it. * The translator gets a no-senders notification, which results in a ports_interrupt_rpcs () call on the S_file_exec_paths (). * This propagates to the exec server (and potentially proc and auth servers). * The exec gets canceled, and the new task gets killed. In my opinion, the party that seems most guilty is the translator canceling exec upon receiving a no-senders notification for the protid. Normally, a no-senders notification means that the caller is no longer interested in the RPC, but this is not true in case of exec. To work around this, create an additional send right to the protid.
* Remove the concept of process ownerSergey Bugaev2022-08-109-44/+28
| | | | | | | | | | Now that it's completely unused. procinfo.owner is now simply set to the first UID that a process has. proc_setowner () is kept for compatibility, but now does nothing. The clients still try to call it, though, for compatibility with older proc server versions.
* libshouldbeinlibc: Do not reauthenticate proc port when secureSergey Bugaev2022-08-102-7/+8
| | | | | | | | | | | | | | exec_reauth () is supposed to reauthenticate the given ports and file descriptors with a new authentication. If the secure flag is set, this reauthentication is happening for a future exec with the EXEC_SECURE flag. Now that the exec server uses proc_reauthenticate_reassign (), the process reauthentication is done atomically with task reassignment by the exec server. So stop doing it inside exec_reauth (). This fixes a vulnerability where a process was able to use its reauthenticated proc port before it got exec'ed over.
* exec: Use proc_reauthenticate_reassign ()Sergey Bugaev2022-08-101-42/+33
| | | | | This lets the exec server atomically replace the old task with the new task while raising its privileges.
* proc: Add proc_reauthenticate_reassign ()Sergey Bugaev2022-08-104-3/+153
| | | | | This is a new RPC to atomically change the UIDs of a process, recreate its process port, and reassign a different task to it.
* proc: Fix an error pathSergey Bugaev2022-08-101-4/+9
| | | | | If the allocation failed, we want to leave the p_ids pointer as it was, and properly propagate the error code.
* proc: Use UIDs for evaluating permissionsSergey Bugaev2022-08-101-9/+31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The previous scheme was to check that PROC1 has the UID that is designated as PROC2's "owner". This is extremely problematic for several reasons, including: * The UIDs and the owner of a process are set separately and can easily get out of sync. While S_proc_setowner () checks that the new owner is among the UIDs that the process has, this invariant is violated after the process is given a new set of UIDs with S_proc_reauthenticate (). In particular, this happens during execution of a SUID binary: the process is reauthenticated to a different set of UIDs first, and its owner is udpated later, if at all. * In the Hurd, a process can have multiple UIDs. Having to designate just one of them as the owner means the other UIDs get ignored for the purpose of permission checking. One particularly problematic case is a SUID process that temporarily lowers its effective UID: glibc sets the first effective UID as the process owner, giving just about anyone access to the task. Resolve this by ignoring the owner for the purpose of permission checking, and relying solely on the authenticated UIDs. Roughly speaking, PROC1 can get complete access to PROC2 if the UIDs PROC1 has form a superset of the UIDs that PROC2 has; in other words, the access is only allowed when it would not result in PROC1 getting access to UIDs it doesn't have already. Of course, root is still allowed to access any process. In particular, this means that: * a process can access another process if they have the same auth; * a process that has "more auth" can access one that has "less auth", but not the other way around; * a SUID-root process that has lowered its effective UIDs can only be accessed by root. Another important point here is that the UIDs in question are both effective and available UIDs that a process has. Normally, available UIDs are ignored for the purpose of permission checking (and that is their whole point). However, POSIX description of kill(2) has the following clause: > For a process to have permission to send a signal to a process designated by > pid, unless the sending process has appropriate privileges, the real or > effective user ID of the sending process shall match the real or saved > set-user-ID of the receiving process. Which I read as saying that the real (i.e. available) UID(s) of PROC1 should be used for evaluating whether kill(2) can succeed, not only its effective UID(s).
* proc: Track both available and effective uidsSergey Bugaev2022-08-101-10/+11
| | | | | This is in preparation for using the UID's to evaluate permissions in a different way.
* libfshelp: Handle proc port in fshelp_start_translator_long ()Sergey Bugaev2022-08-101-7/+49
| | | | | | | | | | | | | | While fshelp_start_translator_long () has been calling proc_setowner () on the task it creates, it has never reauthenticated its process. This meant that the translator, once started, could access processes authenticated same as the process that called fshelp_start_translator_long (). In particular, this means that any unprivileged translator started by a privileged parent translator had in fact had a privileged proc port, and could access other processes through it. With this change, fshelp_start_translator_long () will now reauthenticate the process it creates. Moreover, it will now respect a custom proc server port passed in the given ports.
* libfshelp: Cosmetic cleanupsSergey Bugaev2022-08-101-14/+18
|
* libfshelp: Simplify fshelp_start_translator_long () a bitSergey Bugaev2022-08-101-39/+14
| | | | | | | It only really supports ports_len > INIT_PORT_BOOTSTRAP, ports_type == MACH_MSG_TYPE_COPY_SEND, fds_type == MACH_MSG_TYPE_COPY_SEND. Make that explicit, and remove the branches that tried to handle the other cases.
* startup: Request notifications to a separate portSergey Bugaev2022-08-101-6/+24
| | | | | Since this port is never given out to anyone but the kernel, our clients can't spoof a dead-name notification this way.
* console: Forward any libports-requested notifications to themSergey Bugaev2022-08-101-0/+4
| | | | | | libports will start requesting dead-name notifications on its own. As we handle all notifications, both ones we have requested and ones libports has, distinguish between the two handlers by the port.
* console: Return EOPNOTSUPP when appropriateSergey Bugaev2022-08-101-3/+3
| | | | | | | | | | We do not impement most of the mach_notify_* () routines. Explicitly return an error code so that our caller knows to properly deallocate all resources the messages may carry. Even though we don't expect to receive some of the notifications from the kernel as we never sign up for them, we can always receive spoofed notifications from our clients, so don't abort in that case.
* console: Simplify code with ports_request_dead_name_notification ()Sergey Bugaev2022-08-101-25/+3
| | | | | | We can't use it to *request* notifications here, since we need to use a custom per-display port (and not libports' notify_port), but we can still use it to *cancel* notifications with a lot less boilerplate.
* libports: Only accept dead-name notifications on notify_portSergey Bugaev2022-08-101-2/+2
| | | | | Since this port is never given out to anyone but the kernel, our clients can't spoof a dead-name notification this way.
* libports: Return EOPNOTSUPP when appropriateSergey Bugaev2022-08-104-4/+4
| | | | | | We do not impement most of the mach_notify_* () routines. Explicitly return an error code so that our caller knows to properly deallocate all resources the messages may carry.
* libmachdev: Use notify server implementation from libportsSergey Bugaev2022-08-102-44/+2
| | | | | | Since the implementation in libmachdev was just forwarding calls to the corresponding libports functions, we might as well just use ports_notify_server_routine () directly.
* libdiskfs, libnetfs: Disable broken codeSergey Bugaev2022-08-102-1/+11
| | | | This logic is obviously broken, let's disable it for now.
* libfshelp: Update some commentsSergey Bugaev2022-08-102-3/+5
|
* diskfs: Use libports notificationsSergey Bugaev2022-08-103-10/+7
| | | | | Namely, ports_request_dead_name_notification () where we can, and the libports notify port when we have to pass it to libfshelp.
* netfs: Use the libports notify portSergey Bugaev2022-08-102-2/+6
|
* eth-multiplexer: Use notify server implementation from libportsSergey Bugaev2022-08-106-83/+34
| | | | We can simply override proc_dead_name () to handle dead-name notifications.
* eth-multiplexer: Use ports_request_dead_name_notification ()Sergey Bugaev2022-08-102-16/+4
|
* proc: Use notify server implementation from libportsSergey Bugaev2022-08-104-71/+10
| | | | We can simply override proc_dead_name () to handle dead-name notifications.
* proc: Use ports_request_dead_name_notification ()Sergey Bugaev2022-08-103-44/+17
|
* libports: Add ports_request_dead_name_notification ()Sergey Bugaev2022-08-103-1/+63
| | | | | This significantly cuts down the boilerplate of requesting dead-name notifications.
* libports: Request notifications to the notify_portSergey Bugaev2022-08-101-4/+4
|
* libports: Create a notify_port in each bucketSergey Bugaev2022-08-104-7/+45
| | | | | | | This notify port will be used to request & receive Mach notifications. While it is present in the bucket much like any other port, it is not counted in ports_count_bucket () and is not exposed to the user callback in ports_bucket_iterate ().
* libports: Treat no-senders notifications as a hintSergey Bugaev2022-08-101-4/+19
| | | | | | | No-senders notifications are directed to the port that no longer has any senders left. Since any client can easily spoof such a notification, we have to treat the notification as just a hint and verify whether there are, in fact, any senders, and only call ports_no_senders () if there actually are none left.
* proc: Drop some mach_port_destroy () usesSergey Bugaev2022-08-101-11/+5
| | | | | | | | | | | | | | | | mach_port_destroy () is a dangerous API that has to be used with extreme care. Namely, it destroys not one user reference, but *all* user references that a task has for a port name. Different parts of a program may all keep separate references on a port without coordinating it with each other (which is the whole idea behind reference counting). If one part of a program decides to destroy a port with mach_port_destroy () without informing others, others may still believe they hold a reference and will continue to use the name as if it still refered to the now-destroyed port right. This consitutes a port use-after-free, even if their use is also deallocating their reference. In the particular case of the proc server, this manifested itself as S_proc_reassign () destroying all user references to the task port right before the task port right is deallocated again in the dead-name notification handler.
* Do not use ports_get_right () for send-one rightsSergey Bugaev2022-08-102-3/+3
| | | | | | | | | | | | ports_get_right () expects the caller to make a send, not a send-once, right from the returned receive right, and increments the expected make-send count accordingly. The kernel, however, does not increment the make-send count when a send-once right is being made. The result can be described as a "no-senders leak": libports' idea of the current make-send count always stays one step ahead of it actual value (or several steps ahead, if the process is repeated), which makes libports ignore *all* the subsequent no-senders notifications for the port as outdated.