From 903e87a7bdb2ac9644ef059437e69919b9972a57 Mon Sep 17 00:00:00 2001 From: fangxinyong Date: Sat, 12 Aug 2023 07:39:45 +0800 Subject: [PATCH] builtin: support uid/gid config for binfs app Implement I_SUID/I_SGID feature for binfs in the POSIX compliant way. If set-user-ID bit is set in the file permissions, then the effective user ID of process shall be set to UID of the new process image file. test case: hello example emulates to set uid and file set-user-ID bit, and call geteuid and getegid API. UID = 2000 GID = 3000 MODE = 06555 nsh> ls -l /bin/hello -r-sr-sr-x 2000 3000 0 hello nsh> hello geteuid:2000 getegid:3000 Signed-off-by: fangxinyong --- binfmt/builtin.c | 6 +++ fs/binfs/fs_binfs.c | 10 +++- include/nuttx/lib/builtin.h | 63 +++++++++++++++++++++++++ libs/libc/builtin/Make.defs | 4 ++ libs/libc/builtin/lib_builtin_getgid.c | 63 +++++++++++++++++++++++++ libs/libc/builtin/lib_builtin_getmode.c | 63 +++++++++++++++++++++++++ libs/libc/builtin/lib_builtin_getuid.c | 63 +++++++++++++++++++++++++ 7 files changed, 271 insertions(+), 1 deletion(-) create mode 100644 libs/libc/builtin/lib_builtin_getgid.c create mode 100644 libs/libc/builtin/lib_builtin_getmode.c create mode 100644 libs/libc/builtin/lib_builtin_getuid.c diff --git a/binfmt/builtin.c b/binfmt/builtin.c index 9ba1b59d8a..772068acd3 100644 --- a/binfmt/builtin.c +++ b/binfmt/builtin.c @@ -106,6 +106,12 @@ static int builtin_loadbinary(FAR struct binary_s *binp, binp->entrypt = builtin->main; binp->stacksize = builtin->stacksize; binp->priority = builtin->priority; +#ifdef CONFIG_SCHED_USER_IDENTITY + binp->uid = builtin->uid; + binp->gid = builtin->gid; + binp->mode = builtin->mode; +#endif + return OK; } diff --git a/fs/binfs/fs_binfs.c b/fs/binfs/fs_binfs.c index 31635b123b..0b8d309027 100644 --- a/fs/binfs/fs_binfs.c +++ b/fs/binfs/fs_binfs.c @@ -469,6 +469,7 @@ static int binfs_stat(struct inode *mountpt, const char *relpath, struct stat *buf) { finfo("Entry\n"); + int index; /* The requested directory must be the volume-relative "root" directory */ @@ -476,7 +477,8 @@ static int binfs_stat(struct inode *mountpt, { /* Check if there is a file with this name. */ - if (builtin_isavail(relpath) < 0) + index = builtin_isavail(relpath); + if (index < 0) { return -ENOENT; } @@ -484,6 +486,12 @@ static int binfs_stat(struct inode *mountpt, /* It's a execute-only file name */ buf->st_mode = S_IFREG | S_IXOTH | S_IXGRP | S_IXUSR; + +#ifdef CONFIG_SCHED_USER_IDENTITY + buf->st_uid = builtin_getuid(index); + buf->st_gid = builtin_getgid(index); + buf->st_mode |= builtin_getmode(index); +#endif } else { diff --git a/include/nuttx/lib/builtin.h b/include/nuttx/lib/builtin.h index 7fdd27ad31..4b9baf68f7 100644 --- a/include/nuttx/lib/builtin.h +++ b/include/nuttx/lib/builtin.h @@ -40,6 +40,11 @@ struct builtin_s int priority; /* Use: SCHED_PRIORITY_DEFAULT */ int stacksize; /* Desired stack size */ main_t main; /* Entry point: main(int argc, char *argv[]) */ +#ifdef CONFIG_SCHED_USER_IDENTITY + uid_t uid; /* File owner user identity */ + gid_t gid; /* File owner group identity */ + int mode; /* File mode added to */ +#endif }; /**************************************************************************** @@ -171,6 +176,64 @@ FAR const char *builtin_getname(int index); FAR const struct builtin_s *builtin_for_index(int index); +#ifdef CONFIG_SCHED_USER_IDENTITY + +/**************************************************************************** + * Name: builtin_getuid + * + * Description: + * Returns file uid of the application at 'index' in the table + * of built-in applications. + * + * Input Parameters: + * index - From 0 and on ... + * + * Returned Value: + * Returns valid uid for app if index is valid. + * Otherwise 0 is returned. + * + ****************************************************************************/ + +uid_t builtin_getuid(int index); + +/**************************************************************************** + * Name: builtin_getgid + * + * Description: + * Returns file gid of the application at 'index' in the table + * of built-in applications. + * + * Input Parameters: + * index - From 0 and on ... + * + * Returned Value: + * Returns valid gid for app if index is valid. + * Otherwise 0 is returned. + * + ****************************************************************************/ + +gid_t builtin_getgid(int index); + +/**************************************************************************** + * Name: builtin_getmode + * + * Description: + * Returns file mode of the application at 'index' in the table + * of built-in applications. + * + * Input Parameters: + * index - From 0 and on ... + * + * Returned Value: + * Returns valid mode for app if index is valid. + * Otherwise 0 is returned. + * + ****************************************************************************/ + +int builtin_getmode(int index); + +#endif + #undef EXTERN #if defined(__cplusplus) } diff --git a/libs/libc/builtin/Make.defs b/libs/libc/builtin/Make.defs index 88b71505da..b9c864e290 100644 --- a/libs/libc/builtin/Make.defs +++ b/libs/libc/builtin/Make.defs @@ -28,6 +28,10 @@ ifeq ($(CONFIG_BUILD_PROTECTED),y) CSRCS += lib_builtin_setlist.c endif +ifeq ($(CONFIG_SCHED_USER_IDENTITY),y) +CSRCS += lib_builtin_getuid.c lib_builtin_getgid.c lib_builtin_getmode.c +endif + # Hook the builtin subdirectory into the build DEPPATH += --dep-path builtin diff --git a/libs/libc/builtin/lib_builtin_getgid.c b/libs/libc/builtin/lib_builtin_getgid.c new file mode 100644 index 0000000000..1c7dddbd57 --- /dev/null +++ b/libs/libc/builtin/lib_builtin_getgid.c @@ -0,0 +1,63 @@ +/**************************************************************************** + * libs/libc/builtin/lib_builtin_getgid.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 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: builtin_getgid + * + * Description: + * Returns file gid of the application at 'index' in the table + * of built-in applications. + * + * Input Parameters: + * index - From 0 and on ... + * + * Returned Value: + * Returns valid gid for app if index is valid. + * Otherwise 0 is returned. + * + ****************************************************************************/ + +gid_t builtin_getgid(int index) +{ + FAR const struct builtin_s *builtin; + + builtin = builtin_for_index(index); + + if (builtin != NULL) + { + return builtin->gid; + } + + /* Return group user identity 'root' with a gid value of 0. */ + + return 0; +} diff --git a/libs/libc/builtin/lib_builtin_getmode.c b/libs/libc/builtin/lib_builtin_getmode.c new file mode 100644 index 0000000000..3ea5fe77e9 --- /dev/null +++ b/libs/libc/builtin/lib_builtin_getmode.c @@ -0,0 +1,63 @@ +/**************************************************************************** + * libs/libc/builtin/lib_builtin_getmode.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 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: builtin_getmode + * + * Description: + * Returns file mode of the application at 'index' in the table + * of built-in applications. + * + * Input Parameters: + * index - From 0 and on ... + * + * Returned Value: + * Returns valid mode for app if index is valid. + * Otherwise 0 is returned. + * + ****************************************************************************/ + +int builtin_getmode(int index) +{ + FAR const struct builtin_s *builtin; + + builtin = builtin_for_index(index); + + if (builtin != NULL) + { + return builtin->mode; + } + + /* Return the default mode value of 0. */ + + return 0; +} diff --git a/libs/libc/builtin/lib_builtin_getuid.c b/libs/libc/builtin/lib_builtin_getuid.c new file mode 100644 index 0000000000..a88fd6d72b --- /dev/null +++ b/libs/libc/builtin/lib_builtin_getuid.c @@ -0,0 +1,63 @@ +/**************************************************************************** + * libs/libc/builtin/lib_builtin_getuid.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 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: builtin_getuid + * + * Description: + * Returns file uid of the application at 'index' in the table + * of built-in applications. + * + * Input Parameters: + * index - From 0 and on ... + * + * Returned Value: + * Returns valid uid for app if index is valid. + * Otherwise 0 is returned. + * + ****************************************************************************/ + +uid_t builtin_getuid(int index) +{ + FAR const struct builtin_s *builtin; + + builtin = builtin_for_index(index); + + if (builtin != NULL) + { + return builtin->uid; + } + + /* Return user identity 'root' with a uid value of 0. */ + + return 0; +}