aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2008-01-26 22:35:47 +0000
committerEric Wong <normalperson@yhbt.net>2008-01-26 22:35:47 +0000
commitc0c0bac6573c2c89894d3ee20a9b01e452cea6fd (patch)
tree48257d227789ca59bf3d33e63635f22c9af8c626
parente5a7c14227a2ca69e0e07ac9dc62d6e31f16121a (diff)
downloadmpd-c0c0bac6573c2c89894d3ee20a9b01e452cea6fd.tar.gz
mpd-c0c0bac6573c2c89894d3ee20a9b01e452cea6fd.tar.xz
mpd-c0c0bac6573c2c89894d3ee20a9b01e452cea6fd.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. r7154 in trunk git-svn-id: https://svn.musicpd.org/mpd/branches/branch-0.13.0-fixes@7165 09075e82-0dd4-0310-85a5-a0d7c8717e4f
-rw-r--r--src/playlist.c2
-rw-r--r--src/playlist.h2
-rw-r--r--src/storedPlaylist.c17
3 files changed, 19 insertions, 2 deletions
diff --git a/src/playlist.c b/src/playlist.c
index 02528908b..56915a487 100644
--- a/src/playlist.c
+++ b/src/playlist.c
@@ -65,7 +65,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 0ae3a677f..c06357b1e 100644
--- a/src/playlist.h
+++ b/src/playlist.h
@@ -47,6 +47,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 32e22cc4a..0451316ea 100644
--- a/src/storedPlaylist.c
+++ b/src/storedPlaylist.c
@@ -191,6 +191,9 @@ StoredPlaylist *loadStoredPlaylist(const char *utf8path, int fd)
slength = 0;
temp = fsCharsetToUtf8(s);
if (temp && !commentCharFound) {
+ if (sp->list->numberOfNodes >=
+ (playlist_max_length - 1))
+ goto out;
song = getSongFromDB(temp);
if (song) {
appendSongToStoredPlaylist(sp, song);
@@ -424,17 +427,29 @@ int appendSongToStoredPlaylistByPath(int fd, const char *utf8path, Song *song)
char *filename;
FILE *file;
char *s;
+ int nr_songs = 0;
+ char path_max_tmp[MAXPATHLEN + 1];
filename = utf8pathToFsPathInStoredPlaylist(utf8path, fd);
if (!filename)
return -1;
- while (!(file = fopen(filename, "a")) && errno == EINTR);
+ while (!(file = fopen(filename, "a+")) && errno == EINTR);
if (file == NULL) {
commandError(fd, ACK_ERROR_NO_EXIST, "could not open file "
"\"%s\": %s", filename, 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;
+ }
if (playlist_saveAbsolutePaths && song->type == SONG_TYPE_FILE)
s = rmp2amp(utf8ToFsCharset(getSongUrl(song)));