avoid sending pointer values in struct passwd

Thorsten Glaser t.glaser at tarent.de
Wed Nov 25 11:53:58 AEDT 2020


On Wed, 25 Nov 2020, Damien Miller wrote:

> +		    (r = sshbuf_put_u64(b, pwent->id < 0 ? \
> +		    -pwent->id : pwent->id)) != 0) \

*cough* -2⁶³ will trigger UB/IB on this.


Since sender and recipient are on the same system, you can just…

union a64bitquantity {
	uint64_t u;
	int64_t i;
}

#define PUTPW(b, id) do {				\
	unsigned char issigned = pwent->id < 0;		\
	union a64bitquantity q;				\
							\
	if (issigned)					\
		q.i = pwent->id;			\
	else						\
		q.u = pwent->id;			\
							\
	if ((r = sshbuf_put_u8(b, issigned)) != 0 ||	\
	    (r = sshbuf_put_u64(b, q.u)) != 0)		\
		fatal_fr(r, "assemble pw %s", #id);	\
} while (/* CONSTCOND */ 0)

#define GETPW(b, id) do {				\
	unsigned char issigned;				\
	union a64bitquantity q;				\
							\
	if ((r = sshbuf_get_u8(b, &issigned)) != 0 ||	\
	    (r = sshbuf_get_u64(b, &q.u)) != 0)		\
		fatal_fr(r, "parse pw %s", #id);	\
	/* don’t use a ternary expression here */	\
	if (issigned)					\
		pwent->id = q.i;			\
	else						\
		pwent->id = q.u;			\
} while (/* CONSTCOND */ 0)

Use of such a union is AFAIR safe.

Using a ternary operation could trigger UB/IB by
trying to bring the operands to the same type.


It might actually be easier to try and find out whether
the type is signed or not. I don’t know of a good method,
“the ’net” suggests:

#define	ISUNSIGNED(T)	((T)-1 > 0)

This, unfortunately, doesn’t work as a compile-time check.
But we can do this during configure time:

~ $ gcc -DI='<stdlib.h>' -DT=size_t -c a.c
~ $ gcc -DI='<stdlib.h>' -DT=ssize_t -c a.c
a.c: In function ‘foo’:
a.c:4:6: error: size of array ‘statictest’ is negative
    4 |  int statictest[((T)-1 > 0) ? 1 : -1];
      |      ^~~~~~~~~~
1|~ $ cat a.c
#include I

int foo(void) {
	int statictest[((T)-1 > 0) ? 1 : -1];
	return (0);
}
~ $

Check whether this compiles to set preprocessor
definitions, then use the to select the suitable
function to pass the value.

This is what I feel is safest; ofc YMMV…

bye,
//mirabilos
-- 
tarent solutions GmbH
Rochusstraße 2-4, D-53123 Bonn • http://www.tarent.de/
Tel: +49 228 54881-393 • Fax: +49 228 54881-235
HRB 5168 (AG Bonn) • USt-ID (VAT): DE122264941
Geschäftsführer: Dr. Stefan Barth, Kai Ebenrett, Boris Esser, Alexander Steeg

*************************************************

Mit unserem Consulting bieten wir Unternehmen maßgeschneiderte Angebote in
Form von Beratung, Trainings sowie Workshops in den Bereichen
Softwaretechnologie, IT Strategie und Architektur, Innovation und Umsetzung
sowie Agile Organisation.

Besuchen Sie uns auf https://www.tarent.de/consulting .
Wir freuen uns auf Ihren Kontakt.

*************************************************


More information about the openssh-unix-dev mailing list