From 866e0e1670f79653203a3da65096841ab37fc903 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 31 Aug 2014 19:49:39 +0200 Subject: player: always load playlists Until now, you had to use --load-unsafe-playlists or --playlist to get playlists loaded. Change this and always load playlists by default. This still attempts to reject unsafe URLs. For example, trying to invoke libavdevice pseudo-demuxer is explicitly prevented. Local paths and any http links (and some more) are always allowed. --- stream/stream.c | 16 ++++++++++++++++ stream/stream.h | 3 +++ stream/stream_file.c | 1 + stream/stream_lavf.c | 20 +++++++++++++++++--- 4 files changed, 37 insertions(+), 3 deletions(-) (limited to 'stream') diff --git a/stream/stream.c b/stream/stream.c index cfb3cb6c82..226626cf3c 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -61,6 +61,7 @@ extern const stream_info_t stream_info_null; extern const stream_info_t stream_info_memory; extern const stream_info_t stream_info_mf; extern const stream_info_t stream_info_ffmpeg; +extern const stream_info_t stream_info_ffmpeg_unsafe; extern const stream_info_t stream_info_avdevice; extern const stream_info_t stream_info_file; extern const stream_info_t stream_info_ifo; @@ -77,6 +78,7 @@ static const stream_info_t *const stream_list[] = { &stream_info_cdda, #endif &stream_info_ffmpeg, + &stream_info_ffmpeg_unsafe, &stream_info_avdevice, #if HAVE_DVBIN &stream_info_dvb, @@ -257,6 +259,8 @@ static int open_internal(const stream_info_t *sinfo, struct stream *underlying, return STREAM_NO_MATCH; if (sinfo->stream_filter && (flags & STREAM_NO_FILTERS)) return STREAM_NO_MATCH; + if (!sinfo->is_safe && (flags & STREAM_SAFE_ONLY)) + return STREAM_UNSAFE; const char *path = NULL; // Stream filters use the original URL, with no protocol matching at all. @@ -335,18 +339,30 @@ struct stream *stream_create(const char *url, int flags, struct mpv_global *glob assert(url); // Open stream proper + bool unsafe = false; for (int i = 0; stream_list[i]; i++) { int r = open_internal(stream_list[i], NULL, url, flags, global, &s); if (r == STREAM_OK) break; if (r == STREAM_NO_MATCH || r == STREAM_UNSUPPORTED) continue; + if (r == STREAM_UNSAFE) { + unsafe = true; + continue; + } if (r != STREAM_OK) { mp_err(log, "Failed to open %s.\n", url); goto done; } } + if (!s && unsafe) { + mp_err(log, "\nRefusing to load potentially unsafe URL from a playlist.\n" + "Use --playlist=file or the --load-unsafe-playlists option to " + "load it anyway.\n\n"); + goto done; + } + if (!s) { mp_err(log, "No stream found to handle url %s\n", url); goto done; diff --git a/stream/stream.h b/stream/stream.h index a961267aac..94103962c9 100644 --- a/stream/stream.h +++ b/stream/stream.h @@ -55,7 +55,9 @@ enum streamtype { // flags for stream_open_ext (this includes STREAM_READ and STREAM_WRITE) #define STREAM_NO_FILTERS 2 +#define STREAM_SAFE_ONLY 4 +#define STREAM_UNSAFE -3 #define STREAM_NO_MATCH -2 #define STREAM_UNSUPPORTED -1 #define STREAM_ERROR 0 @@ -141,6 +143,7 @@ typedef struct stream_info_st { const char *const *url_options; bool stream_filter; bool can_write; + bool is_safe; } stream_info_t; typedef struct stream { diff --git a/stream/stream_file.c b/stream/stream_file.c index 12bea3554c..6a10114832 100644 --- a/stream/stream_file.c +++ b/stream/stream_file.c @@ -281,4 +281,5 @@ const stream_info_t stream_info_file = { .open = open_f, .protocols = (const char*const[]){ "file", "", NULL }, .can_write = true, + .is_safe = true, }; diff --git a/stream/stream_lavf.c b/stream/stream_lavf.c index 37c6adc51c..2270831b88 100644 --- a/stream/stream_lavf.c +++ b/stream/stream_lavf.c @@ -322,10 +322,24 @@ const stream_info_t stream_info_ffmpeg = { .name = "ffmpeg", .open = open_f, .protocols = (const char *const[]){ - "lavf", "ffmpeg", "rtmp", "rtsp", "http", "https", "mms", "mmst", "mmsh", - "mmshttp", "udp", "ftp", "rtp", "httpproxy", "hls", "rtmpe", "rtmps", - "rtmpt", "rtmpte", "rtmpts", "srtp", "tcp", "udp", "tls", "unix", "sftp", + "rtmp", "rtsp", "http", "https", "mms", "mmst", "mmsh", "mmshttp", "rtp", + "httpproxy", "hls", "rtmpe", "rtmps", "rtmpt", "rtmpte", "rtmpts", "srtp", "md5", NULL }, .can_write = true, + .is_safe = true, }; + +// Unlike above, this is not marked as safe, and can contain protocols which +// may do insecure things. (Such as "ffmpeg", which can access the "lavfi" +// pseudo-demuxer, which in turn gives access to filters that can access the +// local filesystem.) +const stream_info_t stream_info_ffmpeg_unsafe = { + .name = "ffmpeg", + .open = open_f, + .protocols = (const char *const[]){ + "lavf", "ffmpeg", "udp", "ftp", "tcp", "tls", "unix", "sftp", + NULL }, + .can_write = true, +}; + -- cgit v1.2.3