This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit cf3781b7f0075d7e369ac27394ebbe11843b67ed
Author: Abhishek Mishra <[email protected]>
AuthorDate: Wed Aug 12 07:13:36 2026 +0000

    sched: add setresuid and setresgid
    
    Complete the POSIX credential setters for real/effective/saved UID and
    GID so login and privilege-drop paths can clear saved-root without
    relying on setreuid patterns alone.
    
    Signed-off-by: Abhishek Mishra <[email protected]>
---
 libs/libc/unistd/lib_setresgid.c | 69 +++++++++++++++++++++++++++++
 libs/libc/unistd/lib_setresuid.c | 68 +++++++++++++++++++++++++++++
 sched/group/group_setresgid.c    | 92 +++++++++++++++++++++++++++++++++++++++
 sched/group/group_setresuid.c    | 93 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 322 insertions(+)

diff --git a/libs/libc/unistd/lib_setresgid.c b/libs/libc/unistd/lib_setresgid.c
new file mode 100644
index 00000000000..ae0ad16262c
--- /dev/null
+++ b/libs/libc/unistd/lib_setresgid.c
@@ -0,0 +1,69 @@
+/****************************************************************************
+ * libs/libc/unistd/lib_setresgid.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <unistd.h>
+#include <errno.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: setresgid
+ *
+ * Description:
+ *   The setresgid() function sets the real, effective, and saved
+ *   set-group-ID of the calling process.  Stub when
+ *   CONFIG_SCHED_USER_IDENTITY is disabled: only root (0) or unchanged
+ *   ((gid_t)-1) values are accepted.
+ *
+ * Input Parameters:
+ *   rgid - Real group ID, or (gid_t)-1 to leave unchanged.
+ *   egid - Effective group ID, or (gid_t)-1 to leave unchanged.
+ *   sgid - Saved set-group-ID, or (gid_t)-1 to leave unchanged.
+ *
+ * Returned Value:
+ *   Zero if successful and -1 in case of failure, in which case errno is set
+ *   appropriately.
+ *
+ ****************************************************************************/
+
+int setresgid(gid_t rgid, gid_t egid, gid_t sgid)
+{
+  /* NuttX only supports the group identity 'root' with a gid value of 0. */
+
+  if ((rgid == (gid_t)-1 || rgid == 0) &&
+      (egid == (gid_t)-1 || egid == 0) &&
+      (sgid == (gid_t)-1 || sgid == 0))
+    {
+      return 0;
+    }
+
+  set_errno(EINVAL);
+  return ERROR;
+}
diff --git a/libs/libc/unistd/lib_setresuid.c b/libs/libc/unistd/lib_setresuid.c
new file mode 100644
index 00000000000..847ded42a7e
--- /dev/null
+++ b/libs/libc/unistd/lib_setresuid.c
@@ -0,0 +1,68 @@
+/****************************************************************************
+ * libs/libc/unistd/lib_setresuid.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <unistd.h>
+#include <errno.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: setresuid
+ *
+ * Description:
+ *   The setresuid() function sets the real, effective, and saved set-user-ID
+ *   of the calling process.  Stub when CONFIG_SCHED_USER_IDENTITY is
+ *   disabled: only root (0) or unchanged ((uid_t)-1) values are accepted.
+ *
+ * Input Parameters:
+ *   ruid - Real user ID, or (uid_t)-1 to leave unchanged.
+ *   euid - Effective user ID, or (uid_t)-1 to leave unchanged.
+ *   suid - Saved set-user-ID, or (uid_t)-1 to leave unchanged.
+ *
+ * Returned Value:
+ *   Zero if successful and -1 in case of failure, in which case errno is set
+ *   appropriately.
+ *
+ ****************************************************************************/
+
+int setresuid(uid_t ruid, uid_t euid, uid_t suid)
+{
+  /* NuttX only supports the user identity 'root' with a uid value of 0. */
+
+  if ((ruid == (uid_t)-1 || ruid == 0) &&
+      (euid == (uid_t)-1 || euid == 0) &&
+      (suid == (uid_t)-1 || suid == 0))
+    {
+      return 0;
+    }
+
+  set_errno(EINVAL);
+  return ERROR;
+}
diff --git a/sched/group/group_setresgid.c b/sched/group/group_setresgid.c
new file mode 100644
index 00000000000..825877c1516
--- /dev/null
+++ b/sched/group/group_setresgid.c
@@ -0,0 +1,92 @@
+/****************************************************************************
+ * sched/group/group_setresgid.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <sched/sched.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: setresgid
+ *
+ * Description:
+ *   setresgid() sets the real, effective, and saved set-group-IDs of the
+ *   calling process.  The value (gid_t)-1
+ *   for any argument leaves that ID unchanged.
+ *
+ ****************************************************************************/
+
+int setresgid(gid_t rgid, gid_t egid, gid_t sgid)
+{
+  FAR struct tcb_s *rtcb;
+  FAR struct task_group_s *rgroup;
+  gid_t old_rgid;
+  gid_t old_egid;
+  gid_t old_sgid;
+  gid_t new_rgid;
+  gid_t new_egid;
+  gid_t new_sgid;
+
+  rtcb   = this_task();
+  rgroup = rtcb->group;
+  DEBUGASSERT(rgroup != NULL);
+
+  old_rgid = rgroup->tg_gid;
+  old_egid = rgroup->tg_egid;
+  old_sgid = rgroup->tg_sgid;
+
+  new_rgid = (rgid == (gid_t)-1) ? old_rgid : rgid;
+  new_egid = (egid == (gid_t)-1) ? old_egid : egid;
+  new_sgid = (sgid == (gid_t)-1) ? old_sgid : sgid;
+
+  /* Non-root euid may only select among current real/effective/saved. */
+
+  if (rgroup->tg_euid != 0)
+    {
+      if ((new_rgid != old_rgid && new_rgid != old_egid &&
+           new_rgid != old_sgid) ||
+          (new_egid != old_rgid && new_egid != old_egid &&
+           new_egid != old_sgid) ||
+          (new_sgid != old_rgid && new_sgid != old_egid &&
+           new_sgid != old_sgid))
+        {
+          set_errno(EPERM);
+          return ERROR;
+        }
+    }
+
+  rgroup->tg_gid  = new_rgid;
+  rgroup->tg_egid = new_egid;
+  rgroup->tg_sgid = new_sgid;
+  return OK;
+}
diff --git a/sched/group/group_setresuid.c b/sched/group/group_setresuid.c
new file mode 100644
index 00000000000..ca2d6e32677
--- /dev/null
+++ b/sched/group/group_setresuid.c
@@ -0,0 +1,93 @@
+/****************************************************************************
+ * sched/group/group_setresuid.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <sched/sched.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: setresuid
+ *
+ * Description:
+ *   setresuid() sets the real, effective, and saved set-user-IDs of the
+ *   calling process.  The value (uid_t)-1 for any argument leaves that
+ *   ID unchanged.
+ *
+ ****************************************************************************/
+
+int setresuid(uid_t ruid, uid_t euid, uid_t suid)
+{
+  FAR struct tcb_s *rtcb;
+  FAR struct task_group_s *rgroup;
+  uid_t old_ruid;
+  uid_t old_euid;
+  uid_t old_suid;
+  uid_t new_ruid;
+  uid_t new_euid;
+  uid_t new_suid;
+
+  rtcb   = this_task();
+  rgroup = rtcb->group;
+  DEBUGASSERT(rgroup != NULL);
+
+  old_ruid = rgroup->tg_uid;
+  old_euid = rgroup->tg_euid;
+  old_suid = rgroup->tg_suid;
+
+  new_ruid = (ruid == (uid_t)-1) ? old_ruid : ruid;
+  new_euid = (euid == (uid_t)-1) ? old_euid : euid;
+  new_suid = (suid == (uid_t)-1) ? old_suid : suid;
+
+  if (old_euid != 0)
+    {
+      /* Unprivileged: each new ID must be one of the current r/e/s UIDs. */
+
+      if ((new_ruid != old_ruid && new_ruid != old_euid &&
+           new_ruid != old_suid) ||
+          (new_euid != old_ruid && new_euid != old_euid &&
+           new_euid != old_suid) ||
+          (new_suid != old_ruid && new_suid != old_euid &&
+           new_suid != old_suid))
+        {
+          set_errno(EPERM);
+          return ERROR;
+        }
+    }
+
+  rgroup->tg_uid  = new_ruid;
+  rgroup->tg_euid = new_euid;
+  rgroup->tg_suid = new_suid;
+  return OK;
+}

Reply via email to