ASH: why ash_ptr_to_globals_misc is declared as const pointer

Denys Vlasenko vda.linux at googlemail.com
Tue Jan 30 03:10:05 UTC 2018


On Fri, Jan 26, 2018 at 8:39 PM, Yunlian Jiang <yunlian at google.com> wrote:
> I will use a similar issue in lineedit.c to explain the problem. (it is
> easier to reproduce).
> The problem is that
> clang thinks lineedit_ptr_to_statics is a constant pointer, so the pointer
> should be unchanged. As a result, inside a function, it
> loads the value once, and it can use it as many as it want without worrying
> anthing changes.
> In the macro
>
>  #define INIT_S() do { \
>         (*(struct lineedit_statics**)&lineedit_ptr_to_statics) =
> xzalloc(sizeof(S)); \
>         barrier(); \
>         cmdedit_termw = 80; \
>         IF_USERNAME_OR_HOMEDIR(home_pwd_buf = (char*)null_str;) \
>         IF_FEATURE_EDITING_VI(delptr = delbuf;) \
> } while (0)
>
>  (*(struct lineedit_statics**)&lineedit_ptr_to_statics) =
> xzalloc(sizeof(S));
> actually changes value of the pointer (from 0x0 to the return value of
> xzalloc). But clang did not realize that, otherwise, it
> should omit a compiler time error, so clang thinks it has nothing to do with
> lineedit_ptr_to_statics
>
> in the statement
> IF_FEATURE_EDITING_VI(delptr = delbuf;), clang still assumes the value of
> the pointer is '0x0', so the segfaults happens.

How clang knows that pointer was NULL? It's an extern, clang can't
infer its value
because it doesn't see it, right?

Can you post "make libbb/lineedit.s" result?

Can you experiment with better barriers?


More information about the busybox mailing list