Re: [asterisk-dev] (unreported) uninitialized: struct ast_sockaddr

2015-05-13 Thread Richard Mudgett
On Wed, May 13, 2015 at 3:59 AM, Alexander Traud pabstr...@compuserve.com
wrote:

  What you're proposing is a change to the semantics of ast_sockaddr.

 Not sure what you mean by semantics. Please, let us ignore ast_sockaddr for
 a second and see http://www.ex-parrot.com/~chris/random/initialise.html:


Semantics just mean how something has to be used.  You are changing the
semantics of ast_sockaddr by adding something that must be explicitly
released.
Whereas, before there was nothing that needed to be explicitly released so
nothing would need to be explicitly called to destroy the ast_sockaddr
instance.



 Currently, when a struct with automatic storage duration is created in
 Asterisk, it is initialized
 A) (correct) with {0},
 B) (questionable) via memset,
 C) (questionable) at first use, or
 D) (wrong) not at all.

 Is case D important enough to get fixed, at a whole, or partially. If
 partially, to which extend?

 Example 1:
 The *opaque* peercnt (channels/chan_iax2.c) contains ast_sockaddr and
 therefore has to be initialized correctly in my case to avoid a wild
 pointer. Actually, I am using chan_sip only, added a pointer to
 ast_sockaddr, cleaned memory, and my Asterisk was segfaulting in a complete
 different module (chan_iax2.c). [Offtopic: Yes, my modules.conf was wrong.]


struct peercnt is not opaque as the struct definition is visible to the code
using the structure.  If it were opaque you would only be able to create
pointer
variables to the struct and not instances of the struct itself.  The
compiler
cannot let you create an instance of struct peercnt if it does not know the
size
of it.

struct peercnt *pointer_to_peercnt;
struct peercnt instance_of_peercnt;



 Example 2:
 The *private* sip_peer (channels/sip/include/sip.h) contains pointers and
 is
 not initialized at all twice, at least (sip_peer tmp_peer). This creates
 wild pointers which segfaulted the pointer in my ast_sockaddr.


These particular uses of peercnt in chan_iax2.c and sip_peer in chan_sip.c
are
dummy objects with just enough fields filled in to perform an ao2_find().
Those
dummy objects are never destroyed so the uninitialized pointers are
irrelevant.
The coding pattern that creates a dummy object with the container key fields
filled in pre-dates the introduction of OBJ_SEARCH_KEY and the older name
OBJ_KEY.



 Asked differently:
 I have a diff/patch correcting just the struct-inits for 62 lines of code
 at
 54 places in 5 files, which affects my downstream code. Am I allowed to
 commit just that, although it does not address the issue at a whole (there
 are many more struct inits which stay wrong)?

 Or: Is my compiler configured incorrectly somehow, not setting pointers to
 (void *)0 automatically in structs with automatic storage duration?


I haven't seen a compiler that tracks uninitialized struct members.  You
should
make your addition as a char array rather than an allocated pointer to avoid
incompatibilities in unexpected places.  Otherwise, the semantic change
breaks code all over the place.

Richard
-- 
_
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

asterisk-dev mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/asterisk-dev

Re: [asterisk-dev] (unreported) uninitialized: struct ast_sockaddr

2015-05-12 Thread Matthew Jordan
On Mon, May 11, 2015 at 9:16 AM, Alexander Traud
pabstr...@compuserve.com wrote:
 B) Change my patch not to use a char* but char[128].
 Your easiest option with less chance of regression elsewhere would be this.

 Yes. Anyway: Is the Asterisk team interested in a patch at least for the 5
 affected files? These are 54 changes. I am not sure if the path via an issue
 (Jira) and a commit (Gerrit) is welcome for something like this.

 Furthermore, again there are several options:
   I) in those 5 files, report only those 54 changes which I need; or
  II) in those 5 files, correct *all* struct inits
 The latter is interesting, because there are memsets(.) which get
 unnecessary then. This created an additional option/question:
 III) shall I remove all - then duplicate - struct inits as well?

 Or shall I stop wasting anyone's time and go for option B, a char[128]?

I wouldn't say you're wasting anyone's time. It's a good question.

What you're proposing is a change to the semantics of ast_sockaddr in
order to accommodate a change in a patch you're making. A few things
to keep in mind:
1) Your module/patch, as well as the rest of the Asterisk modules, may
not be the only consumers of ast_sockaddr. It is a fundamental data
structure in Asterisk; other third party modules may use it. Since
your change modifies the semantics of the struct, you will also break
them.
2) If the rest of your patch is never pushed back up to the main
project, then the change you've made has little positive affect, while
breaking most other external modules that use it. That's not good for
the project. On the other hand, if you propose your feature for
inclusion as well, there's more of a benefit to the change.

That aside, if you can make a change with a little bit more work that
maintains the existing usage semantics, you get the best of both
worlds: your new feature gets what it needs, and the mainline Asterisk
project - as well as other third party modules - aren't broken.

So yes, I'd just use a char array with a fixed length.

-- 
Matthew Jordan
Digium, Inc. | Director of Technology
445 Jan Davis Drive NW - Huntsville, AL 35806 - USA
Check us out at: http://digium.com  http://asterisk.org

-- 
_
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

asterisk-dev mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/asterisk-dev


Re: [asterisk-dev] (unreported) uninitialized: struct ast_sockaddr

2015-05-11 Thread Joshua Colp

Alexander Traud wrote:

In a patch of mine (DANE for Asterisk 13/chan_sip; available on request), a
char* was added in the struct ast_sockaddr to store the DNSSEC failure
reason (why_bogus). Not to create any memory leaks, this pointer has to be
freed. For this, the pointer must be initialized to NULL, for example via
struct ast_sockaddr variable_name = { 0 }. Otherwise, I create a
segmentation fault because I free a non-valid address. Long story short:

Neither GCC nor Clang are able to find uninitialized structs in Asterisk,
although the warning flag -Wall includes -Wuninitialized. And I played
around with the optimization in CFLAG. Mhm.

What shall I do?
A) Init all ast_sockaddr (and all structures containing ast_sockaddr).
With the default sample configuration, just 5 files must be changed.
However, I searched with the regular expression struct [^ ]+ [^*=)]+; and
found 2408 lines of code in 418 files which may be uninitialized. As an
external project member, I cannot change/commit all of them. For a start,
shall I create issue report just about these 5 files?

B) Change my patch not to use a char* but char[128].


Your easiest option with less chance of regression elsewhere would be this.

--
Joshua Colp
Digium, Inc. | Senior Software Developer
445 Jan Davis Drive NW - Huntsville, AL 35806 - US
Check us out at: www.digium.com  www.asterisk.org

--
_
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

asterisk-dev mailing list
To UNSUBSCRIBE or update options visit:
  http://lists.digium.com/mailman/listinfo/asterisk-dev


Re: [asterisk-dev] (unreported) uninitialized: struct ast_sockaddr

2015-05-11 Thread Alexander Traud
 B) Change my patch not to use a char* but char[128].
 Your easiest option with less chance of regression elsewhere would be this.

Yes. Anyway: Is the Asterisk team interested in a patch at least for the 5
affected files? These are 54 changes. I am not sure if the path via an issue
(Jira) and a commit (Gerrit) is welcome for something like this.

Furthermore, again there are several options:
  I) in those 5 files, report only those 54 changes which I need; or
 II) in those 5 files, correct *all* struct inits
The latter is interesting, because there are memsets(.) which get
unnecessary then. This created an additional option/question:
III) shall I remove all - then duplicate - struct inits as well?

Or shall I stop wasting anyone's time and go for option B, a char[128]?



-- 
_
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

asterisk-dev mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/asterisk-dev