Bug 21259 - might leak memory in dbus_message_iter_get_args_valist
Summary: might leak memory in dbus_message_iter_get_args_valist
Status: RESOLVED FIXED
Alias: None
Product: dbus
Classification: Unclassified
Component: core (show other bugs)
Version: unspecified
Hardware: Other All
: medium normal
Assignee: Havoc Pennington
QA Contact: John (J5) Palmieri
URL:
Whiteboard: review?
Keywords: patch
Depends on:
Blocks:
 
Reported: 2009-04-17 13:01 UTC by Lennart Poettering
Modified: 2013-11-02 00:20 UTC (History)
1 user (show)

See Also:
i915 platform:
i915 features:


Attachments
[PATCH] Fix memory or unix fd may leak in dbus_message_iter_get_args_valist (2.29 KB, patch)
2013-09-27 06:42 UTC, Chengwei Yang
Details | Splinter Review
[PATCH v2] Fix memory or unix fd may leak in dbus_message_iter_get_args_valist (3.01 KB, patch)
2013-10-11 07:47 UTC, Chengwei Yang
Details | Splinter Review
test client based on client.c from fd.o #13305 (2.72 KB, text/plain)
2013-10-11 07:48 UTC, Chengwei Yang
Details
test server based on server.c from fd.o #13305 (1.73 KB, text/plain)
2013-10-11 07:49 UTC, Chengwei Yang
Details
[PATCH v3 1/2] Correctly set number of arguments already handled (1.46 KB, patch)
2013-10-11 09:00 UTC, Chengwei Yang
Details | Splinter Review
[PATCH v3 2/2] Fix memory or unix fd may leak in dbus_message_iter_get_args_valist (3.02 KB, patch)
2013-10-11 09:01 UTC, Chengwei Yang
Details | Splinter Review
test client based on client.c from fd.o #13305 (2.77 KB, text/plain)
2013-10-11 09:01 UTC, Chengwei Yang
Details
test server based on server.c from fd.o #13305 (1.73 KB, text/plain)
2013-10-11 09:01 UTC, Chengwei Yang
Details
output without this fix (279 bytes, text/plain)
2013-10-11 09:02 UTC, Chengwei Yang
Details
output with this fix (223 bytes, text/plain)
2013-10-11 09:03 UTC, Chengwei Yang
Details
[PATCH v4 1/3] Correctly set number of arguments already handled (1.46 KB, patch)
2013-10-29 02:33 UTC, Chengwei Yang
Details | Splinter Review
[PATCH v4 2/3] Fix memory or unix fd may leak in dbus_message_iter_get_args_valist (4.17 KB, patch)
2013-10-29 02:34 UTC, Chengwei Yang
Details | Splinter Review
[PATCH v4 3/3] Test: add test cases for message parsing (9.52 KB, patch)
2013-10-29 02:36 UTC, Chengwei Yang
Details | Splinter Review
[PATCH v5] Fix memory or unix fd may leak in dbus_message_iter_get_args_valist (4.16 KB, text/plain)
2013-10-29 14:22 UTC, Chengwei Yang
Details

Description Lennart Poettering 2009-04-17 13:01:42 UTC
Let's say we first parse an array of strings successfully and then go on and try to parse something else unsucessfully -- the string list we allocated earlier will not be freed.

http://cgit.freedesktop.org/dbus/dbus/tree/dbus/dbus-message.c#n719
Comment 1 Havoc Pennington 2009-04-17 18:43:03 UTC
Indeed.
Comment 2 Chengwei Yang 2013-09-27 06:42:58 UTC
Created attachment 86707 [details] [review]
[PATCH] Fix memory or unix fd may leak in  dbus_message_iter_get_args_valist

Let's fix it.
Comment 3 Simon McVittie 2013-10-08 11:37:05 UTC
Comment on attachment 86707 [details] [review]
[PATCH] Fix memory or unix fd may leak in  dbus_message_iter_get_args_valist

Review of attachment 86707 [details] [review]:
-----------------------------------------------------------------

The bug here is that if you do

_dbus_message_iter_get_args_valist (&iter, &error,
    DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &as,
    DBUS_TYPE_UNIX_FD, &fd,
    DBUS_TYPE_UINT32, &u,
    DBUS_TYPE_INVALID)

then on failure to parse 'u', 'fd' and 'as' already contain copies which aren't freed.

Your patch fixes that simple case, but it does not fix this:

_dbus_message_iter_get_args_valist (&iter, &error,
    DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &as1,
    DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &as2,
    DBUS_TYPE_UNIX_FD, &fd1,
    DBUS_TYPE_UNIX_FD, &fd2,
    DBUS_TYPE_UINT32, &u,
    DBUS_TYPE_INVALID)

You'd close fd2 and free as2, but not fd1 or as1.

I think the only way to fix this fully would be to copy the var_args before iteration. On failure, we'd have a second loop over the copy, just to free/close them, stopping at the argument we failed to parse (you could use the value of i to track that). It should also set as1 = NULL, as2 = NULL, fd1 = -1, fd2 = -1 etc. to make callers more deterministic.

I can easily imagine existing callers working around this bug by closing/freeing the arguments themselves on failure - which they're not meant to have to do, but it would currently work. Setting the output variables to dummy values would either mean the caller's attempts to free them didn't do anything (if they used a NULL-tolerant free-function), or failing that, at least give them a better backtrace.

I think this is too long-standing and subtle to fix in 1.6. 1.7 would be OK.
Comment 4 Chengwei Yang 2013-10-09 03:29:45 UTC
(In reply to comment #3)
> Comment on attachment 86707 [details] [review] [review]
> [PATCH] Fix memory or unix fd may leak in  dbus_message_iter_get_args_valist
> 
> Review of attachment 86707 [details] [review] [review]:
> -----------------------------------------------------------------
> 
> The bug here is that if you do
> 
> _dbus_message_iter_get_args_valist (&iter, &error,
>     DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &as,
>     DBUS_TYPE_UNIX_FD, &fd,
>     DBUS_TYPE_UINT32, &u,
>     DBUS_TYPE_INVALID)
> 
> then on failure to parse 'u', 'fd' and 'as' already contain copies which
> aren't freed.
> 
> Your patch fixes that simple case, but it does not fix this:
> 
> _dbus_message_iter_get_args_valist (&iter, &error,
>     DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &as1,
>     DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &as2,
>     DBUS_TYPE_UNIX_FD, &fd1,
>     DBUS_TYPE_UNIX_FD, &fd2,
>     DBUS_TYPE_UINT32, &u,
>     DBUS_TYPE_INVALID)
> 
> You'd close fd2 and free as2, but not fd1 or as1.

Good point!

> 
> I think the only way to fix this fully would be to copy the var_args before
> iteration. On failure, we'd have a second loop over the copy, just to
> free/close them, stopping at the argument we failed to parse (you could use
> the value of i to track that). It should also set as1 = NULL, as2 = NULL,
> fd1 = -1, fd2 = -1 etc. to make callers more deterministic.

Yes, I'll create a patch to do that. Another way is to save all duped memory to a structure, but need dynamic expand, not good.

> 
> I can easily imagine existing callers working around this bug by
> closing/freeing the arguments themselves on failure - which they're not
> meant to have to do, but it would currently work. Setting the output
> variables to dummy values would either mean the caller's attempts to free
> them didn't do anything (if they used a NULL-tolerant free-function), or
> failing that, at least give them a better backtrace.
> 
> I think this is too long-standing and subtle to fix in 1.6. 1.7 would be OK.
Comment 5 Chengwei Yang 2013-10-11 07:47:35 UTC
Created attachment 87428 [details] [review]
[PATCH v2] Fix memory or unix fd may leak in  dbus_message_iter_get_args_valist

copy va_list first and then do another iteration over it to free may leaked memory and unix fds.
Comment 6 Chengwei Yang 2013-10-11 07:48:46 UTC
Created attachment 87430 [details]
test client based on client.c from fd.o #13305
Comment 7 Chengwei Yang 2013-10-11 07:49:21 UTC
Created attachment 87431 [details]
test server based on server.c from fd.o #13305
Comment 8 Chengwei Yang 2013-10-11 09:00:37 UTC
Created attachment 87434 [details] [review]
[PATCH v3 1/2] Correctly set number of arguments already handled
Comment 9 Chengwei Yang 2013-10-11 09:01:04 UTC
Created attachment 87435 [details] [review]
[PATCH v3 2/2] Fix memory or unix fd may leak in  dbus_message_iter_get_args_valist
Comment 10 Chengwei Yang 2013-10-11 09:01:33 UTC
Created attachment 87436 [details]
test client based on client.c from fd.o #13305
Comment 11 Chengwei Yang 2013-10-11 09:01:56 UTC
Created attachment 87437 [details]
test server based on server.c from fd.o #13305
Comment 12 Chengwei Yang 2013-10-11 09:02:41 UTC
Created attachment 87438 [details]
output without this fix
Comment 13 Chengwei Yang 2013-10-11 09:03:07 UTC
Created attachment 87439 [details]
output with this fix
Comment 14 Chengwei Yang 2013-10-11 09:07:30 UTC
There are finally two patches, two test files (yeah, very ugly, just to do test temporarily, :-)) most based on files from #bug13305 and output we got without/with this fix applied.

Another off topic question, should we set fd to '-1' in _dbus_close() and array of string pointer to NULL dbus_free_string_array()?
Comment 15 Simon McVittie 2013-10-23 17:02:31 UTC
Comment on attachment 87435 [details] [review]
[PATCH v3 2/2] Fix memory or unix fd may leak in  dbus_message_iter_get_args_valist

Review of attachment 87435 [details] [review]:
-----------------------------------------------------------------

::: dbus/dbus-message.c
@@ +811,5 @@
> +  /* copy var_args first, then we can do another iteration over it to
> +   * free memory and close unix fds if parse failed at some point.
> +   */
> +  va_copy (copy_args, var_args);
> +  va_end (var_args);

I don't see how this va_end makes sense? The function uses var_args after this point, so it's incorrect to have "freed" it.

@@ +998,4 @@
>          }
>      }
>  
> +  return TRUE;

This is wrong if va_copy allocates memory. va_copy(3) says "Each invocation of va_copy() must be matched by a corresponding invocation of va_end() in the same function".

va_copy(3) also says "On some systems, va_end contains a closing '}' matching a '{' in va_start". I think that would necessarily imply that va_copy() contains a '{' on such systems.

I think this structure would work:

  va_copy (copy_args, var_args);

  while (spec_type != DBUS_TYPE_INVALID)
    {
      ... use var_args ...
    }

  retval = TRUE;

out:
  if (!retval)
    {
      ... use copy_args ...
    }

  va_end (copy_args);
  return retval;

@@ +1014,5 @@
> +        {
> +#ifdef HAVE_UNIX_FD_PASSING
> +          int *pfd;
> +
> +          pfd = va_arg (copy_args, int*);

nitpicking: int *, with the space

(I like pointer types in newly-added lines of code to have the form of whitespace that suggests the actual C precedence: see <http://telepathy.freedesktop.org/wiki/Style/#misc>.)

@@ +1017,5 @@
> +
> +          pfd = va_arg (copy_args, int*);
> +          _dbus_assert(pfd);
> +	  if (*pfd > 0)
> +            _dbus_close (*pfd, NULL);

I'd prefer

if (*pfd > 0)
  {
    _dbus_close (*pfd, NULL);
    *pfd = -1;
  }

so that if a caller is trying to work around this leak, they'll just close(-1) and fail, rather than trying to close what has potentially become another thread's valid fd.

@@ +1023,5 @@
> +        }
> +      else if (dbus_type_is_basic (spec_type))
> +        {
> +          /* move the index forward */
> +          va_arg (copy_args, DBusBasicValue*);

DBusBasicValue *

@@ +1034,5 @@
> +          if (dbus_type_is_fixed (spec_element_type))
> +            {
> +              /* move the index forward */
> +              va_arg (copy_args, const DBusBasicValue**);
> +              va_arg (copy_args, int*);

const DBusBasicValue **, int *

@@ +1042,5 @@
> +              char ***str_array_p;
> +
> +              str_array_p = va_arg (copy_args, char***);
> +	      /* move the index forward */
> +	      va_arg (copy_args, int*);

char ***, int *

@@ +1044,5 @@
> +              str_array_p = va_arg (copy_args, char***);
> +	      /* move the index forward */
> +	      va_arg (copy_args, int*);
> +              _dbus_assert (str_array_p != NULL);
> +	      dbus_free_string_array (*str_array_p);

add: *str_array_p = NULL

(same reason as for the fds)
Comment 16 Simon McVittie 2013-10-23 17:15:35 UTC
Please add an actual automated regression test. You shouldn't need to actually send any messages: you should be able to just construct a DBusMessage, do stuff with it, and free it. If you add the testing to dbus-message-util.c, you can use the existing memory- and fd-leak checking code.

Something like this pseudocode, perhaps:

* Construct a message of signature 'uashuashu' or something (where each 'h' is a copy of v_UNIX_FD or something, and each 'as' is a copy of v_ARRAY_STRING)

* Parse it with ..._get_args() using its correct signature, and verify that everything is OK. Close the two fds and free the two string arrays. Expect no error and no fd leaks.

* Parse it with ..._get_args() as if expecting signatures "", "u", "uas", "uash", "uashu", "uashuas", "uashuashu". In each case, expect an error and free it. Again, expect no fd leaks.

* Free the message. Expect no memory leaks (check_memleaks()).

You can test for fd leaks like this:

initial_fds = _dbus_check_fdleaks_enter ();
... do something that shouldn't leak any fds ...
_dbus_check_fdleaks_leave (initial_fds);
Comment 17 Simon McVittie 2013-10-23 17:21:36 UTC
(In reply to comment #14)
> Another off topic question, should we set fd to '-1' in _dbus_close() and
> array of string pointer to NULL dbus_free_string_array()?

*In* those functions, it wouldn't be useful to do that. (Think about where the fd/pointer variable is situated - either in a register or on the stack - and why it wouldn't have a side-effect on the rest of the program.)

*When calling* those functions, yes, it's sometimes useful to do that.

Some libraries have this pattern (I first saw it in CPython, added it to Telepathy, and it's now used in GLib):

    Thing *thing;

    thing = thing_new ();
    ...
    thing_clear (&thing);    // similar to { thing_free (thing); thing = NULL; }

which can also be used for fds (using -1 instead of NULL as the "clearing" value). However, to be useful, thing_clear() needs its argument to have an extra level of "pointerness" beyond what you'd expect a free-function to have - a (Thing **) instead of the usual (Thing *), or for a fd, an (int *) instead of an int.
Comment 18 Simon McVittie 2013-10-23 17:36:34 UTC
(In reply to comment #15)
> @@ +1042,5 @@
> > +              char ***str_array_p;
> > +
> > +              str_array_p = va_arg (copy_args, char***);
> > +	      /* move the index forward */
> > +	      va_arg (copy_args, int*);
...
> > +              str_array_p = va_arg (copy_args, char***);
> > +	      /* move the index forward */
> > +	      va_arg (copy_args, int*);
> > +              _dbus_assert (str_array_p != NULL);
> > +	      dbus_free_string_array (*str_array_p);

I didn't see this when reviewing in Splinter, presumably because it normalizes whitespace or something, but something seems to have gone wrong with the indentation here.

Please indent all newly-added lines of code with spaces, even if they were adapted from a copy of existing code that mixed spaces and tabs. You might find one of these useful:

* git show | sed -e 's/    /»·······/'
  (where the gap between the first two slashes is a literal tab
  character, [Ctrl+V][Tab] in most shells)

* an editor that makes odd whitespace visible, e.g. in gvim or vim in
  a UTF-8 terminal, I use:

  set list listchars=tab:»·,trail:¯,nbsp:¤
Comment 19 Chengwei Yang 2013-10-28 06:55:41 UTC
(In reply to comment #15)
> Comment on attachment 87435 [details] [review] [review]
> [PATCH v3 2/2] Fix memory or unix fd may leak in 
> dbus_message_iter_get_args_valist
> 
> Review of attachment 87435 [details] [review] [review]:
> -----------------------------------------------------------------
> 
> ::: dbus/dbus-message.c
> @@ +811,5 @@
> > +  /* copy var_args first, then we can do another iteration over it to
> > +   * free memory and close unix fds if parse failed at some point.
> > +   */
> > +  va_copy (copy_args, var_args);
> > +  va_end (var_args);
> 
> I don't see how this va_end makes sense? The function uses var_args after
> this point, so it's incorrect to have "freed" it.

definitely, I was mixed with dst and scr of va_copy in va_copy(3).

> 
> @@ +998,4 @@
> >          }
> >      }
> >  
> > +  return TRUE;
> 
> This is wrong if va_copy allocates memory. va_copy(3) says "Each invocation
> of va_copy() must be matched by a corresponding invocation of va_end() in
> the same function".
> 
> va_copy(3) also says "On some systems, va_end contains a closing '}'
> matching a '{' in va_start". I think that would necessarily imply that
> va_copy() contains a '{' on such systems.
> 
> I think this structure would work:
> 
>   va_copy (copy_args, var_args);
> 
>   while (spec_type != DBUS_TYPE_INVALID)
>     {
>       ... use var_args ...
>     }
> 
>   retval = TRUE;
> 
> out:
>   if (!retval)
>     {
>       ... use copy_args ...
>     }
> 
>   va_end (copy_args);
>   return retval;
> 
> @@ +1014,5 @@
> > +        {
> > +#ifdef HAVE_UNIX_FD_PASSING
> > +          int *pfd;
> > +
> > +          pfd = va_arg (copy_args, int*);
> 
> nitpicking: int *, with the space
> 
> (I like pointer types in newly-added lines of code to have the form of
> whitespace that suggests the actual C precedence: see
> <http://telepathy.freedesktop.org/wiki/Style/#misc>.)
> 
> @@ +1017,5 @@
> > +
> > +          pfd = va_arg (copy_args, int*);
> > +          _dbus_assert(pfd);
> > +	  if (*pfd > 0)
> > +            _dbus_close (*pfd, NULL);
> 
> I'd prefer
> 
> if (*pfd > 0)
>   {
>     _dbus_close (*pfd, NULL);
>     *pfd = -1;
>   }
> 
> so that if a caller is trying to work around this leak, they'll just
> close(-1) and fail, rather than trying to close what has potentially become
> another thread's valid fd.
> 
> @@ +1023,5 @@
> > +        }
> > +      else if (dbus_type_is_basic (spec_type))
> > +        {
> > +          /* move the index forward */
> > +          va_arg (copy_args, DBusBasicValue*);
> 
> DBusBasicValue *
> 
> @@ +1034,5 @@
> > +          if (dbus_type_is_fixed (spec_element_type))
> > +            {
> > +              /* move the index forward */
> > +              va_arg (copy_args, const DBusBasicValue**);
> > +              va_arg (copy_args, int*);
> 
> const DBusBasicValue **, int *
> 
> @@ +1042,5 @@
> > +              char ***str_array_p;
> > +
> > +              str_array_p = va_arg (copy_args, char***);
> > +	      /* move the index forward */
> > +	      va_arg (copy_args, int*);
> 
> char ***, int *
> 
> @@ +1044,5 @@
> > +              str_array_p = va_arg (copy_args, char***);
> > +	      /* move the index forward */
> > +	      va_arg (copy_args, int*);
> > +              _dbus_assert (str_array_p != NULL);
> > +	      dbus_free_string_array (*str_array_p);
> 
> add: *str_array_p = NULL
> 
> (same reason as for the fds)
Comment 20 Chengwei Yang 2013-10-28 07:07:21 UTC
(In reply to comment #18)
> (In reply to comment #15)
> > @@ +1042,5 @@
> > > +              char ***str_array_p;
> > > +
> > > +              str_array_p = va_arg (copy_args, char***);
> > > +	      /* move the index forward */
> > > +	      va_arg (copy_args, int*);
> ...
> > > +              str_array_p = va_arg (copy_args, char***);
> > > +	      /* move the index forward */
> > > +	      va_arg (copy_args, int*);
> > > +              _dbus_assert (str_array_p != NULL);
> > > +	      dbus_free_string_array (*str_array_p);
> 
> I didn't see this when reviewing in Splinter, presumably because it
> normalizes whitespace or something, but something seems to have gone wrong
> with the indentation here.
> 

yes, I copied some lines from the first loop and there were two \t left, so I'll fix all of them in this patch.

> Please indent all newly-added lines of code with spaces, even if they were
> adapted from a copy of existing code that mixed spaces and tabs. You might
> find one of these useful:
> 
> * git show | sed -e 's/    /»·······/'
>   (where the gap between the first two slashes is a literal tab
>   character, [Ctrl+V][Tab] in most shells)
> 
> * an editor that makes odd whitespace visible, e.g. in gvim or vim in
>   a UTF-8 terminal, I use:
> 
>   set list listchars=tab:»·,trail:¯,nbsp:¤

thanks for tips.
Comment 21 Chengwei Yang 2013-10-29 01:23:11 UTC
(In reply to comment #16)
> Please add an actual automated regression test. You shouldn't need to
> actually send any messages: you should be able to just construct a
> DBusMessage, do stuff with it, and free it. If you add the testing to
> dbus-message-util.c, you can use the existing memory- and fd-leak checking
> code.
> 
> Something like this pseudocode, perhaps:
> 
> * Construct a message of signature 'uashuashu' or something (where each 'h'
> is a copy of v_UNIX_FD or something, and each 'as' is a copy of
> v_ARRAY_STRING)
> 
> * Parse it with ..._get_args() using its correct signature, and verify that
> everything is OK. Close the two fds and free the two string arrays. Expect
> no error and no fd leaks.
> 
> * Parse it with ..._get_args() as if expecting signatures "", "u", "uas",

I found that currently _dbus_message_iter_get_args_valist() return TRUE if the first argument is DBUS_TYPE_INVALID.

Should we change it to return FALSE? Seems a imcomptable change if so.

> "uash", "uashu", "uashuas", "uashuashu". In each case, expect an error and
> free it. Again, expect no fd leaks.
> 
> * Free the message. Expect no memory leaks (check_memleaks()).
> 
> You can test for fd leaks like this:
> 
> initial_fds = _dbus_check_fdleaks_enter ();
> ... do something that shouldn't leak any fds ...
> _dbus_check_fdleaks_leave (initial_fds);
Comment 22 Chengwei Yang 2013-10-29 01:41:49 UTC
(In reply to comment #16)
> Please add an actual automated regression test. You shouldn't need to
> actually send any messages: you should be able to just construct a
> DBusMessage, do stuff with it, and free it. If you add the testing to
> dbus-message-util.c, you can use the existing memory- and fd-leak checking
> code.
> 
> Something like this pseudocode, perhaps:
> 
> * Construct a message of signature 'uashuashu' or something (where each 'h'
> is a copy of v_UNIX_FD or something, and each 'as' is a copy of
> v_ARRAY_STRING)
> 
> * Parse it with ..._get_args() using its correct signature, and verify that
> everything is OK. Close the two fds and free the two string arrays. Expect
> no error and no fd leaks.
> 
> * Parse it with ..._get_args() as if expecting signatures "", "u", "uas",
> "uash", "uashu", "uashuas", "uashuashu". In each case, expect an error and
> free it. Again, expect no fd leaks.

All the above cases are expected not fail as below documents in dbus_message_get_args()

 * If the requested arguments are not present, or do not have the
 * requested types, then an error will be set.
 *
 * If more arguments than requested are present, the requested
 * arguments are returned and the extra arguments are ignored.

So I'll fail them in another pattern.

> 
> * Free the message. Expect no memory leaks (check_memleaks()).
> 
> You can test for fd leaks like this:
> 
> initial_fds = _dbus_check_fdleaks_enter ();
> ... do something that shouldn't leak any fds ...
> _dbus_check_fdleaks_leave (initial_fds);
Comment 23 Chengwei Yang 2013-10-29 02:33:25 UTC
Created attachment 88263 [details] [review]
[PATCH v4 1/3] Correctly set number of arguments already handled

only did rebase
Comment 24 Chengwei Yang 2013-10-29 02:34:55 UTC
Created attachment 88264 [details] [review]
[PATCH v4 2/3] Fix memory or unix fd may leak in  dbus_message_iter_get_args_valist

addressed Simon's comments, in addition a typo str_array_p = NULL --> *str_array_p = NULL
Comment 25 Chengwei Yang 2013-10-29 02:36:41 UTC
Created attachment 88265 [details] [review]
[PATCH v4 3/3] Test: add test cases for message parsing

test cases for message parsing, for two kinds of testing

1. arguments present but not requested are ignored

2. arguments parse failed should not leak memory or unix fd.
Comment 26 Simon McVittie 2013-10-29 12:37:27 UTC
(In reply to comment #22)
> > * Parse it with ..._get_args() as if expecting signatures "", "u", "uas",
> > "uash", "uashu", "uashuas", "uashuashu". In each case, expect an error and
> > free it. Again, expect no fd leaks.
> 
> All the above cases are expected not fail as below documents in
> dbus_message_get_args()

OK, my mistake - I'd forgotten that corner of the API. In that case, please expect those to succeed, without leaking.
Comment 27 Simon McVittie 2013-10-29 12:40:41 UTC
Comment on attachment 88264 [details] [review]
[PATCH v4 2/3] Fix memory or unix fd may leak in  dbus_message_iter_get_args_valist

Review of attachment 88264 [details] [review]:
-----------------------------------------------------------------

Makes sense. I'll fix the one error I noted when I apply it, if you don't get there first.

::: dbus/dbus-message.c
@@ +1018,5 @@
> +              int *pfd;
> +
> +              pfd = va_arg (copy_args, int *);
> +              _dbus_assert(pfd);
> +              if (*pfd > 0)

>= 0, strictly speaking. 0 is a valid fd too (although it's stdin, so it will nearly always be open already).
Comment 28 Simon McVittie 2013-10-29 12:43:19 UTC
Comment on attachment 88265 [details] [review]
[PATCH v4 3/3] Test: add test cases for message parsing

Review of attachment 88265 [details] [review]:
-----------------------------------------------------------------

::: dbus/dbus-message-util.c
@@ +991,5 @@
>      _dbus_assert_not_reached ("Didn't reach end of arguments");
>  }
>  
> +static void
> +verify_test_message_args_ignored (DBusMessage *message)

I'd prefer this test to check for fd-leaks too. I'll add that when I commit it if necessary.
Comment 29 Chengwei Yang 2013-10-29 13:13:06 UTC
(In reply to comment #27)
> Comment on attachment 88264 [details] [review] [review]
> [PATCH v4 2/3] Fix memory or unix fd may leak in 
> dbus_message_iter_get_args_valist
> 
> Review of attachment 88264 [details] [review] [review]:
> -----------------------------------------------------------------
> 
> Makes sense. I'll fix the one error I noted when I apply it, if you don't
> get there first.

Sure, thank you.

> 
> ::: dbus/dbus-message.c
> @@ +1018,5 @@
> > +              int *pfd;
> > +
> > +              pfd = va_arg (copy_args, int *);
> > +              _dbus_assert(pfd);
> > +              if (*pfd > 0)
> 
> >= 0, strictly speaking. 0 is a valid fd too (although it's stdin, so it will nearly always be open already).

Yeah, make sense.
Comment 30 Chengwei Yang 2013-10-29 13:15:30 UTC
(In reply to comment #28)
> Comment on attachment 88265 [details] [review] [review]
> [PATCH v4 3/3] Test: add test cases for message parsing
> 
> Review of attachment 88265 [details] [review] [review]:
> -----------------------------------------------------------------
> 
> ::: dbus/dbus-message-util.c
> @@ +991,5 @@
> >      _dbus_assert_not_reached ("Didn't reach end of arguments");
> >  }
> >  
> > +static void
> > +verify_test_message_args_ignored (DBusMessage *message)
> 
> I'd prefer this test to check for fd-leaks too. I'll add that when I commit
> it if necessary.

Hmm, It was there but removed before I upload this patch since I think it should not happen there. :-), anyway, your decision.

BTW, did you noticed the first patch? Without it, the second one will take incorrect "i" as a loop stop condition.
Comment 31 Chengwei Yang 2013-10-29 14:22:00 UTC
Created attachment 88293 [details]
[PATCH v5] Fix memory or unix fd may leak in dbus_message_iter_get_args_valist

> > +              if (*pfd > 0)
> 
> >= 0, strictly speaking. 0 is a valid fd too (although it's stdin, so it will nearly always be open already).

Fixed.
Comment 32 Chengwei Yang 2013-11-02 00:20:54 UTC
already merged into master, for 1.7.8.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.