|
@@ -11475,39 +11475,58 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
|
|
{
|
|
{
|
|
int gidsetsize = arg1;
|
|
int gidsetsize = arg1;
|
|
target_id *target_grouplist;
|
|
target_id *target_grouplist;
|
|
- gid_t *grouplist;
|
|
|
|
|
|
+ g_autofree gid_t *grouplist = NULL;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
- grouplist = alloca(gidsetsize * sizeof(gid_t));
|
|
|
|
|
|
+ if (gidsetsize > NGROUPS_MAX) {
|
|
|
|
+ return -TARGET_EINVAL;
|
|
|
|
+ }
|
|
|
|
+ if (gidsetsize > 0) {
|
|
|
|
+ grouplist = g_try_new(gid_t, gidsetsize);
|
|
|
|
+ if (!grouplist) {
|
|
|
|
+ return -TARGET_ENOMEM;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
ret = get_errno(getgroups(gidsetsize, grouplist));
|
|
ret = get_errno(getgroups(gidsetsize, grouplist));
|
|
- if (gidsetsize == 0)
|
|
|
|
- return ret;
|
|
|
|
- if (!is_error(ret)) {
|
|
|
|
- target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
|
|
|
|
- if (!target_grouplist)
|
|
|
|
|
|
+ if (!is_error(ret) && gidsetsize > 0) {
|
|
|
|
+ target_grouplist = lock_user(VERIFY_WRITE, arg2,
|
|
|
|
+ gidsetsize * sizeof(target_id), 0);
|
|
|
|
+ if (!target_grouplist) {
|
|
return -TARGET_EFAULT;
|
|
return -TARGET_EFAULT;
|
|
- for(i = 0;i < ret; i++)
|
|
|
|
|
|
+ }
|
|
|
|
+ for (i = 0; i < ret; i++) {
|
|
target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
|
|
target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
|
|
- unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
|
|
|
|
|
|
+ }
|
|
|
|
+ unlock_user(target_grouplist, arg2,
|
|
|
|
+ gidsetsize * sizeof(target_id));
|
|
}
|
|
}
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
- return ret;
|
|
|
|
case TARGET_NR_setgroups:
|
|
case TARGET_NR_setgroups:
|
|
{
|
|
{
|
|
int gidsetsize = arg1;
|
|
int gidsetsize = arg1;
|
|
target_id *target_grouplist;
|
|
target_id *target_grouplist;
|
|
- gid_t *grouplist = NULL;
|
|
|
|
|
|
+ g_autofree gid_t *grouplist = NULL;
|
|
int i;
|
|
int i;
|
|
- if (gidsetsize) {
|
|
|
|
- grouplist = alloca(gidsetsize * sizeof(gid_t));
|
|
|
|
- target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * sizeof(target_id), 1);
|
|
|
|
|
|
+
|
|
|
|
+ if (gidsetsize > NGROUPS_MAX || gidsetsize < 0) {
|
|
|
|
+ return -TARGET_EINVAL;
|
|
|
|
+ }
|
|
|
|
+ if (gidsetsize > 0) {
|
|
|
|
+ grouplist = g_try_new(gid_t, gidsetsize);
|
|
|
|
+ if (!grouplist) {
|
|
|
|
+ return -TARGET_ENOMEM;
|
|
|
|
+ }
|
|
|
|
+ target_grouplist = lock_user(VERIFY_READ, arg2,
|
|
|
|
+ gidsetsize * sizeof(target_id), 1);
|
|
if (!target_grouplist) {
|
|
if (!target_grouplist) {
|
|
return -TARGET_EFAULT;
|
|
return -TARGET_EFAULT;
|
|
}
|
|
}
|
|
for (i = 0; i < gidsetsize; i++) {
|
|
for (i = 0; i < gidsetsize; i++) {
|
|
grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
|
|
grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
|
|
}
|
|
}
|
|
- unlock_user(target_grouplist, arg2, 0);
|
|
|
|
|
|
+ unlock_user(target_grouplist, arg2,
|
|
|
|
+ gidsetsize * sizeof(target_id));
|
|
}
|
|
}
|
|
return get_errno(setgroups(gidsetsize, grouplist));
|
|
return get_errno(setgroups(gidsetsize, grouplist));
|
|
}
|
|
}
|
|
@@ -11792,41 +11811,59 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
|
|
{
|
|
{
|
|
int gidsetsize = arg1;
|
|
int gidsetsize = arg1;
|
|
uint32_t *target_grouplist;
|
|
uint32_t *target_grouplist;
|
|
- gid_t *grouplist;
|
|
|
|
|
|
+ g_autofree gid_t *grouplist = NULL;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
- grouplist = alloca(gidsetsize * sizeof(gid_t));
|
|
|
|
|
|
+ if (gidsetsize > NGROUPS_MAX) {
|
|
|
|
+ return -TARGET_EINVAL;
|
|
|
|
+ }
|
|
|
|
+ if (gidsetsize > 0) {
|
|
|
|
+ grouplist = g_try_new(gid_t, gidsetsize);
|
|
|
|
+ if (!grouplist) {
|
|
|
|
+ return -TARGET_ENOMEM;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
ret = get_errno(getgroups(gidsetsize, grouplist));
|
|
ret = get_errno(getgroups(gidsetsize, grouplist));
|
|
- if (gidsetsize == 0)
|
|
|
|
- return ret;
|
|
|
|
- if (!is_error(ret)) {
|
|
|
|
- target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
|
|
|
|
|
|
+ if (!is_error(ret) && gidsetsize > 0) {
|
|
|
|
+ target_grouplist = lock_user(VERIFY_WRITE, arg2,
|
|
|
|
+ gidsetsize * 4, 0);
|
|
if (!target_grouplist) {
|
|
if (!target_grouplist) {
|
|
return -TARGET_EFAULT;
|
|
return -TARGET_EFAULT;
|
|
}
|
|
}
|
|
- for(i = 0;i < ret; i++)
|
|
|
|
|
|
+ for (i = 0; i < ret; i++) {
|
|
target_grouplist[i] = tswap32(grouplist[i]);
|
|
target_grouplist[i] = tswap32(grouplist[i]);
|
|
|
|
+ }
|
|
unlock_user(target_grouplist, arg2, gidsetsize * 4);
|
|
unlock_user(target_grouplist, arg2, gidsetsize * 4);
|
|
}
|
|
}
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
- return ret;
|
|
|
|
#endif
|
|
#endif
|
|
#ifdef TARGET_NR_setgroups32
|
|
#ifdef TARGET_NR_setgroups32
|
|
case TARGET_NR_setgroups32:
|
|
case TARGET_NR_setgroups32:
|
|
{
|
|
{
|
|
int gidsetsize = arg1;
|
|
int gidsetsize = arg1;
|
|
uint32_t *target_grouplist;
|
|
uint32_t *target_grouplist;
|
|
- gid_t *grouplist;
|
|
|
|
|
|
+ g_autofree gid_t *grouplist = NULL;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
- grouplist = alloca(gidsetsize * sizeof(gid_t));
|
|
|
|
- target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
|
|
|
|
- if (!target_grouplist) {
|
|
|
|
- return -TARGET_EFAULT;
|
|
|
|
|
|
+ if (gidsetsize > NGROUPS_MAX || gidsetsize < 0) {
|
|
|
|
+ return -TARGET_EINVAL;
|
|
|
|
+ }
|
|
|
|
+ if (gidsetsize > 0) {
|
|
|
|
+ grouplist = g_try_new(gid_t, gidsetsize);
|
|
|
|
+ if (!grouplist) {
|
|
|
|
+ return -TARGET_ENOMEM;
|
|
|
|
+ }
|
|
|
|
+ target_grouplist = lock_user(VERIFY_READ, arg2,
|
|
|
|
+ gidsetsize * 4, 1);
|
|
|
|
+ if (!target_grouplist) {
|
|
|
|
+ return -TARGET_EFAULT;
|
|
|
|
+ }
|
|
|
|
+ for (i = 0; i < gidsetsize; i++) {
|
|
|
|
+ grouplist[i] = tswap32(target_grouplist[i]);
|
|
|
|
+ }
|
|
|
|
+ unlock_user(target_grouplist, arg2, 0);
|
|
}
|
|
}
|
|
- for(i = 0;i < gidsetsize; i++)
|
|
|
|
- grouplist[i] = tswap32(target_grouplist[i]);
|
|
|
|
- unlock_user(target_grouplist, arg2, 0);
|
|
|
|
return get_errno(setgroups(gidsetsize, grouplist));
|
|
return get_errno(setgroups(gidsetsize, grouplist));
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|