Fix up write_versions() to eliminate the possibility of overflowing its output buffer. Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx> --- fs/nfsd/nfsctl.c | 26 ++++++++++++++++++-------- 1 files changed, 18 insertions(+), 8 deletions(-) diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index f8a2a7f..41e09c6 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -777,7 +777,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size) { char *mesg = buf; char *vers, sign; - int len, num; + int len, num, remaining; ssize_t tlen = 0; char *sep; @@ -818,18 +818,28 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size) */ nfsd_reset_versions(); } + /* Now write current state into reply buffer */ - len = 0; + tlen = 0; sep = ""; - for (num=2 ; num <= 4 ; num++) + remaining = SIMPLE_TRANSACTION_LIMIT; + for (num = 2 ; num <= 4 ; num++) if (nfsd_vers(num, NFSD_AVAIL)) { - len += sprintf(buf+len, "%s%c%d", sep, - nfsd_vers(num, NFSD_TEST)?'+':'-', - num); + len = snprintf(buf, remaining, "%s%c%d", sep, + nfsd_vers(num, NFSD_TEST) ? '+' : '-', + num); sep = " "; + + if (len >= remaining - 1) + break; + + remaining -= len; + buf += len; + tlen += len; } - len += sprintf(buf+len, "\n"); - return len; + snprintf(buf, remaining, "\n"); + + return tlen; } /** -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html