diff mbox

[FFmpeg-devel,v2] Let clang-FORTIFY build; NFC.

Message ID 1472597344-8124-1-git-send-email-gbiv@chromium.org
State Withdrawn
Headers show

Commit Message

George Burgess IV Aug. 30, 2016, 10:49 p.m. UTC
ChromeOS is adopting a new FORTIFY implementation tailored for clang. As
an artifact of how this new FORTIFY is implemented, a handful of
implicit conversion warnings get turned into errors. This patch fixes
the implicit conversions in ffmpeg that clang-FORTIFY has an issue with.

Signed-off-by: George Burgess IV <gbiv@chromium.org>
---

If anyone feels that more comments would be useful, I'll add them above some of
the char* casts, so it's a bit more obvious why we have said casts.

Testing methodology was "run `make fate` and see what doesn't build." If there
are other targets that would be good to try, I'm happy to check with those, as
well. :)

 libavcodec/pamenc.c           | 2 +-
 libavcodec/pnmenc.c           | 4 ++--
 libavcodec/xbmenc.c           | 8 +++++---
 libavcodec/xsubenc.c          | 2 +-
 libavfilter/af_astats.c       | 4 ++--
 libavfilter/avf_aphasemeter.c | 2 +-
 libavformat/flacenc.c         | 2 +-
 libavformat/http.c            | 4 ++--
 libavformat/matroskaenc.c     | 3 ++-
 libavformat/md5proto.c        | 3 ++-
 libavformat/nutenc.c          | 4 ++--
 libavformat/rtmppkt.c         | 4 ++--
 libavutil/hash.c              | 2 +-
 libavutil/opt.c               | 5 +++--
 14 files changed, 27 insertions(+), 22 deletions(-)

Comments

Ronald S. Bultje Aug. 30, 2016, 11:10 p.m. UTC | #1
Hi,

On Tue, Aug 30, 2016 at 6:49 PM, George Burgess IV <gbiv@chromium.org>
wrote:

> ChromeOS is adopting a new FORTIFY implementation tailored for clang. As
> an artifact of how this new FORTIFY is implemented, a handful of
> implicit conversion warnings get turned into errors. This patch fixes
> the implicit conversions in ffmpeg that clang-FORTIFY has an issue with.


Isn't it easier to change your fortify-clang and add a compiler option to
disable this specific error for specific targets? (I don't find the casts
particularly pretty.)

Ronald
George Burgess IV Aug. 31, 2016, 12:47 a.m. UTC | #2
Thanks for the feedback! I agree the casts aren't pretty. :)

> Isn't it easier to change your fortify-clang and add a compiler option to
disable this specific error for specific targets?

The short answer is "in some cases, yes. Sadly, this doesn't seem to be one
of those cases."

The longer answer is that FORTIFY is a thing that's implemented partially
in the compiler, and partially in the standard library (for example, the
canonical FORTIFY implementation* has bits in both gcc and glibc). The
errors this patch is trying to fix originate from the bits in the standard
library, so it's not as simple as checking if the compiler got a flag. At
this point, the least-effort fix would be turning FORTIFY off for
${project_with_errors}. If we wanted to be more granular, we could probably
add #ifndef _DISABLE_FORTIFY_FOR_$functionName for each FORTIFY'ed
function, but:
1. grep tells me there are currently 75 FORTIFY functions, so we would need
75 such flags;
2. it lessens the effectiveness of FORTIFY across the entire project; and
3. the idea of hand-curating a list of per-project+per-function defines,
that can arbitrarily change from release to release, seems kind of ugly in
itself. :/

* - Clang is able to compile things with this gcc-based FORTIFY
implementation enabled. It's not able to do *nearly* as well as GCC,
though, because said impl depends heavily on implementation details of GCC
that don't hold true for clang.

Thanks,
George

On Tue, Aug 30, 2016 at 4:10 PM, Ronald S. Bultje <rsbultje@gmail.com>
wrote:

> Hi,
>
> On Tue, Aug 30, 2016 at 6:49 PM, George Burgess IV <gbiv@chromium.org>
> wrote:
>
>> ChromeOS is adopting a new FORTIFY implementation tailored for clang. As
>> an artifact of how this new FORTIFY is implemented, a handful of
>> implicit conversion warnings get turned into errors. This patch fixes
>> the implicit conversions in ffmpeg that clang-FORTIFY has an issue with.
>
>
> Isn't it easier to change your fortify-clang and add a compiler option to
> disable this specific error for specific targets? (I don't find the casts
> particularly pretty.)
>
> Ronald
>
Ronald S. Bultje Aug. 31, 2016, 8:24 a.m. UTC | #3
Hi George,

On Tue, Aug 30, 2016 at 8:47 PM, George Burgess <gbiv@chromium.org> wrote:

> Thanks for the feedback! I agree the casts aren't pretty. :)
>
> > Isn't it easier to change your fortify-clang and add a compiler option
> to disable this specific error for specific targets?
>
> The short answer is "in some cases, yes. Sadly, this doesn't seem to be
> one of those cases."
>
> The longer answer is that FORTIFY is a thing that's implemented partially
> in the compiler, and partially in the standard library (for example, the
> canonical FORTIFY implementation* has bits in both gcc and glibc). The
> errors this patch is trying to fix originate from the bits in the standard
> library, so it's not as simple as checking if the compiler got a flag. At
> this point, the least-effort fix would be turning FORTIFY off for
> ${project_with_errors}. If we wanted to be more granular, we could probably
> add #ifndef _DISABLE_FORTIFY_FOR_$functionName for each FORTIFY'ed
> function, but:
> 1. grep tells me there are currently 75 FORTIFY functions, so we would
> need 75 such flags;
> 2. it lessens the effectiveness of FORTIFY across the entire project; and
> 3. the idea of hand-curating a list of per-project+per-function defines,
> that can arbitrarily change from release to release, seems kind of ugly in
> itself. :/
>

I agree it's a little iffy. Can you explain what the goal of fortify is and
what the reason for the errors is? Most of the patch (cursory glance, not
looking at scope of variables or anything) seems to suggest that the patch
tries to prevent the compiler auto-casting between pointers of sized types
(almost always uint8_t *) and native types (almost always char *). It seems
the goal here is to remove the assumption that the two are of the same
size. I'm blindly assuming the signedness isn't relevant here, but please
feel free to correct me. Did I get that right?

If that's the case, I'm wondering if there's a chance the patch makes
things worse. It obviously doesn't introduce bugs, don't get me wrong. But
there's an issue. If the goal of fortify is to prepare sources from being
ready for situations where e.g. char=16bit, then I don't think this patch
fixes that situation. FFmpeg will still not work in that situation. It will
probably crash, but at the very least it will generate incorrect data in
these functions. The patch essentially silences compiler warnings that
would be generated related to this.

Is that the right thing to do?

(Or maybe I'm misunderstanding fortify, is there some documentation about
it? Or do you know what you're trying to accomplish with it? Is this the
same thing as FORTIFY_SOURCE?)

One reason for asking all these questions is that if we accept this patch,
we likely want to add a fate station (at least compilation) to guarantee
this keeps working in the future. That essentially makes it officially
supported. As such, it'd make sense to ensure/understand we're doing the
right thing and not just silencing some "valid warnings". In no way do I
want to suggest you don't know what you're doing, I'm sort-of trying to
verify that we understand it also.

Thanks!
Ronald
Michael Niedermayer Aug. 31, 2016, 9:37 a.m. UTC | #4
On Wed, Aug 31, 2016 at 04:24:36AM -0400, Ronald S. Bultje wrote:
> Hi George,
> 
> On Tue, Aug 30, 2016 at 8:47 PM, George Burgess <gbiv@chromium.org> wrote:
> 
> > Thanks for the feedback! I agree the casts aren't pretty. :)
> >
> > > Isn't it easier to change your fortify-clang and add a compiler option
> > to disable this specific error for specific targets?
> >
> > The short answer is "in some cases, yes. Sadly, this doesn't seem to be
> > one of those cases."
> >
> > The longer answer is that FORTIFY is a thing that's implemented partially
> > in the compiler, and partially in the standard library (for example, the
> > canonical FORTIFY implementation* has bits in both gcc and glibc). The
> > errors this patch is trying to fix originate from the bits in the standard
> > library, so it's not as simple as checking if the compiler got a flag. At
> > this point, the least-effort fix would be turning FORTIFY off for
> > ${project_with_errors}. If we wanted to be more granular, we could probably
> > add #ifndef _DISABLE_FORTIFY_FOR_$functionName for each FORTIFY'ed
> > function, but:
> > 1. grep tells me there are currently 75 FORTIFY functions, so we would
> > need 75 such flags;
> > 2. it lessens the effectiveness of FORTIFY across the entire project; and
> > 3. the idea of hand-curating a list of per-project+per-function defines,
> > that can arbitrarily change from release to release, seems kind of ugly in
> > itself. :/
> >
> 
> I agree it's a little iffy. Can you explain what the goal of fortify is and
> what the reason for the errors is? Most of the patch (cursory glance, not
> looking at scope of variables or anything) seems to suggest that the patch
> tries to prevent the compiler auto-casting between pointers of sized types
> (almost always uint8_t *) and native types (almost always char *). It seems
> the goal here is to remove the assumption that the two are of the same
> size. I'm blindly assuming the signedness isn't relevant here, but please
> feel free to correct me. Did I get that right?
> 
> If that's the case, I'm wondering if there's a chance the patch makes
> things worse. It obviously doesn't introduce bugs, don't get me wrong. But
> there's an issue. If the goal of fortify is to prepare sources from being
> ready for situations where e.g. char=16bit, then I don't think this patch
> fixes that situation. FFmpeg will still not work in that situation. It will

I wonder if a 16bit char system could even have uint8_t
sizeof(char) is fixed at 1 by the standard, if that represents 16bit
uint8_t should be stored as 16bit too
but quite possibly iam missing something

[...]
George Burgess IV Sept. 1, 2016, 3:43 a.m. UTC | #5
> I'm blindly assuming the signedness isn't relevant here

That's actually what matters here, sadly. The only way we've been able to
get FORTIFY on clang to work nearly as well as FORTIFY on gcc is with
overloading (via clang's __attribute__((overloadable)) ). This attribute is
specced to use C++'s overload resolution rules, and C++ doesn't allow for
implicitly converting between unsigned char* and char*. (AFAICT, neither
does C, but most C compilers are happy to accept it anyway)

The more I think about this, though, the more it sounds like a reasonable
idea to extend that attribute to allow these kinds of conversions if we're
in C. I'll see if clang will accept this + if we can do that without
breaking existing users of overloadable. If so, this patch won't be
necessary. If not, I'll come back with a hopefully-better approach for this.

> Can you explain what the goal of fortify is and what the reason for the
errors is?

Yeah, I could've been more clear about that -- apologies.

> Is this the same thing as FORTIFY_SOURCE?

Precisely. :) The goal is to make FORTIFY_SOURCE work better on clang. As
far as docs, there seem to be a few blog posts about what FORTIFY is meant
to do. I'm unsure if there's an official piece of documentation describing
how it works for gcc+glibc, though. I have a doc (that's still *very* much
a draft) describing it here if you're interested: https://docs.googl
e.com/document/d/1DFfZDICTbL7RqS74wJVIJ-YnjQOj1SaoqfhbgddFYS
M/edit?usp=sharing .

> One reason for asking all these questions is that if we accept this
patch, we likely want to add a fate station (at least compilation) to
guarantee this keeps working in the future

Yeah, the testing story for these changes is bad at the moment. :/ After a
bit more refinement (and a lot of testing), the goal is to upstream these
FORTIFY changes into glibc. If that works out well, testing will hopefully
be simple ("does it compile with clang version >N and glibc >M? If yes,
yay!"), but like you said earlier, fixing this in the compiler -- if
possible -- is probably our best bet.

> In no way do I want to suggest you don't know what you're doing

FWIW, I didn't get the "you don't know what you're doing" vibe at all from
either of your messages. :)

Thank you both for your time!
George

On Wed, Aug 31, 2016 at 2:37 AM, Michael Niedermayer <michael@niedermayer.cc
> wrote:

> On Wed, Aug 31, 2016 at 04:24:36AM -0400, Ronald S. Bultje wrote:
> > Hi George,
> >
> > On Tue, Aug 30, 2016 at 8:47 PM, George Burgess <gbiv@chromium.org>
> wrote:
> >
> > > Thanks for the feedback! I agree the casts aren't pretty. :)
> > >
> > > > Isn't it easier to change your fortify-clang and add a compiler
> option
> > > to disable this specific error for specific targets?
> > >
> > > The short answer is "in some cases, yes. Sadly, this doesn't seem to be
> > > one of those cases."
> > >
> > > The longer answer is that FORTIFY is a thing that's implemented
> partially
> > > in the compiler, and partially in the standard library (for example,
> the
> > > canonical FORTIFY implementation* has bits in both gcc and glibc). The
> > > errors this patch is trying to fix originate from the bits in the
> standard
> > > library, so it's not as simple as checking if the compiler got a flag.
> At
> > > this point, the least-effort fix would be turning FORTIFY off for
> > > ${project_with_errors}. If we wanted to be more granular, we could
> probably
> > > add #ifndef _DISABLE_FORTIFY_FOR_$functionName for each FORTIFY'ed
> > > function, but:
> > > 1. grep tells me there are currently 75 FORTIFY functions, so we would
> > > need 75 such flags;
> > > 2. it lessens the effectiveness of FORTIFY across the entire project;
> and
> > > 3. the idea of hand-curating a list of per-project+per-function
> defines,
> > > that can arbitrarily change from release to release, seems kind of
> ugly in
> > > itself. :/
> > >
> >
> > I agree it's a little iffy. Can you explain what the goal of fortify is
> and
> > what the reason for the errors is? Most of the patch (cursory glance, not
> > looking at scope of variables or anything) seems to suggest that the
> patch
> > tries to prevent the compiler auto-casting between pointers of sized
> types
> > (almost always uint8_t *) and native types (almost always char *). It
> seems
> > the goal here is to remove the assumption that the two are of the same
> > size. I'm blindly assuming the signedness isn't relevant here, but please
> > feel free to correct me. Did I get that right?
> >
> > If that's the case, I'm wondering if there's a chance the patch makes
> > things worse. It obviously doesn't introduce bugs, don't get me wrong.
> But
> > there's an issue. If the goal of fortify is to prepare sources from being
> > ready for situations where e.g. char=16bit, then I don't think this patch
> > fixes that situation. FFmpeg will still not work in that situation. It
> will
>
> I wonder if a 16bit char system could even have uint8_t
> sizeof(char) is fixed at 1 by the standard, if that represents 16bit
> uint8_t should be stored as 16bit too
> but quite possibly iam missing something
>
> [...]
> --
> Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> Many that live deserve death. And some that die deserve life. Can you give
> it to them? Then do not be too eager to deal out death in judgement. For
> even the very wise cannot see all ends. -- Gandalf
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
>
Carl Eugen Hoyos Sept. 4, 2016, 11:46 a.m. UTC | #6
Hi!

2016-08-31 0:49 GMT+02:00 George Burgess IV <gbiv@chromium.org>:
> +++ b/libavfilter/avf_aphasemeter.c
> @@ -190,7 +190,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
>
>      metadata = avpriv_frame_get_metadatap(out);
>      if (metadata) {
> -        uint8_t value[128];
> +        char value[128];

You could resend only the uncontroversial parts of
your patch (that do not add casts) if it makes your
life easier.

Carl Eugen
diff mbox

Patch

diff --git a/libavcodec/pamenc.c b/libavcodec/pamenc.c
index 50c9fcb..143d38f 100644
--- a/libavcodec/pamenc.c
+++ b/libavcodec/pamenc.c
@@ -98,7 +98,7 @@  static int pam_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     bytestream       = pkt->data;
     bytestream_end   = pkt->data + pkt->size;
 
-    snprintf(bytestream, bytestream_end - bytestream,
+    snprintf((char *)bytestream, bytestream_end - bytestream,
              "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
              w, h, depth, maxval, tuple_type);
     bytestream += strlen(bytestream);
diff --git a/libavcodec/pnmenc.c b/libavcodec/pnmenc.c
index ba9478d..f1bcbc6 100644
--- a/libavcodec/pnmenc.c
+++ b/libavcodec/pnmenc.c
@@ -80,12 +80,12 @@  static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     default:
         return -1;
     }
-    snprintf(bytestream, bytestream_end - bytestream,
+    snprintf((char *)bytestream, bytestream_end - bytestream,
              "P%c\n%d %d\n", c, avctx->width, h1);
     bytestream += strlen(bytestream);
     if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE) {
         int maxdepth = (1 << av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth) - 1;
-        snprintf(bytestream, bytestream_end - bytestream,
+        snprintf((char *)bytestream, bytestream_end - bytestream,
                  "%d\n", maxdepth);
         bytestream += strlen(bytestream);
     }
diff --git a/libavcodec/xbmenc.c b/libavcodec/xbmenc.c
index b25615f..7f7fbc0 100644
--- a/libavcodec/xbmenc.c
+++ b/libavcodec/xbmenc.c
@@ -28,14 +28,16 @@  static int xbm_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                             const AVFrame *p, int *got_packet)
 {
     int i, j, ret, size, linesize;
-    uint8_t *ptr, *buf;
+    // buf is a char* instead of a uint8_t* to make FORTIFY on clang happy.
+    char *buf;
+    uint8_t *ptr;
 
     linesize = (avctx->width + 7) / 8;
     size     = avctx->height * (linesize * 7 + 2) + 110;
     if ((ret = ff_alloc_packet2(avctx, pkt, size, 0)) < 0)
         return ret;
 
-    buf = pkt->data;
+    buf = (char *)pkt->data;
     ptr = p->data[0];
 
     buf += snprintf(buf, 32, "#define image_width %u\n", avctx->width);
@@ -49,7 +51,7 @@  static int xbm_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     }
     buf += snprintf(buf, 5, " };\n");
 
-    pkt->size   = buf - pkt->data;
+    pkt->size   = (uint8_t *)buf - pkt->data;
     pkt->flags |= AV_PKT_FLAG_KEY;
     *got_packet = 1;
     return 0;
diff --git a/libavcodec/xsubenc.c b/libavcodec/xsubenc.c
index b3da909..a4a8221 100644
--- a/libavcodec/xsubenc.c
+++ b/libavcodec/xsubenc.c
@@ -163,7 +163,7 @@  FF_ENABLE_DEPRECATION_WARNINGS
         return -1;
     }
 
-    snprintf(buf, 28,
+    snprintf((char *)buf, 28,
         "[%02d:%02d:%02d.%03d-%02d:%02d:%02d.%03d]",
         start_tc[3], start_tc[2], start_tc[1], start_tc[0],
         end_tc[3],   end_tc[2],   end_tc[1],   end_tc[0]);
diff --git a/libavfilter/af_astats.c b/libavfilter/af_astats.c
index e7f9675..32c6041 100644
--- a/libavfilter/af_astats.c
+++ b/libavfilter/af_astats.c
@@ -211,8 +211,8 @@  static inline void update_stat(AudioStatsContext *s, ChannelStats *p, double d,
 static void set_meta(AVDictionary **metadata, int chan, const char *key,
                      const char *fmt, double val)
 {
-    uint8_t value[128];
-    uint8_t key2[128];
+    char value[128];
+    char key2[128];
 
     snprintf(value, sizeof(value), fmt, val);
     if (chan)
diff --git a/libavfilter/avf_aphasemeter.c b/libavfilter/avf_aphasemeter.c
index 8e8b292..4afc6bb 100644
--- a/libavfilter/avf_aphasemeter.c
+++ b/libavfilter/avf_aphasemeter.c
@@ -190,7 +190,7 @@  static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 
     metadata = avpriv_frame_get_metadatap(out);
     if (metadata) {
-        uint8_t value[128];
+        char value[128];
 
         snprintf(value, sizeof(value), "%f", fphase);
         av_dict_set(metadata, "lavfi.aphasemeter.phase", value, 0);
diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c
index 89b21e9..8ef4292 100644
--- a/libavformat/flacenc.c
+++ b/libavformat/flacenc.c
@@ -115,7 +115,7 @@  static int flac_write_header(struct AVFormatContext *s)
             av_log(s, AV_LOG_WARNING, "A WAVEFORMATEXTENSIBLE_CHANNEL_MASK is "
                    "already present, this muxer will not overwrite it.\n");
         } else {
-            uint8_t buf[32];
+            char buf[32];
             snprintf(buf, sizeof(buf), "0x%"PRIx64, par->channel_layout);
             av_dict_set(&s->metadata, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", buf, 0);
         }
diff --git a/libavformat/http.c b/libavformat/http.c
index adb3d92..282310b 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -1095,7 +1095,7 @@  static int http_connect(URLContext *h, const char *path, const char *local_path,
     if (s->headers)
         av_strlcpy(headers + len, s->headers, sizeof(headers) - len);
 
-    snprintf(s->buffer, sizeof(s->buffer),
+    snprintf((char *)s->buffer, sizeof(s->buffer),
              "%s %s HTTP/1.1\r\n"
              "%s"
              "%s"
@@ -1593,7 +1593,7 @@  redo:
 
     authstr = ff_http_auth_create_response(&s->proxy_auth_state, auth,
                                            path, "CONNECT");
-    snprintf(s->buffer, sizeof(s->buffer),
+    snprintf((char *)s->buffer, sizeof(s->buffer),
              "CONNECT %s HTTP/1.1\r\n"
              "Host: %s\r\n"
              "Connection: close\r\n"
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 2a2877f..2788ff7 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -576,7 +576,8 @@  static int put_flac_codecpriv(AVFormatContext *s,
         const char *vendor = (s->flags & AVFMT_FLAG_BITEXACT) ?
                              "Lavf" : LIBAVFORMAT_IDENT;
         AVDictionary *dict = NULL;
-        uint8_t buf[32], *data, *p;
+        char buf[32];
+        uint8_t *data, *p;
         int64_t len;
 
         snprintf(buf, sizeof(buf), "0x%"PRIx64, par->channel_layout);
diff --git a/libavformat/md5proto.c b/libavformat/md5proto.c
index 0e04b90..23a067a 100644
--- a/libavformat/md5proto.c
+++ b/libavformat/md5proto.c
@@ -57,7 +57,8 @@  static int md5_close(URLContext *h)
 {
     struct MD5Context *c = h->priv_data;
     const char *filename = h->filename;
-    uint8_t md5[16], buf[64];
+    uint8_t md5[16];
+    char buf[64];
     URLContext *out;
     int i, err = 0;
 
diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c
index 9e422e1..d698711 100644
--- a/libavformat/nutenc.c
+++ b/libavformat/nutenc.c
@@ -533,7 +533,7 @@  static int write_streaminfo(NUTContext *nut, AVIOContext *bc, int stream_id) {
             count += add_info(dyn_bc, "Disposition", ff_nut_dispositions[i].str);
     }
     if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
-        uint8_t buf[256];
+        char buf[256];
         if (st->r_frame_rate.num>0 && st->r_frame_rate.den>0)
             snprintf(buf, sizeof(buf), "%d/%d", st->r_frame_rate.num, st->r_frame_rate.den);
         else
@@ -842,7 +842,7 @@  static int write_sm_data(AVFormatContext *s, AVIOContext *bc, AVPacket *pkt, int
     unsigned flags;
     AVIOContext *dyn_bc;
     int sm_data_count = 0;
-    uint8_t tmp[256];
+    char tmp[256];
     uint8_t *dyn_buf;
 
     ret = avio_open_dyn_buf(&dyn_bc);
diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c
index 0d693c2..4856808 100644
--- a/libavformat/rtmppkt.c
+++ b/libavformat/rtmppkt.c
@@ -494,10 +494,10 @@  int ff_amf_get_field_value(const uint8_t *data, const uint8_t *data_end,
         if (size == namelen && !memcmp(data-size, name, namelen)) {
             switch (*data++) {
             case AMF_DATA_TYPE_NUMBER:
-                snprintf(dst, dst_size, "%g", av_int2double(AV_RB64(data)));
+                snprintf((char *)dst, dst_size, "%g", av_int2double(AV_RB64(data)));
                 break;
             case AMF_DATA_TYPE_BOOL:
-                snprintf(dst, dst_size, "%s", *data ? "true" : "false");
+                snprintf((char *)dst, dst_size, "%s", *data ? "true" : "false");
                 break;
             case AMF_DATA_TYPE_STRING:
                 len = bytestream_get_be16(&data);
diff --git a/libavutil/hash.c b/libavutil/hash.c
index 7037b0d..27637b7 100644
--- a/libavutil/hash.c
+++ b/libavutil/hash.c
@@ -215,7 +215,7 @@  void av_hash_final_hex(struct AVHashContext *ctx, uint8_t *dst, int size)
 
     av_hash_final(ctx, buf);
     for (i = 0; i < FFMIN(rsize, size / 2); i++)
-        snprintf(dst + i * 2, size - i * 2, "%02x", buf[i]);
+        snprintf((char *)dst + i * 2, size - i * 2, "%02x", buf[i]);
 }
 
 void av_hash_final_b64(struct AVHashContext *ctx, uint8_t *dst, int size)
diff --git a/libavutil/opt.c b/libavutil/opt.c
index cd16bd1..f7f5225 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -733,7 +733,8 @@  int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
 {
     void *dst, *target_obj;
     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
-    uint8_t *bin, buf[128];
+    uint8_t *bin;
+    char buf[128];
     int len, i, ret;
     int64_t i64;
 
@@ -795,7 +796,7 @@  int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
         }
         bin = *(uint8_t **)dst;
         for (i = 0; i < len; i++)
-            snprintf(*out_val + i * 2, 3, "%02X", bin[i]);
+            snprintf(*(char **)out_val + i * 2, 3, "%02X", bin[i]);
         return 0;
     case AV_OPT_TYPE_IMAGE_SIZE:
         ret = snprintf(buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]);