summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorBob Beck <beck@cvs.openbsd.org>2009-12-14 16:26:20 +0000
committerBob Beck <beck@cvs.openbsd.org>2009-12-14 16:26:20 +0000
commit08715c4cca55339b6172439518c6befab992639b (patch)
treea646f2f31bb00b51f03780fb831e4ebb039d1d00 /usr.sbin
parent2c1805e867fb1bf521080a933ba332efe85d5da2 (diff)
Fix buffer overflow possibility, noticed by parfait:
Buffer overflow (CWE 120): In memcpy of msg.msg with length 'size' Array size is 2048 bytes, size <= 2080 at line 317 of /usr/src/usr.sbin/afs/src/arlad/nnpfs.c in function 'nnpf s_send_message_wakeup_data'. tesing by todd@ and jj@ and me
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/afs/src/arlad/messages.c50
-rw-r--r--usr.sbin/afs/src/arlad/nnpfs.c15
2 files changed, 39 insertions, 26 deletions
diff --git a/usr.sbin/afs/src/arlad/messages.c b/usr.sbin/afs/src/arlad/messages.c
index 458e3ce03d3..068d7aa7cdb 100644
--- a/usr.sbin/afs/src/arlad/messages.c
+++ b/usr.sbin/afs/src/arlad/messages.c
@@ -2375,8 +2375,11 @@ viocgetvolstat(int fd, struct nnpfs_message_pioctl *h, u_int size)
char volumename[AFSNAMEMAX];
char offlinemsg[AFSOPAQUEMAX];
char motd[AFSOPAQUEMAX];
- char out[SYSNAMEMAXLEN];
+ char out[NNPFS_MSG_MAX_DATASIZE];
+ char * outstr;
int32_t outsize = 0;
+ int32_t os = 0;
+ int32_t osmax = 0;
int error;
if (!h->handle.a && !h->handle.b && !h->handle.c && !h->handle.d)
@@ -2393,7 +2396,8 @@ viocgetvolstat(int fd, struct nnpfs_message_pioctl *h, u_int size)
memset (volumename, 0, AFSNAMEMAX);
memset (offlinemsg, 0, AFSOPAQUEMAX);
memset (motd, 0, AFSOPAQUEMAX);
- memset (out, 0, SYSNAMEMAXLEN);
+
+ memset (out, 0, sizeof(out));
do {
error = getvolstat (fid, ce, &volstat,
@@ -2409,33 +2413,39 @@ viocgetvolstat(int fd, struct nnpfs_message_pioctl *h, u_int size)
memcpy (out, (char *) &volstat, sizeof (AFSFetchVolumeStatus));
outsize = sizeof (AFSFetchVolumeStatus);
+ outstr = out + outsize;
+ os = 0;
+ osmax = sizeof(out) - outsize;
- if (volumename[0]) {
- strncpy (out+outsize, volumename, AFSNAMEMAX);
- outsize += strlen (volumename);
- }
+ if (os < osmax && (volumename[0]))
+ os = strlcat(outstr, volumename, osmax);
else {
- out[outsize] = 0;
+ *outstr++ = '\0';
outsize++;
+ osmax--;
}
-
- if (offlinemsg[0]) {
- strncpy (out+outsize, offlinemsg, AFSOPAQUEMAX);
- outsize += strlen (offlinemsg);
- }
+ if (os < osmax && (offlinemsg[0]))
+ os = strlcat(outstr, offlinemsg, osmax);
else {
- out[outsize] = 0;
+ *outstr++ = '\0';
outsize++;
+ osmax--;
}
-
- if (motd[0]) {
- strncpy (out+outsize, motd, AFSOPAQUEMAX);
- outsize += strlen (motd);
- }
+ if (os < osmax && (motd[0]))
+ os = strlcat(outstr, motd, osmax);
else {
- out[outsize] = 0;
+ *outstr++ = '\0';
outsize++;
+ osmax--;
}
+ /* this can potentially truncate the motd.. who cares */
+ if (os + outsize >= sizeof(out)) {
+ /* XXX warn about trucated motd */
+ arla_warnx(ADEBMSG,
+ "truncated motd by %d bytes", os + outsize - sizeof(out));
+ outsize = sizeof(out);
+ } else
+ outsize += os;
nnpfs_send_message_wakeup_data (fd, h->header.sequence_num, error,
out, outsize);
@@ -3433,7 +3443,7 @@ vioc_fpriostatus (int fd, struct nnpfs_message_pioctl *h, u_int size)
error = EINVAL;
break;
}
-
+
prio = fprio_get(fid);
nnpfs_send_message_wakeup_data (fd,
h->header.sequence_num,
diff --git a/usr.sbin/afs/src/arlad/nnpfs.c b/usr.sbin/afs/src/arlad/nnpfs.c
index 9edb5c837ce..ff92528aeb7 100644
--- a/usr.sbin/afs/src/arlad/nnpfs.c
+++ b/usr.sbin/afs/src/arlad/nnpfs.c
@@ -306,19 +306,22 @@ nnpfs_send_message_wakeup_data (int fd, u_int seqnum, int error,
void *data, int size)
{
struct nnpfs_message_wakeup_data msg;
-
+
msg.header.opcode = NNPFS_MSG_WAKEUP_DATA;
msg.sleepers_sequence_num = seqnum;
msg.error = error;
arla_warnx (ADEBMSG,
"sending wakeup: seq = %u, error = %d", seqnum, error);
- if (sizeof(msg) >= size && size != 0) {
- memcpy(msg.msg, data, size);
- }
-
+ if (sizeof(msg.msg) < size || size < 0) {
+ errno = EINVAL;
+ arla_warn (ADEBMSG,
+ "nnpfs_send_message_wakeup_data: invalid message size %d",
+ size);
+ return errno;
+ } else
+ memcpy(msg.msg, data, size);
msg.len = size;
-
return nnpfs_message_send (fd, (struct nnpfs_message_header *)&msg,
sizeof(msg));
}