diff options
| author | David 'Digit' Turner <digit@google.com> | 2011-01-17 03:29:04 +0100 |
|---|---|---|
| committer | David 'Digit' Turner <digit@google.com> | 2011-01-19 02:18:40 +0100 |
| commit | c6b0def5f039dc3bbe1d4b7dc1666c24316eb020 (patch) | |
| tree | 4b4e46acd532701eee188c4a72926edcc32073fc /libsysutils | |
| parent | cf9e1003ce69a2aea2c64cd82d54a0d3e8917dbb (diff) | |
| download | system_core-c6b0def5f039dc3bbe1d4b7dc1666c24316eb020.tar.gz system_core-c6b0def5f039dc3bbe1d4b7dc1666c24316eb020.tar.bz2 system_core-c6b0def5f039dc3bbe1d4b7dc1666c24316eb020.zip | |
libsysutils: Fix potential overwrites in FrameworkListener
+ Handle EINTR in read()
Change-Id: If7d486dd4fb5666ce16ef36dca5f417da23e0b73
Diffstat (limited to 'libsysutils')
| -rw-r--r-- | libsysutils/src/FrameworkListener.cpp | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/libsysutils/src/FrameworkListener.cpp b/libsysutils/src/FrameworkListener.cpp index 4da8eb66..3416ceb1 100644 --- a/libsysutils/src/FrameworkListener.cpp +++ b/libsysutils/src/FrameworkListener.cpp @@ -34,7 +34,8 @@ bool FrameworkListener::onDataAvailable(SocketClient *c) { char buffer[255]; int len; - if ((len = read(c->getSocket(), buffer, sizeof(buffer) -1)) < 0) { + len = TEMP_FAILURE_RETRY(read(c->getSocket(), buffer, sizeof(buffer))); + if (len < 0) { SLOGE("read() failed (%s)", strerror(errno)); return false; } else if (!len) @@ -45,6 +46,7 @@ bool FrameworkListener::onDataAvailable(SocketClient *c) { for (i = 0; i < len; i++) { if (buffer[i] == '\0') { + /* IMPORTANT: dispatchCommand() expects a zero-terminated string */ dispatchCommand(c, buffer + offset); offset = i + 1; } @@ -63,6 +65,7 @@ void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) { char tmp[255]; char *p = data; char *q = tmp; + char *qlimit = tmp + sizeof(tmp) - 1; bool esc = false; bool quote = false; int k; @@ -72,6 +75,8 @@ void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) { while(*p) { if (*p == '\\') { if (esc) { + if (q >= qlimit) + goto overflow; *q++ = '\\'; esc = false; } else @@ -79,11 +84,15 @@ void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) { p++; continue; } else if (esc) { - if (*p == '"') + if (*p == '"') { + if (q >= qlimit) + goto overflow; *q++ = '"'; - else if (*p == '\\') + } else if (*p == '\\') { + if (q >= qlimit) + goto overflow; *q++ = '\\'; - else { + } else { cli->sendMsg(500, "Unsupported escape sequence", false); goto out; } @@ -101,9 +110,13 @@ void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) { continue; } + if (q >= qlimit) + goto overflow; *q = *p++; if (!quote && *q == ' ') { *q = '\0'; + if (argc >= CMD_ARGS_MAX) + goto overflow; argv[argc++] = strdup(tmp); memset(tmp, 0, sizeof(tmp)); q = tmp; @@ -112,6 +125,9 @@ void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) { q++; } + *q = '\0'; + if (argc >= CMD_ARGS_MAX) + goto overflow; argv[argc++] = strdup(tmp); #if 0 for (k = 0; k < argc; k++) { @@ -123,7 +139,7 @@ void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) { cli->sendMsg(500, "Unclosed quotes error", false); goto out; } - + for (i = mCommands->begin(); i != mCommands->end(); ++i) { FrameworkCommand *c = *i; @@ -141,4 +157,8 @@ out: for (j = 0; j < argc; j++) free(argv[j]); return; + +overflow: + cli->sendMsg(500, "Command too long", false); + goto out; } |
