diff options
author | Eric Wong <normalperson@yhbt.net> | 2008-01-26 20:20:59 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2008-01-26 20:20:59 +0000 |
commit | 29df70366c807a671611720ad0419c6da1ac0e41 (patch) | |
tree | 61e2975a336efb2a1f76d7bacd42afe278252692 | |
parent | 3a1b3e3807609434bf3f392b6b1f66ac218e265c (diff) | |
download | mpd-29df70366c807a671611720ad0419c6da1ac0e41.tar.gz mpd-29df70366c807a671611720ad0419c6da1ac0e41.tar.xz mpd-29df70366c807a671611720ad0419c6da1ac0e41.zip |
storedPlaylist: prevent potential DoS from stored playlist commands
While mpd has always protected against the infinite expansion of
the main playlist by limiting its size in memory, however the
new storedPlaylist code has never checked for this limit.
Malicious (or clumsy) users could repeatedly append songs to
stored playlists, causing files to grow increasingly large
on disk. Attempting to load extremely large files into memory
will require mpd to slurp that all into memory, and ultimately
the file would be unusable by mpd because of the configurable
playlist size limit.
Now we limit stored playlists to the max_playlist_length
configuration variable set by the user (default is 16384). We
will refuse to append to playlist files if they hit that limit;
and also refuse to load more than the specified amount of songs
into memory.
git-svn-id: https://svn.musicpd.org/mpd/trunk@7154 09075e82-0dd4-0310-85a5-a0d7c8717e4f
-rw-r--r-- | src/playlist.c | 2 | ||||
-rw-r--r-- | src/playlist.h | 2 | ||||
-rw-r--r-- | src/storedPlaylist.c | 16 |
3 files changed, 18 insertions, 2 deletions
diff --git a/src/playlist.c b/src/playlist.c index 0f76c49a0..e67fb9430 100644 --- a/src/playlist.c +++ b/src/playlist.c @@ -58,7 +58,7 @@ static Playlist playlist; static int playlist_state = PLAYLIST_STATE_STOP; -static int playlist_max_length = DEFAULT_PLAYLIST_MAX_LENGTH; +int playlist_max_length = DEFAULT_PLAYLIST_MAX_LENGTH; static int playlist_stopOnError; static int playlist_errorCount; static int playlist_queueError; diff --git a/src/playlist.h b/src/playlist.h index 2e5ccf9ab..732ea814e 100644 --- a/src/playlist.h +++ b/src/playlist.h @@ -45,6 +45,8 @@ typedef struct _Playlist { extern int playlist_saveAbsolutePaths; +extern int playlist_max_length; + void initPlaylist(void); void finishPlaylist(void); diff --git a/src/storedPlaylist.c b/src/storedPlaylist.c index b0d66fb10..69eb34807 100644 --- a/src/storedPlaylist.c +++ b/src/storedPlaylist.c @@ -129,6 +129,9 @@ List *loadStoredPlaylist(int fd, const char *utf8path) insertInListWithoutKey(list, xstrdup(path_max_tmp)); } else if (isValidRemoteUtf8Url(s)) insertInListWithoutKey(list, xstrdup(s)); + + if (list->numberOfNodes >= playlist_max_length) + break; } while (fclose(file) && errno == EINTR); @@ -284,6 +287,7 @@ int appendSongToStoredPlaylistByPath(int fd, const char *utf8path, Song *song) { FILE *file; char *s; + int nr_songs = 0; char path_max_tmp[MPD_PATH_MAX]; char path_max_tmp2[MPD_PATH_MAX]; @@ -291,12 +295,22 @@ int appendSongToStoredPlaylistByPath(int fd, const char *utf8path, Song *song) return -1; utf8_to_fs_playlist_path(path_max_tmp, utf8path); - while (!(file = fopen(path_max_tmp, "a")) && errno == EINTR); + while (!(file = fopen(path_max_tmp, "a+")) && errno == EINTR); if (file == NULL) { commandError(fd, ACK_ERROR_NO_EXIST, "could not open file " "\"%s\": %s", path_max_tmp, strerror(errno)); return -1; } + while (myFgets(path_max_tmp, sizeof(path_max_tmp), file)) { + if (path_max_tmp[0] != PLAYLIST_COMMENT && + (++nr_songs >= playlist_max_length)) + break; + } + if (nr_songs >= playlist_max_length) { + commandError(fd, ACK_ERROR_PLAYLIST_MAX, + "playlist is at the max size"); + return -1; + } s = utf8_to_fs_charset(path_max_tmp2, get_song_url(path_max_tmp, song)); |