Applied, thanks!
On Mon, Jan 4, 2016 at 8:10 PM, Arnout Vandecappelle <[email protected]> wrote: > ping > > On 01-12-15 13:52, Arnout Vandecappelle (Essensium/Mind) wrote: >> The non-fancy version of the from_cpuset uses CPU_SETSIZE as if it >> represents the number of bytes in the cpuset, while it is actually >> the number of bits. This leads to out-of-bounds accesses on the >> cpu_set_t in the big-endian case. Basically all uses of CPU_SETSIZE >> have to be divided by 8. This is done correctly in the fancy version >> of from_cpuset. >> >> In addition, the big-endian case is completely wrong to begin with. >> All standard C libraries that I know of implement cpu_set_t as an >> unsigned long array, so both for big and little endian, the least >> significant bits are in the beginning of the array. Therefore, the >> approach taken for the little endian case is equally valid. We only >> need special handling for big endian when CPU_SETSIZE is large and >> we use an unsigned long long to get more bits out. >> >> Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <[email protected]> >> --- >> miscutils/taskset.c | 35 ++++++++++++++++++----------------- >> 1 file changed, 18 insertions(+), 17 deletions(-) >> >> diff --git a/miscutils/taskset.c b/miscutils/taskset.c >> index 100b1d9..18a4b67 100644 >> --- a/miscutils/taskset.c >> +++ b/miscutils/taskset.c >> @@ -75,27 +75,28 @@ static char *from_cpuset(cpu_set_t *mask) >> #define TASKSET_PRINTF_MASK "%llx" >> static unsigned long long from_cpuset(cpu_set_t *mask) >> { >> - char *p = (void*)mask; >> + BUILD_BUG_ON((CPU_SETSIZE/8) < sizeof(int)); >> >> - BUILD_BUG_ON(CPU_SETSIZE < sizeof(int)); >> - >> - /* Take the least significant bits. Careful! >> - * Consider both CPU_SETSIZE=4 and CPU_SETSIZE=1024 cases >> + /* Take the least significant bits. Assume cpu_set_t is >> + * implemented as an array of unsigned long or unsigned >> + * int. >> */ >> + if ((CPU_SETSIZE/8) < sizeof(long)) >> + return *(unsigned*)mask; >> + if ((CPU_SETSIZE/8) < sizeof(long long)) >> + return *(unsigned long*)mask; >> #if BB_BIG_ENDIAN >> - /* For big endian, it means LAST bits */ >> - if (CPU_SETSIZE < sizeof(long)) >> - p += CPU_SETSIZE - sizeof(int); >> - else if (CPU_SETSIZE < sizeof(long long)) >> - p += CPU_SETSIZE - sizeof(long); >> - else >> - p += CPU_SETSIZE - sizeof(long long); >> + if (sizeof(unsigned long long) > sizeof(unsigned long)) { >> + /* We can put two long in the long long, but they have to >> + * be swapped: the least significant word comes first in the >> + * array */ >> + unsigned long *p = (void*)mask; >> + return (unsigned long long)*p + >> + ((unsigned long long)*(p+1) << (8*sizeof(unsigned >> long))); >> + } >> +#else >> + return *(unsigned long long*)mask; >> #endif >> - if (CPU_SETSIZE < sizeof(long)) >> - return *(unsigned*)p; >> - if (CPU_SETSIZE < sizeof(long long)) >> - return *(unsigned long*)p; >> - return *(unsigned long long*)p; >> } >> #endif >> >> > > -- > Arnout Vandecappelle arnout dot vandecappelle at essensium dot com > Senior Embedded Software Architect . . . . . . +32-478-010353 (mobile) > Essensium, Mind division . . . . . . . . . . . . . . http://www.mind.be > G.Geenslaan 9, 3001 Leuven, Belgium . . . . . BE 872 984 063 RPR Leuven > LinkedIn profile: http://www.linkedin.com/in/arnoutvandecappelle > GPG fingerprint: 7493 020B C7E3 8618 8DEC 222C 82EB F404 F9AC 0DDF > > _______________________________________________ > busybox mailing list > [email protected] > http://lists.busybox.net/mailman/listinfo/busybox _______________________________________________ busybox mailing list [email protected] http://lists.busybox.net/mailman/listinfo/busybox
