From patchwork Thu Nov 3 15:29:05 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 123460 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from rcsinet15.oracle.com (rcsinet15.oracle.com [148.87.113.117]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "rcsinet15.oracle.com", Issuer "VeriSign Class 3 International Server CA - G3" (verified OK)) by ozlabs.org (Postfix) with ESMTPS id 59FB7B6F68 for ; Fri, 4 Nov 2011 02:29:23 +1100 (EST) Received: from ucsinet21.oracle.com (ucsinet21.oracle.com [156.151.31.93]) by rcsinet15.oracle.com (Switch-3.4.4/Switch-3.4.4) with ESMTP id pA3FTJ7U002470 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 3 Nov 2011 15:29:19 GMT Received: from oss.oracle.com (oss.oracle.com [141.146.12.120]) by ucsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id pA3FTISO023740 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 3 Nov 2011 15:29:18 GMT Received: from localhost ([127.0.0.1] helo=oss.oracle.com) by oss.oracle.com with esmtp (Exim 4.63) (envelope-from ) id 1RLzE9-0001l8-5f; Thu, 03 Nov 2011 08:29:13 -0700 Received: from rcsinet12.oracle.com ([148.87.113.124]) by oss.oracle.com with esmtp (Exim 4.63) (envelope-from ) id 1RLzE6-0001kl-6a for fedfs-utils-devel@oss.oracle.com; Thu, 03 Nov 2011 08:29:10 -0700 Received: from mail-qy0-f178.google.com (mail-qy0-f178.google.com [209.85.216.178]) by rcsinet12.oracle.com (Sentrion-MTA-4.2.0/Sentrion-MTA-4.2.0) with ESMTP id pA3FT7S0029723 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=OK) for ; Thu, 3 Nov 2011 15:29:09 GMT Received: by qyg14 with SMTP id 14so550365qyg.2 for ; Thu, 03 Nov 2011 08:29:07 -0700 (PDT) Received: by 10.229.69.130 with SMTP id z2mr1240178qci.16.1320334147599; Thu, 03 Nov 2011 08:29:07 -0700 (PDT) Received: from degas.1015granger.net ([99.26.161.222]) by mx.google.com with ESMTPS id ed2sm6301601qab.15.2011.11.03.08.29.06 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 03 Nov 2011 08:29:06 -0700 (PDT) From: Chuck Lever To: fedfs-utils-devel@oss.oracle.com Date: Thu, 03 Nov 2011 11:29:05 -0400 Message-ID: <20111103152904.2445.63715.stgit@degas.1015granger.net> In-Reply-To: <20111103152051.2445.69747.stgit@degas.1015granger.net> References: <20111103152051.2445.69747.stgit@degas.1015granger.net> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 Subject: [fedfs-utils] [PATCH 6/7] libjunction: Buffer overrun in fedfs_get_xattr() X-BeenThere: fedfs-utils-devel@oss.oracle.com X-Mailman-Version: 2.1.9 Precedence: list Reply-To: fedfs-utils Developers List-Id: fedfs-utils Developers List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: fedfs-utils-devel-bounces@oss.oracle.com Errors-To: fedfs-utils-devel-bounces@oss.oracle.com X-Source-IP: ucsinet21.oracle.com [156.151.31.93] X-CT-RefId: str=0001.0A090207.4EB2B350.0060:SCFSTAT3865452, ss=1, re=-4.000, fgs=0 Callers of fedfs_get_xattr() assume the returned buffer is NUL- terminated. It's not: it's an opaque stream of bytes. No caller expects an opaque byte stream, though. So convert fedfs_get_xattr() to return a NUL-terminated C string in a fresh buffer. Signed-off-by: Chuck Lever --- src/libjunction/junction.c | 45 ++++++++++++++++++++++---------------------- 1 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/libjunction/junction.c b/src/libjunction/junction.c index 6bc5310..73aa779 100644 --- a/src/libjunction/junction.c +++ b/src/libjunction/junction.c @@ -239,22 +239,22 @@ fedfs_is_xattr_present(int fd, const char *path, const char *name) } /** - * Retrieve the contents of xattr "name" + * Read the contents of xattr "name" * * @param fd an open file descriptor * @param path NUL-terminated C string containing pathname of a directory * @param name NUL-terminated C string containing name of xattr to retrieve - * @param contents OUT: opaque byte array containing contents of xattr - * @param contentlen OUT: size of "contents" + * @param contents OUT: NUL-terminated C string containing contents of xattr * @return a FedFsStatus code * + * Caller must free string returned in "contents" with free(3). + * * @note Access to trusted attributes requires CAP_SYS_ADMIN. */ static FedFsStatus -fedfs_get_xattr(int fd, const char *path, const char *name, void **contents, - size_t *contentlen) +fedfs_read_xattr(int fd, const char *path, const char *name, char **contents) { - void *xattrbuf = NULL; + char *xattrbuf = NULL; ssize_t len; len = fgetxattr(fd, name, xattrbuf, 0); @@ -264,7 +264,7 @@ fedfs_get_xattr(int fd, const char *path, const char *name, void **contents, return FEDFS_ERR_ACCESS; } - xattrbuf = malloc(len); + xattrbuf = (char *)malloc(len + 1); if (xattrbuf == NULL) { xlog(D_GENERAL, "%s: failed to get buffer for xattr %s on %s", __func__, name, path); @@ -277,11 +277,11 @@ fedfs_get_xattr(int fd, const char *path, const char *name, void **contents, free(xattrbuf); return FEDFS_ERR_ACCESS; } + xattrbuf[len] = '\0'; xlog(D_CALL, "%s: read xattr %s from path %s", __func__, name, path); *contents = xattrbuf; - *contentlen = len; return FEDFS_OK; } @@ -440,37 +440,39 @@ out_err: * @param fsn_uuid OUT: NUL-terminated C string containing FSN UUID to store * @param host OUT: an initialized nsdb_t object * @return a FedFsStatus code + * + * Caller must free string returned in "fsn_uuid" with free(3), and the + * host returned in "host" with nsdb_free_nsdb(). */ FedFsStatus fedfs_get_fsn(const char *pathname, char **fsn_uuid, nsdb_t *host) { - void *uuid_tmp = NULL; - void *nsdbname_tmp = NULL; - void *port_tmp = NULL; + char *uuid_tmp = NULL; + char *nsdbname_tmp = NULL; + char *port_tmp = NULL; nsdb_t host_tmp = NULL; unsigned short port; FedFsStatus retval; - size_t len; int fd; - if (fsn_uuid == NULL || host == NULL) + if (pathname == NULL || fsn_uuid == NULL || host == NULL) return FEDFS_ERR_INVAL; retval = fedfs_open_path(pathname, &fd); if (retval != FEDFS_OK) return retval; - retval = fedfs_get_xattr(fd, pathname, FEDFSD_XATTR_NAME_FSNUUID, - &uuid_tmp, &len); + retval = fedfs_read_xattr(fd, pathname, FEDFSD_XATTR_NAME_FSNUUID, + &uuid_tmp); if (retval != FEDFS_OK) goto out_err; - retval = fedfs_get_xattr(fd, pathname, FEDFSD_XATTR_NAME_NSDB, - &nsdbname_tmp, &len); + retval = fedfs_read_xattr(fd, pathname, FEDFSD_XATTR_NAME_NSDB, + &nsdbname_tmp); if (retval != FEDFS_OK) goto out_err; - retval = fedfs_get_xattr(fd, pathname, FEDFSD_XATTR_NAME_PORT, - &port_tmp, &len); + retval = fedfs_read_xattr(fd, pathname, FEDFSD_XATTR_NAME_PORT, + &port_tmp); if (retval != FEDFS_OK) goto out_err; @@ -670,15 +672,14 @@ fedfs_restore_mode(const char *pathname) { FedFsStatus retval; mode_t mode; - size_t len; - void *buf; + char *buf; int fd; retval = fedfs_open_path(pathname, &fd); if (retval != FEDFS_OK) return retval; - retval = fedfs_get_xattr(fd, pathname, FEDFSD_XATTR_NAME_MODE, &buf, &len); + retval = fedfs_read_xattr(fd, pathname, FEDFSD_XATTR_NAME_MODE, &buf); if (retval != FEDFS_OK) goto out;