diff mbox

[FFmpeg-devel] Fix sdp size check on fmtp integer parameters

Message ID 1552921720-13028-1-git-send-email-olivier.maignial@smile.fr
State Superseded
Headers show

Commit Message

Olivier Maignial March 18, 2019, 3:08 p.m. UTC
RFC-4566 do not give any limit of size on interger parameters given in fmtp line.
By reading some more RFCs it is possible to find examples where some integers parameters are greater than 32 (see RFC-6416, 7.4)
---
 libavformat/rtpdec_mpeg4.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

Comments

Michael Niedermayer March 18, 2019, 8:47 p.m. UTC | #1
On Mon, Mar 18, 2019 at 04:08:40PM +0100, Olivier Maignial wrote:
> RFC-4566 do not give any limit of size on interger parameters given in fmtp line.
> By reading some more RFCs it is possible to find examples where some integers parameters are greater than 32 (see RFC-6416, 7.4)
> ---
>  libavformat/rtpdec_mpeg4.c | 17 +++++++++++++----
>  1 file changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/libavformat/rtpdec_mpeg4.c b/libavformat/rtpdec_mpeg4.c
> index 994ab49..4b86f4a 100644
> --- a/libavformat/rtpdec_mpeg4.c
> +++ b/libavformat/rtpdec_mpeg4.c
> @@ -289,15 +289,24 @@ static int parse_fmtp(AVFormatContext *s,
>          for (i = 0; attr_names[i].str; ++i) {
>              if (!av_strcasecmp(attr, attr_names[i].str)) {
>                  if (attr_names[i].type == ATTR_NAME_TYPE_INT) {
> -                    int val = atoi(value);
> -                    if (val > 32) {
> +                    char * end_ptr = NULL;
> +                    long int val = strtol(value, &end_ptr, 10);
> +                    if (value[0] == '\n' || end_ptr[0] != '\0')
> +                    {
>                          av_log(s, AV_LOG_ERROR,
> -                               "The %s field size is invalid (%d)\n",
> +                               "The %s field value is not a number (%s)\n",
> +                               attr, value);
> +                        return AVERROR_INVALIDDATA;
> +                    }
> +
> +                    if (val > INT_MAX || val < INT_MIN) {
> +                        av_log(s, AV_LOG_ERROR,
> +                               "The %s field size is invalid (%ld)\n",
>                                 attr, val);
>                          return AVERROR_INVALIDDATA;
>                      }

does this also work as intended if int is 64bit ? (it can be)


[...]
Carl Eugen Hoyos March 18, 2019, 9:51 p.m. UTC | #2
2019-03-18 16:08 GMT+01:00, Olivier Maignial <olivier.maignial@smile.fr>:

> +                    char * end_ptr = NULL;

Assuming you have to send a new patch anyway,
please make this "char *end_ptr"...

> +                    long int val = strtol(value, &end_ptr, 10);

> +                    if (value[0] == '\n' || end_ptr[0] != '\0')
> +                    {

... and merge these lines.

Thank you, Carl Eugen
diff mbox

Patch

diff --git a/libavformat/rtpdec_mpeg4.c b/libavformat/rtpdec_mpeg4.c
index 994ab49..4b86f4a 100644
--- a/libavformat/rtpdec_mpeg4.c
+++ b/libavformat/rtpdec_mpeg4.c
@@ -289,15 +289,24 @@  static int parse_fmtp(AVFormatContext *s,
         for (i = 0; attr_names[i].str; ++i) {
             if (!av_strcasecmp(attr, attr_names[i].str)) {
                 if (attr_names[i].type == ATTR_NAME_TYPE_INT) {
-                    int val = atoi(value);
-                    if (val > 32) {
+                    char * end_ptr = NULL;
+                    long int val = strtol(value, &end_ptr, 10);
+                    if (value[0] == '\n' || end_ptr[0] != '\0')
+                    {
                         av_log(s, AV_LOG_ERROR,
-                               "The %s field size is invalid (%d)\n",
+                               "The %s field value is not a number (%s)\n",
+                               attr, value);
+                        return AVERROR_INVALIDDATA;
+                    }
+
+                    if (val > INT_MAX || val < INT_MIN) {
+                        av_log(s, AV_LOG_ERROR,
+                               "The %s field size is invalid (%ld)\n",
                                attr, val);
                         return AVERROR_INVALIDDATA;
                     }
                     *(int *)((char *)data+
-                        attr_names[i].offset) = val;
+                        attr_names[i].offset) = (int) val;
                 } else if (attr_names[i].type == ATTR_NAME_TYPE_STR) {
                     char *val = av_strdup(value);
                     if (!val)