NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: bin/38396: sshd does not work



The following reply was made to PR bin/38396; it has been noted by GNATS.

From: der Mouse <mouse%Rodents.Montreal.QC.CA@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc: 
Subject: Re: bin/38396: sshd does not work
Date: Sat, 19 Apr 2008 21:52:15 -0400 (EDT)

 It was a mistake to use CMSG_* for SCM_RIGHTS messages in the first
 place (I'm not convinced it was a right thing to do even for its design
 purpose, but that is substantially more defensible; there was no pripr
 API/ABI to be incompatible with there).  However, that is unlikely to
 be undone.  Given that, I think the kernel should be as liberal as
 feasible here.
 
 And no, CMSG_SPACE is not constant.  As far as I recall from when I
 read it, the API definition is silent on whether this is permitted,
 meaning that that declaration of buf[] is depending on either
 CMSG_SPACE being constant or a gccism.
 
 >>         char tmp[CMSG_SPACE(sizeof(int))];
 > Hmmm... that isn't guaranteed to be adequately aligned :-)
 
 That's one of the reasons I dislike the CMSG_* interface.  Here's
 scm-rights.h from moussh, most of which is comments containing a longer
 discussion of the issues.
 
 #ifndef _SCM_RIGHTS_H_e8240238_
 #define _SCM_RIGHTS_H_e8240238_
 
 /* This file is in the public domain. */
 
 /*
  * This file exists because the SCM_RIGHTS interface silently changed.
  *  It used to work the traditional way: pack file descriptors tightly
  *  as an array of ints immediately after the struct cmsghdr.  It was
  *  changed to use the layout corresponding to the CMSG_* macros, which
  *  don't exist historically; since the resulting layout is different
  *  on architectures for which __cmsg_alignbytes is greater than
  *  sizeof(int)-1, this is rather broken, breaking historically working
  *  code.  (The CMSG_* macros were invented for all the control guff
  *  IPv6 wants to shovel around.  What I don't understand is why they
  *  were imposed on SCM_RIGHTS messages.)  To make things worse, the
  *  CMSG_* macros are a broken API: they don't even try to support
  *  control messages that aren't in buffers aligned suitably for a
  *  struct cmsghdr (in particular, there is no way to find out where
  *  the data for a message falls relative to the message's beginning
  *  except by computing the data pointer as a function of the cmsghdr
  *  pointer).  This means you have to either use gcc extensions like
  *  __alignof__ or you have to do something like the CMSKIP macro
  *  below - unless you're willing to malloc the buffer (and, strictly,
  *  even that is not enough, since there is no guarantee that the
  *  required alignment is that of any object type).
  *
  * So we actually use macros CMSPACE, CMLEN, and CMSKIP, which are
  *  defined either suitably for the historical way (if
  *  NEW_CMSG_INTERFACE is not defined) or the least ugly way I've found
  *  for the CMSG_* way (if NEW_CMSG_INTERFACE is defined).
  */
 
 #ifdef NEW_CMSG_INTERFACE
 #define CMSPACE(x) (CMSG_SPACE((x)))
 #define CMLEN(x) (CMSG_LEN((x)))
 /*
  * It's gross to have to do this, but it's more or less forced upon us
  *  by the botched design of the the CMSG_* interface.  The interface
  *  takes first steps towards a completely opaque interface, but
  *  botches it rather badly, resulting in neither an interface that can
  *  be used opaquely nor an interface that can be used transparently.
  *  Since the traditional interface is the transparent style, and the
  *  opaque style cannot be done without alignment issues (see below),
  *  this code goes in the transparent direction.  The result is not as
  *  portable as I'd like - it can depend on using a pointer past the
  *  end of an object, depending on the architecture - but I believe
  *  it's the least horrible of the available alternatives.
  *
  * The interface seems designed to overlay the structs cmsghdr onto the
  *  control buffer, but that demands the buffer be aligned, without
  *  providing any way to actually achieve that, which more or less
  *  compels its allocation with malloc(), that being the only portable
  *  way to correctly align a buffer whose alignment requirements are
  *  inacessible.  (Using gcc extensions like __aligned__ and
  *  __alignof__, this can be worked around, but (a) that's gcc-specific
  *  and rather ugly, (b) it shouldn't be necessary, and (c) it can't be
  *  done without making assumptions for which there is no basis except
  *  knowledge of the implementation, like "the alignment necessary is
  *  the most strict of struct cmsghdr and the types to be stored in the
  *  buffer".
  */
 #define CMSKIP(x) ((char *)CMSG_DATA((x))-(char *)(x))
 #else
 #define CMSPACE(x) (sizeof(struct cmsghdr)+(x))
 #define CMLEN(x) (sizeof(struct cmsghdr)+(x))
 #define CMSKIP(x) (sizeof(struct cmsghdr))
 #endif
 
 #endif
 
 /~\ The ASCII                          der Mouse
 \ / Ribbon Campaign
  X  Against HTML              mouse%rodents.montreal.qc.ca@localhost
 / \ Email!          7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B
 


Home | Main Index | Thread Index | Old Index