From 896f34fde99cc9584ef2f1bf0b8711bda5e7e2ed Mon Sep 17 00:00:00 2001 From: fangxinyong Date: Sat, 15 Apr 2023 14:47:19 +0800 Subject: [PATCH] sched: implement effective uid and gid interfaces Implement 'effective' setuid, getuid, setgid, and getgid interfaces. These will be inheritance by all child task groups. These definitons are explicitly specified here: https://pubs.opengroup.org/onlinepubs/000095399/functions/geteuid.html https://pubs.opengroup.org/onlinepubs/000095399/functions/getegid.html https://pubs.opengroup.org/onlinepubs/000095399/functions/seteuid.html https://pubs.opengroup.org/onlinepubs/000095399/functions/setegid.html Signed-off-by: fangxinyong --- include/nuttx/sched.h | 2 + include/sys/syscall_lookup.h | 4 ++ libs/libc/unistd/Make.defs | 4 +- libs/libc/unistd/lib_getegid.c | 8 ---- libs/libc/unistd/lib_geteuid.c | 8 ---- libs/libc/unistd/lib_setegid.c | 8 ---- libs/libc/unistd/lib_seteuid.c | 8 ---- sched/group/Make.defs | 1 + sched/group/group_create.c | 2 + sched/group/group_getegid.c | 61 ++++++++++++++++++++++++ sched/group/group_geteuid.c | 61 ++++++++++++++++++++++++ sched/group/group_setegid.c | 84 +++++++++++++++++++++++++++++++++ sched/group/group_seteuid.c | 86 ++++++++++++++++++++++++++++++++++ syscall/syscall.csv | 8 ++-- 14 files changed, 307 insertions(+), 38 deletions(-) create mode 100644 sched/group/group_getegid.c create mode 100644 sched/group/group_geteuid.c create mode 100644 sched/group/group_setegid.c create mode 100644 sched/group/group_seteuid.c diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 3bae61fed4..47f2549ea2 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -427,6 +427,8 @@ struct task_group_s #ifdef CONFIG_SCHED_USER_IDENTITY uid_t tg_uid; /* User identity */ gid_t tg_gid; /* User group identity */ + uid_t tg_euid; /* Effective user identity */ + gid_t tg_egid; /* Effective user group identity */ #endif /* Group membership *******************************************************/ diff --git a/include/sys/syscall_lookup.h b/include/sys/syscall_lookup.h index 6b18801f2b..2b4d449b71 100644 --- a/include/sys/syscall_lookup.h +++ b/include/sys/syscall_lookup.h @@ -67,6 +67,10 @@ SYSCALL_LOOKUP(sethostname, 2) SYSCALL_LOOKUP(getuid, 0) SYSCALL_LOOKUP(setgid, 1) SYSCALL_LOOKUP(getgid, 0) + SYSCALL_LOOKUP(seteuid, 1) + SYSCALL_LOOKUP(geteuid, 0) + SYSCALL_LOOKUP(setegid, 1) + SYSCALL_LOOKUP(getegid, 0) #endif /* Semaphores */ diff --git a/libs/libc/unistd/Make.defs b/libs/libc/unistd/Make.defs index 66ba8184fe..c30bc721be 100644 --- a/libs/libc/unistd/Make.defs +++ b/libs/libc/unistd/Make.defs @@ -25,15 +25,15 @@ CSRCS += lib_getentropy.c lib_getopt_common.c lib_getopt.c lib_getopt_long.c CSRCS += lib_getopt_longonly.c lib_getoptvars.c lib_getoptargp.c CSRCS += lib_getopterrp.c lib_getoptindp.c lib_getoptoptp.c lib_times.c CSRCS += lib_alarm.c lib_fstatvfs.c lib_statvfs.c lib_sleep.c lib_nice.c -CSRCS += lib_usleep.c lib_seteuid.c lib_setegid.c lib_geteuid.c lib_getegid.c CSRCS += lib_setreuid.c lib_setregid.c lib_getrusage.c lib_utime.c lib_utimes.c CSRCS += lib_setrlimit.c lib_getrlimit.c lib_setpriority.c lib_getpriority.c CSRCS += lib_futimes.c lib_lutimes.c lib_gethostname.c lib_sethostname.c CSRCS += lib_fchownat.c lib_linkat.c lib_readlinkat.c lib_symlinkat.c -CSRCS += lib_unlinkat.c lib_getpgrp.c lib_getpgid.c +CSRCS += lib_unlinkat.c lib_usleep.c lib_getpgrp.c lib_getpgid.c ifneq ($(CONFIG_SCHED_USER_IDENTITY),y) CSRCS += lib_setuid.c lib_setgid.c lib_getuid.c lib_getgid.c +CSRCS += lib_seteuid.c lib_setegid.c lib_geteuid.c lib_getegid.c endif ifneq ($(CONFIG_DISABLE_ENVIRON),y) diff --git a/libs/libc/unistd/lib_getegid.c b/libs/libc/unistd/lib_getegid.c index fe8c8e0c6c..89b6bef988 100644 --- a/libs/libc/unistd/lib_getegid.c +++ b/libs/libc/unistd/lib_getegid.c @@ -48,15 +48,7 @@ gid_t getegid(void) { -#ifdef CONFIG_SCHED_USER_IDENTITY - /* If we have real UID/GID support, then treat the real group as the - * effective group ID. - */ - - return getgid(); -#else /* Return group identity 'root' with a gid value of 0. */ return 0; -#endif } diff --git a/libs/libc/unistd/lib_geteuid.c b/libs/libc/unistd/lib_geteuid.c index 6083205df1..4b17ae9617 100644 --- a/libs/libc/unistd/lib_geteuid.c +++ b/libs/libc/unistd/lib_geteuid.c @@ -48,15 +48,7 @@ uid_t geteuid(void) { -#ifdef CONFIG_SCHED_USER_IDENTITY - /* If we have real UID/GID support, then treat the real user ID as the - * effective user ID. - */ - - return getuid(); -#else /* Return the user identity 'root' with a uid value of 0. */ return 0; -#endif } diff --git a/libs/libc/unistd/lib_setegid.c b/libs/libc/unistd/lib_setegid.c index 029823a1b4..91be25d350 100644 --- a/libs/libc/unistd/lib_setegid.c +++ b/libs/libc/unistd/lib_setegid.c @@ -50,13 +50,6 @@ int setegid(gid_t gid) { -#ifdef CONFIG_SCHED_USER_IDENTITY - /* If we have real UID/GID support, then treat the effective user ID as - * the real group ID. - */ - - return setgid(gid); -#else /* NuttX only supports the group identity 'root' with a gid value of 0. */ if (gid == 0) @@ -70,5 +63,4 @@ int setegid(gid_t gid) set_errno(EINVAL); return -1; -#endif } diff --git a/libs/libc/unistd/lib_seteuid.c b/libs/libc/unistd/lib_seteuid.c index 2df0c6532b..d77579ed79 100644 --- a/libs/libc/unistd/lib_seteuid.c +++ b/libs/libc/unistd/lib_seteuid.c @@ -49,13 +49,6 @@ int seteuid(uid_t uid) { -#ifdef CONFIG_SCHED_USER_IDENTITY - /* If we have real UID/GID support, then treat the effective user ID as - * the real user ID. - */ - - return setuid(uid); -#else /* NuttX only supports the user identity 'root' with a uid value of 0. */ if (uid == 0) @@ -69,5 +62,4 @@ int seteuid(uid_t uid) set_errno(EINVAL); return -1; -#endif } diff --git a/sched/group/Make.defs b/sched/group/Make.defs index de6fdbb249..0328e042f4 100644 --- a/sched/group/Make.defs +++ b/sched/group/Make.defs @@ -35,6 +35,7 @@ endif ifeq ($(CONFIG_SCHED_USER_IDENTITY),y) CSRCS += group_setuid.c group_setgid.c group_getuid.c group_getgid.c +CSRCS += group_seteuid.c group_setegid.c group_geteuid.c group_getegid.c endif ifeq ($(CONFIG_SIG_SIGSTOP_ACTION),y) diff --git a/sched/group/group_create.c b/sched/group/group_create.c index f353df0ca8..7a239194c3 100644 --- a/sched/group/group_create.c +++ b/sched/group/group_create.c @@ -90,6 +90,8 @@ static inline void group_inherit_identity(FAR struct task_group_s *group) DEBUGASSERT(group != NULL); group->tg_uid = rgroup->tg_uid; group->tg_gid = rgroup->tg_gid; + group->tg_euid = rgroup->tg_euid; + group->tg_egid = rgroup->tg_egid; } #else # define group_inherit_identity(group) diff --git a/sched/group/group_getegid.c b/sched/group/group_getegid.c new file mode 100644 index 0000000000..0d4d070b4b --- /dev/null +++ b/sched/group/group_getegid.c @@ -0,0 +1,61 @@ +/**************************************************************************** + * sched/group/group_getegid.c + * + * 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 + +#include +#include +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: getegid + * + * Description: + * The getegid() function will return the effective group ID of the calling + * task group. + * + * Input Parameters: + * None. + * + * Returned Value: + * The effective group ID of the calling task group. + * + ****************************************************************************/ + +gid_t getegid(void) +{ + FAR struct tcb_s *rtcb = this_task(); + FAR struct task_group_s *rgroup = rtcb->group; + + /* Set the task group's group identity. */ + + DEBUGASSERT(rgroup != NULL); + return rgroup->tg_egid; +} diff --git a/sched/group/group_geteuid.c b/sched/group/group_geteuid.c new file mode 100644 index 0000000000..7bf2b7e624 --- /dev/null +++ b/sched/group/group_geteuid.c @@ -0,0 +1,61 @@ +/**************************************************************************** + * sched/group/group_geteuid.c + * + * 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 + +#include +#include +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: geteuid + * + * Description: + * The geteuid() function will return the effective user ID of the calling + * process. + * + * Input Parameters: + * None + * + * Returned Value: + * The effective user ID of the calling task group. + * + ****************************************************************************/ + +uid_t geteuid(void) +{ + FAR struct tcb_s *rtcb = this_task(); + FAR struct task_group_s *rgroup = rtcb->group; + + /* Set the task group's group identity. */ + + DEBUGASSERT(rgroup != NULL); + return rgroup->tg_euid; +} diff --git a/sched/group/group_setegid.c b/sched/group/group_setegid.c new file mode 100644 index 0000000000..95b570b3ea --- /dev/null +++ b/sched/group/group_setegid.c @@ -0,0 +1,84 @@ +/**************************************************************************** + * sched/group/group_setegid.c + * + * 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 + +#include +#include +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: setegid + * + * Description: + * The setegid() function sets the effective group ID of the calling + * process to gid, given appropriate privileges. + * + * Input Parameters: + * gid - Identity to set the various process's group ID attributes to. + * + * Returned Value: + * Zero if successful and -1 in case of failure, in which case errno is set + * to one of he following values: + * + * EINVAL - The value of the uid argument is invalid and not supported by + * the implementation. + * EPERM - The process does not have appropriate privileges and uid does + * not match the effective group ID or the saved set-group-ID. + * + ****************************************************************************/ + +int setegid(gid_t gid) +{ + FAR struct tcb_s *rtcb; + FAR struct task_group_s *rgroup; + + /* Verify that the GID is in the valid range of 0 through INT16_MAX. + * OpenGroup.org does not specify a GID_MAX or GID_MIN. Instead we use a + * priori knowledge that gid_t is type int16_t. + */ + + if ((uint16_t)gid > INT16_MAX) + { + set_errno(EINVAL); + return ERROR; + } + + /* Get the currently executing thread's task group. */ + + rtcb = this_task(); + rgroup = rtcb->group; + + /* Set the task group's group identity. */ + + DEBUGASSERT(rgroup != NULL); + rgroup->tg_egid = gid; + return OK; +} diff --git a/sched/group/group_seteuid.c b/sched/group/group_seteuid.c new file mode 100644 index 0000000000..73c9c577ac --- /dev/null +++ b/sched/group/group_seteuid.c @@ -0,0 +1,86 @@ +/**************************************************************************** + * sched/group/group_seteuid.c + * + * 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 + +#include +#include +#include +#include + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: seteuid + * + * Description: + * The seteuid() function sets the effective user ID of the calling process + * to uid, given appropriate privileges. + * + * Input Parameters: + * uid - User identity to set the various process's effective user ID + * attributes to. + * + * Returned Value: + * Zero if successful and -1 in case of failure, in which case errno is set + * to one of he following values: + * + * EINVAL - The value of the uid argument is invalid and not supported by + * the implementation. + * EPERM - The process does not have appropriate privileges and uid does + * not match the effective user ID or the saved set-user-ID. + * + ****************************************************************************/ + +int seteuid(uid_t uid) +{ + FAR struct tcb_s *rtcb; + FAR struct task_group_s *rgroup; + + /* Verify that the UID is in the valid range of 0 through INT16_MAX. + * OpenGroup.org does not specify a UID_MAX or UID_MIN. Instead we use a + * priori knowledge that uid_t is type int16_t. + */ + + if ((uint16_t)uid > INT16_MAX) + { + set_errno(EINVAL); + return ERROR; + } + + /* Get the currently executing thread's task group. */ + + rtcb = this_task(); + rgroup = rtcb->group; + + /* Set the task group's group identity. */ + + DEBUGASSERT(rgroup != NULL); + rgroup->tg_euid = uid; + return OK; +} diff --git a/syscall/syscall.csv b/syscall/syscall.csv index 7428e37f7d..3fea87ecd5 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -36,9 +36,9 @@ "ftruncate","unistd.h","","int","int","off_t" "futimens","sys/stat.h","","int","int","const struct timespec [2]|FAR const struct timespec *" "get_environ_ptr","stdlib.h","!defined(CONFIG_DISABLE_ENVIRON)","FAR char **" -"getegid","unistd.h","","gid_t" +"getegid","unistd.h","defined(CONFIG_SCHED_USER_IDENTITY)","gid_t" "getenv","stdlib.h","!defined(CONFIG_DISABLE_ENVIRON)","FAR char *","FAR const char *" -"geteuid","unistd.h","","uid_t" +"geteuid","unistd.h","defined(CONFIG_SCHED_USER_IDENTITY)","uid_t" "getgid","unistd.h","defined(CONFIG_SCHED_USER_IDENTITY)","gid_t" "gethostname","unistd.h","","int","FAR char *","size_t" "getitimer","sys/time.h","!defined(CONFIG_DISABLE_POSIX_TIMERS)","int","int","FAR struct itimerval *" @@ -150,9 +150,9 @@ "sendfile","sys/sendfile.h","","ssize_t","int","int","FAR off_t *","size_t" "sendmsg","sys/socket.h","defined(CONFIG_NET)","ssize_t","int","FAR struct msghdr *","int" "sendto","sys/socket.h","defined(CONFIG_NET)","ssize_t","int","FAR const void *","size_t","int","FAR const struct sockaddr *","socklen_t" -"setegid","unistd.h","","int","gid_t" +"setegid","unistd.h","defined(CONFIG_SCHED_USER_IDENTITY)","int","gid_t" "setenv","stdlib.h","!defined(CONFIG_DISABLE_ENVIRON)","int","FAR const char *","FAR const char *","int" -"seteuid","unistd.h","","int","uid_t" +"seteuid","unistd.h","defined(CONFIG_SCHED_USER_IDENTITY)","int","uid_t" "setgid","unistd.h","defined(CONFIG_SCHED_USER_IDENTITY)","int","gid_t" "sethostname","unistd.h","","int","FAR const char *","size_t" "setitimer","sys/time.h","!defined(CONFIG_DISABLE_POSIX_TIMERS)","int","int","FAR const struct itimerval *","FAR struct itimerval *"