linux: Implement setfsuid(2) and setfsgid(2) as no-ops

These system calls exist to decouple the Linux filesystem credentials
from the effective credentials, avoiding signal exposure during
privilege transitions.
The signal permission model that motivated this was revised
in Linux 2.0, making these syscalls obsolete for new applications.

Implement both syscalls as no-ops that return the current effective
UID/GID as the previous filesystem UID/GID.
Linux returns the previous filesystem UID/GID for these syscalls
with no error indication.

Same for the equivalent setfsuid16() & setfsgid16() system calls.

Signed-off-by:	Ricardo Branco <rbranco@suse.de>
PR:		294879
Reviewed by:	kib, pouria
Pull-Request:	https://github.com/freebsd/freebsd-src/pull/2175
This commit is contained in:
Ricardo Branco
2026-04-29 20:27:22 +02:00
committed by Pouria Mousavizadeh Tehrani
parent 9c77fb6aaa
commit f4ae41b7ea
3 changed files with 40 additions and 4 deletions
-2
View File
@@ -56,8 +56,6 @@ UNIMPLEMENTED(query_module); /* Added in Linux 2.2 removed in 2.6. */
UNIMPLEMENTED(security);
UNIMPLEMENTED(vserver);
DUMMY(setfsuid);
DUMMY(setfsgid);
DUMMY(vhangup);
DUMMY(pivot_root);
DUMMY(adjtimex);
+26
View File
@@ -3179,4 +3179,30 @@ linux_membarrier(struct thread *td, struct linux_membarrier_args *args)
return (0);
}
/*
* setfsuid() & setfsgid() exist to decouple the Linux filesystem credentials
* from the effective credentials, avoiding signal exposure during privilege
* transitions. The signal permission model that motivated this was revised in
* Linux 2.0, making these syscalls obsolete for new applications.
*
* As there's no FreeBSD equivalent, implement both syscalls as no-ops that
* return the current effective UID/GID as the previous filesystem UID/GID.
* Linux returns the previous filesystem UID/GID for these syscalls, with no
* error indication.
*/
int
linux_setfsuid(struct thread *td, struct linux_setfsuid_args *args)
{
td->td_retval[0] = td->td_ucred->cr_uid;
return (0);
}
int
linux_setfsgid(struct thread *td, struct linux_setfsgid_args *args)
{
td->td_retval[0] = td->td_ucred->cr_gid;
return (0);
}
MODULE_DEPEND(linux, mqueuefs, 1, 1, 1);
+14 -2
View File
@@ -59,8 +59,6 @@ LIN_SDT_PROBE_DEFINE1(uid16, linux_setgroups16, copyin_error, "int");
LIN_SDT_PROBE_DEFINE1(uid16, linux_setgroups16, priv_check_cred_error, "int");
LIN_SDT_PROBE_DEFINE1(uid16, linux_getgroups16, copyout_error, "int");
DUMMY(setfsuid16);
DUMMY(setfsgid16);
DUMMY(getresuid16);
DUMMY(getresgid16);
@@ -284,3 +282,17 @@ linux_setresuid16(struct thread *td, struct linux_setresuid16_args *args)
return (error);
}
int
linux_setfsuid16(struct thread *td, struct linux_setfsuid16_args *args)
{
td->td_retval[0] = td->td_ucred->cr_uid;
return (0);
}
int
linux_setfsgid16(struct thread *td, struct linux_setfsgid16_args *args)
{
td->td_retval[0] = td->td_ucred->cr_gid;
return (0);
}