[Buildroot] Buildroot fails on powerpc with busybox login.c

Denis Vlasenko vda.linux at googlemail.com
Mon Sep 18 05:44:01 UTC 2006


On Monday 18 September 2006 00:59, Rob Landley wrote:
> > One place where you can use it more-or-less safely is in <applet>_main().
> 
> No, you can only use it if you understand all the code an applet calls.  But 
> if you don't understand all the code an applet calls, you're likely to break 
> stuff anyway.

	fgets(bb_common_bufsiz1, sizeof(bb_common_bufsiz1), stdin);
	if (strcmp(bb_common_bufsiz1,"diediedie")) exit(1);

Here it is obviously safe unless applet has a function which
uses bb_common_bufsiz1 as a non-temporary buffer which must
retain contents across calls (not very sane code).

> Using it from libbb is nasty, but within an applet should be quite sane.
> 
> > You can be sure that caller doesn't use it and you can
> > directly code it so that there are no calls to functions
> > which implicitly clobber bb_common_bufsiz1.
> > It's easy because currently no libbb function uses it IIRC.
> 
> It would be bad for libbb functions to use bb_common_bufsiz1 (which should 
> probably have a better name, like bb_buffer or bb_common something), because 
> then code calling them would have to worry about side effects.  But within an 
> applet, if you can't track side effects from modifying global variables, 
> there's already a problem.



> > But here it is used in a function, not in a <applet>_main().
> > The function has no way to check whether caller uses bb_common_bufsiz1
> > in an unsafe manner (i.e. across the call to this function).
> > 
> > So it is a bit scary here. And it gives no size savings AT ALL
> > because char buf[BUFSIZ] was an automatic variable on stack.
> 
> Declaring 4k on the stack is a bit impolite to nommu systems.

In this particular case buffer is used for reading lines from /etc/securetty.
I think it can be reduced to 128 bytes. If someone got bigger line there,
they'll get what they asked for.

> > > login.02_of_03.diff
> > > shrink by perusing bb_getopt_ulflags()
> > 
> > +#define LOGIN_OPT_f (1<<0)
> > +#define LOGIN_OPT_h (1<<1)
> > +#define LOGIN_OPT_p (1<<2)
> > 
> > Defining constants using enum {...}; is saner.
> 
> Why?  (I've never understood this one.  O_RDWR and O_BINARY were #defines back 
> in the 1970's, what exactly's wrong with it?)

In 1970's there were no enums in C, iirc. I think this is the sole reason.

[cut-n-pasting...]

#defines just look more familiar than enum {}. But #define has serious
flaws: it knows nothing about scope rules, and when you accidentally
#define name which is already used for something before or after
#define site, possibly inside another macro/#define
(for example: errno is a #define in glibc!), you get really obscure
compile errors. If you are lucky, that is. If you are not,
you get the most obscure bugs.

"enum { a = 1, b = 10 };" looks a bit ugly AT FIRST, while one
is not yet accustomized to parse them visually,
but has none of those "bug generator" properties.

"const a = 1;" is even better, but currently gcc+ld is not clever enough
to optimize it out completely.
--
vda



More information about the busybox mailing list