diff --git a/sys/compat/linux/linux_dummy.c b/sys/compat/linux/linux_dummy.c index dfabf33eb8a..971e070e90a 100644 --- a/sys/compat/linux/linux_dummy.c +++ b/sys/compat/linux/linux_dummy.c @@ -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); diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 4c8ad669f03..f89758f41ba 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -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); diff --git a/sys/compat/linux/linux_uid16.c b/sys/compat/linux/linux_uid16.c index 8ac093e004d..16866c374aa 100644 --- a/sys/compat/linux/linux_uid16.c +++ b/sys/compat/linux/linux_uid16.c @@ -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); +}