mirror of
https://github.com/apache/nuttx.git
synced 2026-10-02 19:58:01 +00:00
fs: add chroot() syscall
Add CONFIG_FS_CHROOT and POSIX chroot(). Store the jail as an absolute path on the task group, and require euid 0 when user identity is enabled. Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
This commit is contained in:
parent
a0adad6602
commit
2977db2632
6 changed files with 155 additions and 0 deletions
12
fs/Kconfig
12
fs/Kconfig
|
|
@ -105,6 +105,18 @@ config FS_PIN
|
|||
The pin is held for as long as the module is loaded and given back
|
||||
when it is unloaded.
|
||||
|
||||
config FS_CHROOT
|
||||
bool "chroot() filesystem jail"
|
||||
default n
|
||||
---help---
|
||||
Enable POSIX chroot(). Each task group may pin a directory as its
|
||||
root; absolute path lookup starts there so the group cannot see
|
||||
files outside that tree. This is a filesystem jail, not a
|
||||
container (open file descriptors that already point outside the
|
||||
tree remain usable). Nested chroot() is relative to the current
|
||||
root. When SCHED_USER_IDENTITY is enabled, chroot() requires
|
||||
effective UID 0.
|
||||
|
||||
config FS_PERMISSION
|
||||
bool "Enable UNIX Filesystem Permission Support"
|
||||
default n
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@ set(SRCS
|
|||
fs_truncate.c
|
||||
fs_link.c)
|
||||
|
||||
if(CONFIG_FS_CHROOT)
|
||||
list(APPEND SRCS fs_chroot.c)
|
||||
endif()
|
||||
|
||||
# File notify support
|
||||
|
||||
if(CONFIG_FS_NOTIFY)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@ CSRCS += fs_rename.c fs_rmdir.c fs_select.c fs_sendfile.c fs_stat.c
|
|||
CSRCS += fs_statfs.c fs_uio.c fs_unlink.c fs_write.c fs_dir.c fs_fsync.c
|
||||
CSRCS += fs_syncfs.c fs_truncate.c fs_link.c
|
||||
|
||||
ifeq ($(CONFIG_FS_CHROOT),y)
|
||||
CSRCS += fs_chroot.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_FS_NOTIFY),y)
|
||||
CSRCS += fs_inotify.c
|
||||
endif
|
||||
|
|
|
|||
131
fs/vfs/fs_chroot.c
Normal file
131
fs/vfs/fs_chroot.c
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
/****************************************************************************
|
||||
* fs/vfs/fs_chroot.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/stat.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/sched.h>
|
||||
|
||||
#include "inode/inode.h"
|
||||
#include "fs_heap.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: chroot
|
||||
*
|
||||
* Description:
|
||||
* Cause the named directory to become the root directory, that is, the
|
||||
* starting point for path names beginning with '/'.
|
||||
*
|
||||
* Input Parameters:
|
||||
* path - Directory to use as the new root
|
||||
*
|
||||
* Returned Value:
|
||||
* 0(OK) on success; -1(ERROR) on failure with errno set appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int chroot(FAR const char *path)
|
||||
{
|
||||
FAR struct tcb_s *rtcb;
|
||||
FAR struct task_group_s *group;
|
||||
FAR char *newroot;
|
||||
struct inode_search_s desc;
|
||||
struct stat buf;
|
||||
int ret;
|
||||
|
||||
if (path == NULL || path[0] == '\0')
|
||||
{
|
||||
set_errno(ENOENT);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
rtcb = nxsched_self();
|
||||
DEBUGASSERT(rtcb != NULL && rtcb->group != NULL);
|
||||
group = rtcb->group;
|
||||
|
||||
#ifdef CONFIG_SCHED_USER_IDENTITY
|
||||
if (group->tg_euid != 0)
|
||||
{
|
||||
set_errno(EPERM);
|
||||
return ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = stat(path, &buf);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (!S_ISDIR(buf.st_mode))
|
||||
{
|
||||
set_errno(ENOTDIR);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Resolve to a host absolute path the same way lookups do: make
|
||||
* absolute, prepend the current jail, and canonicalize. No second
|
||||
* inode walk.
|
||||
*/
|
||||
|
||||
ret = inode_search_setup(&desc, path, true);
|
||||
if (ret < 0)
|
||||
{
|
||||
set_errno(-ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Host "/" means no jail. Clear any previous root. */
|
||||
|
||||
if (strcmp(desc.path, "/") == 0)
|
||||
{
|
||||
fs_heap_free(group->tg_root);
|
||||
group->tg_root = NULL;
|
||||
inode_search_release(&desc);
|
||||
return OK;
|
||||
}
|
||||
|
||||
newroot = fs_heap_strdup(desc.path);
|
||||
inode_search_release(&desc);
|
||||
if (newroot == NULL)
|
||||
{
|
||||
set_errno(ENOMEM);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
fs_heap_free(group->tg_root);
|
||||
group->tg_root = newroot;
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -428,6 +428,9 @@ unsigned int alarm(unsigned int seconds);
|
|||
|
||||
int chdir(FAR const char *path);
|
||||
int fchdir(int fd);
|
||||
#ifdef CONFIG_FS_CHROOT
|
||||
int chroot(FAR const char *path);
|
||||
#endif
|
||||
FAR char *getcwd(FAR char *buf, size_t size);
|
||||
FAR char *get_current_dir_name(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
"boardctl","sys/boardctl.h","defined(CONFIG_BOARDCTL)","int","unsigned int","uintptr_t"
|
||||
"chmod","sys/stat.h","","int","FAR const char *","mode_t"
|
||||
"chown","unistd.h","","int","FAR const char *","uid_t","gid_t"
|
||||
"chroot","unistd.h","defined(CONFIG_FS_CHROOT)","int","FAR const char *"
|
||||
"clearenv","stdlib.h","!defined(CONFIG_DISABLE_ENVIRON)","int"
|
||||
"clock","time.h","","clock_t"
|
||||
"clock_adjtime","sys/timex.h","defined(CONFIG_CLOCK_ADJTIME)","int","clockid_t","struct timex *"
|
||||
|
|
|
|||
|
Can't render this file because it has a wrong number of fields in line 2.
|
Loading…
Add table
Add a link
Reference in a new issue