nshlib: add chroot command

chdir into the new root, call chroot("."), then chdir("/") so relative
paths stay in the jail. With a command, execvp() after the jail is set.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
This commit is contained in:
Abhishek Mishra 2026-08-19 08:07:17 +00:00 committed by Xiang Xiao
parent 68aa7a838b
commit bcf2cd1795
4 changed files with 71 additions and 0 deletions

View file

@ -361,6 +361,11 @@ config NSH_DISABLE_CD
bool "Disable cd"
default DEFAULT_SMALL
config NSH_DISABLE_CHROOT
bool "Disable chroot"
default DEFAULT_SMALL
depends on FS_CHROOT
config NSH_DISABLE_CHMOD
bool "Disable chmod"
default DEFAULT_SMALL

View file

@ -1084,6 +1084,9 @@ int cmd_irqinfo(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv);
#ifndef CONFIG_NSH_DISABLE_CD
int cmd_cd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv);
#endif
#if defined(CONFIG_FS_CHROOT) && !defined(CONFIG_NSH_DISABLE_CHROOT)
int cmd_chroot(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv);
#endif
#ifndef CONFIG_NSH_DISABLE_PWD
int cmd_pwd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv);
#endif

View file

@ -168,6 +168,11 @@ static const struct cmdmap_s g_cmdmap[] =
CMD_MAP("cd", cmd_cd, 1, 2, "[<dir-path>|-|~|..]"),
#endif
#if defined(CONFIG_FS_CHROOT) && !defined(CONFIG_NSH_DISABLE_CHROOT)
CMD_MAP("chroot", cmd_chroot, 2, CONFIG_NSH_MAXARGUMENTS,
"<newroot> [<command> [args...]]"),
#endif
#if defined(CONFIG_FS_PERMISSION) && !defined(CONFIG_NSH_DISABLE_CHMOD)
CMD_MAP("chmod", cmd_chmod, 3, 3, "<octal-mode> <path>"),
#endif

View file

@ -324,6 +324,64 @@ errout:
}
#endif
/****************************************************************************
* Name: cmd_chroot
****************************************************************************/
#if defined(CONFIG_FS_CHROOT) && !defined(CONFIG_NSH_DISABLE_CHROOT)
int cmd_chroot(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv)
{
FAR char *fullpath;
int ret;
fullpath = nsh_getfullpath(vtbl, argv[1]);
if (fullpath == NULL)
{
nsh_error(vtbl, g_fmtcmdoutofmemory, argv[0]);
return ERROR;
}
ret = chdir(fullpath);
nsh_freefullpath(fullpath);
if (ret < 0)
{
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "chdir", NSH_ERRNO);
return ERROR;
}
ret = chroot(".");
if (ret < 0)
{
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "chroot", NSH_ERRNO);
return ERROR;
}
ret = chdir("/");
if (ret < 0)
{
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "chdir", NSH_ERRNO);
return ERROR;
}
#ifdef CONFIG_LIBC_EXECFUNCS
if (argc > 2)
{
execvp(argv[2], &argv[2]);
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "execvp", NSH_ERRNO);
return ERROR;
}
#else
if (argc > 2)
{
nsh_error(vtbl, g_fmtcmdfailed, argv[0], "execvp", NSH_ERRNO);
return ERROR;
}
#endif
return OK;
}
#endif /* CONFIG_FS_CHROOT && !CONFIG_NSH_DISABLE_CHROOT */
/****************************************************************************
* Name: cmd_echo
****************************************************************************/