On 08/22/2013 05:13 PM, chru...@suse.cz wrote:
>> One of parameters to setgroups() syscall is (gid_t *) pointer.
>> If TST_USE_COMPAT16_VSYSCALL is defined a pointer to GID_T is passed
>> instead (and sizeof(GID_T) < sizeof(gid_t)). It's not safe and
>> can result in unaligned access (and SIGBUS) on several platforms.
>>
>> Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmansk...@oracle.com>
>> ---
>>   testcases/kernel/syscalls/setgroups/compat_16.h   |   22 
>> +++++++++++++++++++-
>>   testcases/kernel/syscalls/setgroups/setgroups04.c |    6 ++++-
>>   2 files changed, 25 insertions(+), 3 deletions(-)
>>
>> diff --git a/testcases/kernel/syscalls/setgroups/compat_16.h 
>> b/testcases/kernel/syscalls/setgroups/compat_16.h
>> index 0de4e78..35723d6 100644
>> --- a/testcases/kernel/syscalls/setgroups/compat_16.h
>> +++ b/testcases/kernel/syscalls/setgroups/compat_16.h
>> @@ -32,9 +32,27 @@ extern void cleanup(void);
>>   #ifdef TST_USE_COMPAT16_SYSCALL
>>   
>>   long
>> -SETGROUPS(size_t gidsetsize, GID_T *list)
>> +SETGROUPS(size_t gidsetsize, GID_T *list16)
>>   {
>> -    return ltp_syscall(__NR_setgroups, gidsetsize, list);
>> +    int r;
>> +    int i;
>> +
>> +    gid_t *list32;
>> +
>> +    list32 = calloc(gidsetsize, sizeof(gid_t));
>> +    if (list32 == NULL)
>> +            tst_brkm(TBROK | TERRNO, NULL,
>> +                    "calloc failed to allocate %zu bytes at %s:%d",
>> +                    gidsetsize * sizeof(gid_t),
>> +                    __FILE__, __LINE__);
>> +
>> +    for (i = 0; i < gidsetsize; i++)
>> +            list32[i] = list16[i];
>> +
>> +    r = ltp_syscall(__NR_setgroups, gidsetsize, list32);
>> +
>> +    free(list32);
>> +    return r;
>>   }
> This looks like the __NR_setgroups is not the compact16 one we want.
>
> Look at the getgroups16 in kernel/uid16.c it calls groups16_from_user()
> and that does:
>
>
>          for (i = 0; i < group_info->ngroups; i++) {
>                  if (get_user(group, grouplist+i))
>                          return  -EFAULT;
>
>
> The grouplist is of old_gid_t __user *grouplist type so it's unsigned short, 
> so
> it works with array of unsigned short which is aligned to unsigned shorts due
> to definiton of the GID_T in the test sources, there is no way this
> would trigger unaligned access.
>
> And actually the GETGROUPS() seems to be coded to pass list32 and converts it
> to list16 which looks just wrong to me as it's inside of
> TST_USE_COMPAT16_SYSCALL. It just looks to me like we have wrong syscall
> number to begin with.
>
Hi, Cyril.

Thank you for this point.

At first sight it seems that this testcase is very specific for i386 
(maybe for other architectures also).

In i386 I found two variants of setgroups syscall (from 
arch/x86/syscalls/syscall_32.tbl):
     81      i386    setgroups               sys_setgroups16
     206     i386    setgroups32             sys_setgroups

I guess in i386 glibc handler for setgroups() internally uses 
_setgroups32_ syscall.

In x86_64 there is only one variant (from arch/x86/syscalls/syscall_64.tbl):
     116     common  setgroups               sys_setgroups

which points to 32-bit version.

But It's just an assumption and I'll verify this.




------------------------------------------------------------------------------
Introducing Performance Central, a new site from SourceForge and 
AppDynamics. Performance Central is your source for news, insights, 
analysis and resources for efficient Application Performance Management. 
Visit us today!
http://pubads.g.doubleclick.net/gampad/clk?id=48897511&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to