* Ingo Molnar <[email protected]> wrote:

> We could do something like:
> 
>                 c = *(unsigned long *)(src+res);
>                 *(unsigned long *)(dest+res) = c;
> 
>                 if (has_zero(c, &data, &constants)) {
>                       unsigned int zero_pos;
> 
>                         data = prep_zero_mask(c, data, &constants);
>                         data = create_zero_mask(data);
> 
>                       zero_pos = find_zero(data);
>                       res += zero_pos;
> 
>                       memset(dest+res, 0, sizeof(long)-zero_pos);
> 
>                         return res;
>                 }
> 
> I.e. the extra memset() clears out the partial word (if any) after the NUL.

A slightly more paranoid version would be:

                c = *(unsigned long *)(src+res);
 
                if (has_zero(c, &data, &constants)) {
                        unsigned int zero_pos;
 
                        data = prep_zero_mask(c, data, &constants);
                        data = create_zero_mask(data);
 
                        zero_pos = find_zero(data);

                        /* Clear out undefined data within the final word after 
the NUL: */ 
                        memset((void *)&c + zero_pos, 0, sizeof(long)-zero_pos);

                        *(unsigned long *)(dest+res) = c;
 
                        return res+zero_pos;
                }
                *(unsigned long *)(dest+res) = c;

This would solve any theoretical races in the _target_ buffer: if the target 
buffer may be copied to user-space in a racy fashion and we don't ever want it 
to 
have undefined data, then this variant does the tail-zeroing of the final word 
in 
the temporary copy, not in the target buffer.

Still untested.

Thanks,

        Ingo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to