fix: L1 toybox 命令功能实现
【背景】 解决toybox已支持命令的遗留问题,新增命令功能。 【修改方案】 1. 在内核态对toybox的系统调用进行支持。 【影响】 对现有的产品编译不会有影响。 re #I41N2A Signed-off-by: wangchen <253227059@qq.com>
This commit is contained in:
parent
d79fd50693
commit
2ff44c4938
|
@ -36,7 +36,7 @@
|
|||
#include "sys/utsname.h"
|
||||
#include "mqueue.h"
|
||||
#include "semaphore.h"
|
||||
|
||||
#include "los_hw.h"
|
||||
|
||||
/*
|
||||
* Supply some suitable values for constants that may not be present
|
||||
|
@ -52,17 +52,27 @@
|
|||
int uname(struct utsname *name)
|
||||
{
|
||||
INT32 ret;
|
||||
const char *cpuInfo = NULL;
|
||||
|
||||
if (name == NULL) {
|
||||
return -EFAULT;
|
||||
}
|
||||
(VOID)strncpy_s(name->sysname, sizeof(name->sysname), KERNEL_NAME, strlen(KERNEL_NAME) + 1);
|
||||
(VOID)strncpy_s(name->nodename, sizeof(name->nodename), "hisilicon", strlen("hisilicon") + 1);
|
||||
ret = snprintf_s(name->version, sizeof(name->version), sizeof(name->version) - 1, "%s %u.%u.%u.%u %s %s\n",
|
||||
ret = snprintf_s(name->version, sizeof(name->version), sizeof(name->version) - 1, "%s %u.%u.%u.%u %s %s",
|
||||
KERNEL_NAME, KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE, __DATE__, __TIME__);
|
||||
if (ret < 0) {
|
||||
return -EIO;
|
||||
}
|
||||
name->machine[0] = '\0';
|
||||
|
||||
cpuInfo = LOS_CpuInfo();
|
||||
(VOID)strncpy_s(name->machine, sizeof(name->machine), cpuInfo, sizeof(name->machine));
|
||||
ret = snprintf_s(name->release, sizeof(name->release), sizeof(name->release) - 1, "%u.%u.%u.%u",
|
||||
KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE);
|
||||
if (ret < 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
name->domainname[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -29,11 +29,13 @@
|
|||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "syscall_pub.h"
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
#include "errno.h"
|
||||
#include "unistd.h"
|
||||
#include "fs/fd_table.h"
|
||||
#include "fs/file.h"
|
||||
#include "fs/fs.h"
|
||||
#include "fs/fs_operation.h"
|
||||
#include "sys/mount.h"
|
||||
#include "los_task_pri.h"
|
||||
|
@ -56,29 +58,77 @@
|
|||
#include "sys/statfs.h"
|
||||
|
||||
#define HIGH_SHIFT_BIT 32
|
||||
#define TIMESPEC_TIMES_NUM 2
|
||||
|
||||
static int UserPathCopy(const char *userPath, char **pathBuf)
|
||||
static int CheckNewAttrTime(struct IATTR *attr, struct timespec times[TIMESPEC_TIMES_NUM])
|
||||
{
|
||||
int ret = ENOERR;
|
||||
struct timespec stp = {0};
|
||||
|
||||
if (times) {
|
||||
if (times[0].tv_nsec == UTIME_OMIT) {
|
||||
attr->attr_chg_valid &= ~CHG_ATIME;
|
||||
} else if (times[0].tv_nsec == UTIME_NOW) {
|
||||
ret = clock_gettime(CLOCK_REALTIME, &stp);
|
||||
if (ret < 0) {
|
||||
return -get_errno();
|
||||
}
|
||||
attr->attr_chg_atime = (unsigned int)stp.tv_sec;
|
||||
attr->attr_chg_valid |= CHG_ATIME;
|
||||
} else {
|
||||
attr->attr_chg_atime = (unsigned int)times[0].tv_sec;
|
||||
attr->attr_chg_valid |= CHG_ATIME;
|
||||
}
|
||||
|
||||
if (times[1].tv_nsec == UTIME_OMIT) {
|
||||
attr->attr_chg_valid &= ~CHG_MTIME;
|
||||
} else if (times[1].tv_nsec == UTIME_NOW) {
|
||||
ret = clock_gettime(CLOCK_REALTIME, &stp);
|
||||
if (ret < 0) {
|
||||
return -get_errno();
|
||||
}
|
||||
attr->attr_chg_mtime = (unsigned int)stp.tv_sec;
|
||||
attr->attr_chg_valid |= CHG_MTIME;
|
||||
} else {
|
||||
attr->attr_chg_mtime = (unsigned int)times[1].tv_sec;
|
||||
attr->attr_chg_valid |= CHG_MTIME;
|
||||
}
|
||||
} else {
|
||||
ret = clock_gettime(CLOCK_REALTIME, &stp);
|
||||
if (ret < 0) {
|
||||
return -get_errno();
|
||||
}
|
||||
attr->attr_chg_atime = (unsigned int)stp.tv_sec;
|
||||
attr->attr_chg_mtime = (unsigned int)stp.tv_sec;
|
||||
attr->attr_chg_valid |= CHG_ATIME;
|
||||
attr->attr_chg_valid |= CHG_MTIME;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int GetFullpathNull(int fd, const char *path, char **filePath)
|
||||
{
|
||||
int ret;
|
||||
char *fullPath = NULL;
|
||||
struct file *file = NULL;
|
||||
|
||||
*pathBuf = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, PATH_MAX + 1);
|
||||
if (*pathBuf == NULL) {
|
||||
return -ENOMEM;
|
||||
if ((fd != AT_FDCWD) && (path == NULL)) {
|
||||
fd = GetAssociatedSystemFd(fd);
|
||||
ret = fs_getfilep(fd, &file);
|
||||
if (ret < 0) {
|
||||
return -get_errno();
|
||||
}
|
||||
fullPath = file->f_path;
|
||||
} else {
|
||||
ret = GetFullpath(fd, path, &fullPath);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = LOS_StrncpyFromUser(*pathBuf, userPath, PATH_MAX + 1);
|
||||
if (ret < 0) {
|
||||
(void)LOS_MemFree(OS_SYS_MEM_ADDR, *pathBuf);
|
||||
*pathBuf = NULL;
|
||||
return ret;
|
||||
} else if (ret > PATH_MAX) {
|
||||
(void)LOS_MemFree(OS_SYS_MEM_ADDR, *pathBuf);
|
||||
*pathBuf = NULL;
|
||||
return -ENAMETOOLONG;
|
||||
}
|
||||
(*pathBuf)[ret] = '\0';
|
||||
|
||||
return 0;
|
||||
*filePath = fullPath;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int UserIovItemCheck(const struct iovec *iov, const int iovcnt)
|
||||
|
@ -2124,6 +2174,37 @@ OUT:
|
|||
return result;
|
||||
}
|
||||
|
||||
int SysUtimensat(int fd, const char *path, struct timespec times[TIMESPEC_TIMES_NUM], int flag)
|
||||
{
|
||||
int ret;
|
||||
int timeLen;
|
||||
struct IATTR attr = {0};
|
||||
char *filePath = NULL;
|
||||
|
||||
timeLen = TIMESPEC_TIMES_NUM * sizeof(struct timespec);
|
||||
CHECK_ASPACE(times, timeLen);
|
||||
DUP_FROM_USER(times, timeLen);
|
||||
ret = CheckNewAttrTime(&attr, times);
|
||||
FREE_DUP(times);
|
||||
if (ret < 0) {
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
ret = GetFullpathNull(fd, path, &filePath);
|
||||
if (ret < 0) {
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
ret = chattr(filePath, &attr);
|
||||
if (ret < 0) {
|
||||
ret = -get_errno();
|
||||
}
|
||||
|
||||
OUT:
|
||||
PointerFree(filePath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SysChmod(const char *pathname, mode_t mode)
|
||||
{
|
||||
int ret;
|
||||
|
@ -2148,6 +2229,112 @@ OUT:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int SysFchmodat(int fd, const char *path, mode_t mode, int flag)
|
||||
{
|
||||
int ret;
|
||||
char *pathRet = NULL;
|
||||
char *fullpath = NULL;
|
||||
struct IATTR attr = {
|
||||
.attr_chg_mode = mode,
|
||||
.attr_chg_valid = CHG_MODE,
|
||||
};
|
||||
|
||||
if (path != NULL) {
|
||||
ret = UserPathCopy(path, &pathRet);
|
||||
if (ret != 0) {
|
||||
goto OUT;
|
||||
}
|
||||
}
|
||||
|
||||
if (fd != AT_FDCWD) {
|
||||
/* Process fd convert to system global fd */
|
||||
fd = GetAssociatedSystemFd(fd);
|
||||
}
|
||||
|
||||
ret = vfs_normalize_pathat(fd, pathRet, &fullpath);
|
||||
if (ret < 0) {
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
ret = chattr(fullpath, &attr);
|
||||
if (ret < 0) {
|
||||
ret = -get_errno();
|
||||
}
|
||||
|
||||
OUT:
|
||||
PointerFree(pathRet);
|
||||
PointerFree(fullpath);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SysFchownat(int fd, const char *path, uid_t owner, gid_t group, int flag)
|
||||
{
|
||||
int ret;
|
||||
char *fullpath = NULL;
|
||||
struct IATTR attr = {
|
||||
.attr_chg_valid = 0,
|
||||
};
|
||||
|
||||
ret = GetFullpath(fd, path, &fullpath);
|
||||
if (ret < 0) {
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
if (owner != (uid_t)-1) {
|
||||
attr.attr_chg_uid = owner;
|
||||
attr.attr_chg_valid |= CHG_UID;
|
||||
}
|
||||
if (group != (gid_t)-1) {
|
||||
attr.attr_chg_gid = group;
|
||||
attr.attr_chg_valid |= CHG_GID;
|
||||
}
|
||||
|
||||
ret = chattr(fullpath, &attr);
|
||||
if (ret < 0) {
|
||||
ret = -get_errno();
|
||||
}
|
||||
|
||||
OUT:
|
||||
PointerFree(fullpath);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SysFchown(int fd, uid_t owner, gid_t group)
|
||||
{
|
||||
int ret;
|
||||
int sysFd;
|
||||
struct IATTR attr = {0};
|
||||
attr.attr_chg_valid = 0;
|
||||
struct file *file = NULL;
|
||||
|
||||
sysFd = GetAssociatedSystemFd(fd);
|
||||
if (sysFd < 0) {
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
ret = fs_getfilep(sysFd, &file);
|
||||
if (ret < 0) {
|
||||
return -get_errno();
|
||||
}
|
||||
|
||||
if (owner != (uid_t)-1) {
|
||||
attr.attr_chg_uid = owner;
|
||||
attr.attr_chg_valid |= CHG_UID;
|
||||
}
|
||||
if (group != (gid_t)-1) {
|
||||
attr.attr_chg_gid = group;
|
||||
attr.attr_chg_valid |= CHG_GID;
|
||||
}
|
||||
ret = chattr(file->f_path, &attr);
|
||||
if (ret < 0) {
|
||||
ret = -get_errno();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SysChown(const char *pathname, uid_t owner, gid_t group)
|
||||
{
|
||||
int ret;
|
||||
|
@ -2218,4 +2405,43 @@ OUT:
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SysFaccessat(int fd, const char *filename, int amode, int flag)
|
||||
{
|
||||
int ret;
|
||||
struct stat buf;
|
||||
struct statfs fsBuf;
|
||||
char *fullDirectory = NULL;
|
||||
|
||||
ret = GetFullpath(fd, filename, &fullDirectory);
|
||||
if (ret < 0) {
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
ret = statfs(fullDirectory, &fsBuf);
|
||||
if (ret != 0) {
|
||||
ret = -get_errno();
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
if ((fsBuf.f_flags & MS_RDONLY) && ((unsigned int)amode & W_OK)) {
|
||||
ret = -EROFS;
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
ret = stat(fullDirectory, &buf);
|
||||
if (ret != 0) {
|
||||
ret = -get_errno();
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
if (VfsPermissionCheck(buf.st_uid, buf.st_gid, buf.st_mode, amode)) {
|
||||
ret = -EACCES;
|
||||
}
|
||||
|
||||
OUT:
|
||||
PointerFree(fullDirectory);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#define _GNU_SOURCE
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
#include "fs/file.h"
|
||||
#include "fs/file.h"
|
||||
#endif
|
||||
#include "los_init.h"
|
||||
#include "los_signal.h"
|
||||
|
|
|
@ -230,7 +230,11 @@ extern ssize_t SysReadlinkat(int dirfd, const char *pathname, char *buf, size_t
|
|||
extern int SysUnlink( const char *pathname);
|
||||
extern int SysExecve(const char *fileName, char *const *argv, char *const *envp);
|
||||
extern int SysChdir(const char *path);
|
||||
extern int SysUtimensat(int fd, const char *path, struct timespec times[2], int flag);
|
||||
extern int SysFchmodat(int fd, const char *path, mode_t mode, int flag);
|
||||
extern int SysChmod(const char *path, mode_t mode);
|
||||
extern int SysFchownat(int fd, const char *path, uid_t owner, gid_t group, int flag);
|
||||
extern int SysFchown(int fd, uid_t owner, gid_t group);
|
||||
extern int SysChown(const char *pathname, uid_t owner, gid_t group);
|
||||
extern off_t SysLseek(int fd, off_t offset, int whence);
|
||||
extern off64_t SysLseek64(int fd, int offsetHigh, int offsetLow, off64_t *result, int whence);
|
||||
|
@ -238,6 +242,7 @@ extern int SysMount(const char *source, const char *target, const char *filesyst
|
|||
const void *data);
|
||||
extern int SysUmount(const char *target);
|
||||
extern int SysAccess(const char *path, int amode);
|
||||
extern int SysFaccessat(int fd, const char *filename, int amode, int flag);
|
||||
extern int SysRename(const char *oldpath, const char *newpath);
|
||||
extern int SysMkdir(const char *pathname, mode_t mode);
|
||||
extern int SysRmdir(const char *pathname);
|
||||
|
|
|
@ -48,11 +48,15 @@ SYSCALL_HAND_DEF(__NR_execve, SysExecve, int, ARG_NUM_3)
|
|||
|
||||
SYSCALL_HAND_DEF(__NR_sysinfo, SysInfo, int, ARG_NUM_1)
|
||||
SYSCALL_HAND_DEF(__NR_chdir, SysChdir, int, ARG_NUM_1)
|
||||
SYSCALL_HAND_DEF(__NR_utimensat, SysUtimensat, int, ARG_NUM_4)
|
||||
SYSCALL_HAND_DEF(__NR_fchmodat, SysFchmodat, int, ARG_NUM_4)
|
||||
SYSCALL_HAND_DEF(__NR_utimensat, SysUtimensat, int, ARG_NUM_4)
|
||||
SYSCALL_HAND_DEF(__NR_chmod, SysChmod, int, ARG_NUM_2)
|
||||
SYSCALL_HAND_DEF(__NR_lseek, SysLseek, off_t, ARG_NUM_7) /* current only support 32bit max 4G file */
|
||||
SYSCALL_HAND_DEF(__NR_mount, SysMount, int, ARG_NUM_5)
|
||||
SYSCALL_HAND_DEF(__NR_umount, SysUmount, int, ARG_NUM_1)
|
||||
SYSCALL_HAND_DEF(__NR_access, SysAccess, int, ARG_NUM_2)
|
||||
SYSCALL_HAND_DEF(__NR_faccessat, SysFaccessat, int, ARG_NUM_4)
|
||||
SYSCALL_HAND_DEF(__NR_sync, SysSync, void, ARG_NUM_0)
|
||||
SYSCALL_HAND_DEF(__NR_rename, SysRename, int, ARG_NUM_2)
|
||||
SYSCALL_HAND_DEF(__NR_mkdir, SysMkdir, int, ARG_NUM_2)
|
||||
|
@ -166,6 +170,8 @@ SYSCALL_HAND_DEF(__NR_rt_sigpending, SysSigPending, int, ARG_NUM_1)
|
|||
SYSCALL_HAND_DEF(__NR_rt_sigtimedwait, SysSigTimedWait, int, ARG_NUM_4)
|
||||
SYSCALL_HAND_DEF(__NR_rt_sigsuspend, SysSigSuspend, int, ARG_NUM_1)
|
||||
|
||||
SYSCALL_HAND_DEF(__NR_fchownat, SysFchownat, int, ARG_NUM_5)
|
||||
SYSCALL_HAND_DEF(__NR_fchown32, SysFchown, int, ARG_NUM_3)
|
||||
SYSCALL_HAND_DEF(__NR_chown, SysChown, int, ARG_NUM_3)
|
||||
SYSCALL_HAND_DEF(__NR_chown32, SysChown, int, ARG_NUM_3)
|
||||
#ifdef LOSCFG_SECURITY_CAPABILITY
|
||||
|
|
|
@ -60,3 +60,68 @@ void *DupUserMem(const void *ptr, size_t len, int needCopy)
|
|||
|
||||
return p;
|
||||
}
|
||||
|
||||
int GetFullpath(int fd, const char *path, char **fullpath)
|
||||
{
|
||||
int ret = 0;
|
||||
char *pathRet = NULL;
|
||||
struct file *file = NULL;
|
||||
struct stat bufRet = {0};
|
||||
|
||||
if (path != NULL) {
|
||||
ret = UserPathCopy(path, &pathRet);
|
||||
if (ret != 0) {
|
||||
goto OUT;
|
||||
}
|
||||
}
|
||||
|
||||
if ((pathRet != NULL) && (*pathRet == '/')) {
|
||||
*fullpath = pathRet;
|
||||
pathRet = NULL;
|
||||
} else {
|
||||
if (fd != AT_FDCWD) {
|
||||
/* Process fd convert to system global fd */
|
||||
fd = GetAssociatedSystemFd(fd);
|
||||
}
|
||||
ret = fs_getfilep(fd, &file);
|
||||
if (file) {
|
||||
ret = stat(file->f_path, &bufRet);
|
||||
if (!ret) {
|
||||
if (!S_ISDIR(bufRet.st_mode)) {
|
||||
set_errno(ENOTDIR);
|
||||
ret = -ENOTDIR;
|
||||
goto OUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = vfs_normalize_pathat(fd, pathRet, fullpath);
|
||||
}
|
||||
|
||||
OUT:
|
||||
PointerFree(pathRet);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int UserPathCopy(const char *userPath, char **pathBuf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
*pathBuf = (char *)LOS_MemAlloc(OS_SYS_MEM_ADDR, PATH_MAX + 1);
|
||||
if (*pathBuf == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = LOS_StrncpyFromUser(*pathBuf, userPath, PATH_MAX + 1);
|
||||
if (ret < 0) {
|
||||
(void)LOS_MemFree(OS_SYS_MEM_ADDR, *pathBuf);
|
||||
*pathBuf = NULL;
|
||||
return ret;
|
||||
} else if (ret > PATH_MAX) {
|
||||
(void)LOS_MemFree(OS_SYS_MEM_ADDR, *pathBuf);
|
||||
*pathBuf = NULL;
|
||||
return -ENAMETOOLONG;
|
||||
}
|
||||
(*pathBuf)[ret] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -36,9 +36,14 @@
|
|||
#include "los_vm_lock.h"
|
||||
#include "los_vm_map.h"
|
||||
#include "user_copy.h"
|
||||
#include "fs/fs.h"
|
||||
#include "fcntl.h"
|
||||
#include "los_strncpy_from_user.h"
|
||||
|
||||
extern int CheckRegion(const LosVmSpace *space, VADDR_T ptr, size_t len);
|
||||
extern void *DupUserMem(const void *ptr, size_t len, int needCopy);
|
||||
extern int GetFullpath(int fd, const char *path, char **fullpath);
|
||||
extern int UserPathCopy(const char *userPath, char **pathBuf);
|
||||
|
||||
#define CHECK_ASPACE(ptr, len, ...) \
|
||||
do { \
|
||||
|
|
Loading…
Reference in New Issue