From patchwork Wed Jan 4 21:06:57 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 134361 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 A93AD1007D7 for ; Thu, 5 Jan 2012 08:07:10 +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 q04L74A8000313 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 4 Jan 2012 21:07:04 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 q04L73uA024454 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 4 Jan 2012 21:07:03 GMT Received: from localhost ([127.0.0.1] helo=oss.oracle.com) by oss.oracle.com with esmtp (Exim 4.63) (envelope-from ) id 1RiY34-0001hN-Vb; Wed, 04 Jan 2012 13:07:03 -0800 Received: from rcsinet12.oracle.com ([148.87.113.124]) by oss.oracle.com with esmtp (Exim 4.63) (envelope-from ) id 1RiY33-0001hE-MW for fedfs-utils-devel@oss.oracle.com; Wed, 04 Jan 2012 13:07:01 -0800 Received: from mail-gx0-f171.google.com (mail-gx0-f171.google.com [209.85.161.171]) by rcsinet12.oracle.com (Sentrion-MTA-4.2.0/Sentrion-MTA-4.2.0) with ESMTP id q04L6xDe008731 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=OK) for ; Wed, 4 Jan 2012 21:07:01 GMT Received: by ggnh4 with SMTP id h4so12271742ggn.2 for ; Wed, 04 Jan 2012 13:06:59 -0800 (PST) Received: by 10.101.144.19 with SMTP id w19mr3368057ann.34.1325711219435; Wed, 04 Jan 2012 13:06:59 -0800 (PST) Received: from degas.1015granger.net (adsl-99-26-161-222.dsl.sfldmi.sbcglobal.net. [99.26.161.222]) by mx.google.com with ESMTPS id d8sm106104764ang.2.2012.01.04.13.06.58 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 04 Jan 2012 13:06:58 -0800 (PST) From: Chuck Lever To: fedfs-utils-devel@oss.oracle.com Date: Wed, 04 Jan 2012 16:06:57 -0500 Message-ID: <20120104210657.8810.73069.stgit@degas.1015granger.net> In-Reply-To: <20120104204207.8810.10569.stgit@degas.1015granger.net> References: <20120104204207.8810.10569.stgit@degas.1015granger.net> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 X-Flow-Control-Info: class=Default ip=209.85.161.171 ct-class=R6 ct-vol1=0 ct-vol2=0 ct-vol3=0 ct-risk=68 ct-spam1=0 ct-spam2=0 ct-bulk=0 rcpts=1 size=3982 Subject: [fedfs-utils] [PATCH 5/7] libjunction: Don't treat opaque byte array as NUL-terminated 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.0A090208.4F04BF79.002E:SCFSTAT3865452, ss=1, re=-4.000, fgs=0 junction_get_xattr() returns an opaque byte array, but junction_restore_mode() treats it like a NUL-terminated string. Bad function, no biscuit. Fork off a second API that can return a NUL-terminated string. Callers will have to take care to choose the correct API. Introduced in commit 0520ee72: "Initial commit," (March 29, 2011). Signed-off-by: Chuck Lever --- src/libjunction/junction-internal.h | 2 + src/libjunction/junction.c | 57 +++++++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/libjunction/junction-internal.h b/src/libjunction/junction-internal.h index c013275..5be355d 100644 --- a/src/libjunction/junction-internal.h +++ b/src/libjunction/junction-internal.h @@ -32,6 +32,8 @@ FedFsStatus junction_is_sticky_bit_set(int fd, const char *path); FedFsStatus junction_set_sticky_bit(int fd, const char *path); FedFsStatus junction_is_xattr_present(int fd, const char *path, const char *name); +FedFsStatus junction_read_xattr(int fd, const char *path, const char *name, + char **contents); FedFsStatus junction_get_xattr(int fd, const char *path, const char *name, void **contents, size_t *contentlen); FedFsStatus junction_set_xattr(int fd, const char *path, const char *name, diff --git a/src/libjunction/junction.c b/src/libjunction/junction.c index 7bde11a..832c19f 100644 --- a/src/libjunction/junction.c +++ b/src/libjunction/junction.c @@ -221,6 +221,54 @@ junction_is_xattr_present(int fd, const char *path, const char *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: NUL-terminated C string containing contents of xattr + * @return a FedFsStatus code + * + * If junction_read_xattr() returns FEDFS_OK, the caller must free "*contents" + * with free(3). + * + * @note Access to trusted attributes requires CAP_SYS_ADMIN. + */ +FedFsStatus +junction_read_xattr(int fd, const char *path, const char *name, char **contents) +{ + char *xattrbuf = NULL; + ssize_t len; + + len = fgetxattr(fd, name, xattrbuf, 0); + if (len == -1) { + xlog(D_GENERAL, "%s: failed to get size of xattr %s on %s: %m", + __func__, name, path); + return FEDFS_ERR_ACCESS; + } + + xattrbuf = malloc(len + 1); + if (xattrbuf == NULL) { + xlog(D_GENERAL, "%s: failed to get buffer for xattr %s on %s", + __func__, name, path); + return FEDFS_ERR_SVRFAULT; + } + + if (fgetxattr(fd, name, xattrbuf, len) == -1) { + xlog(D_GENERAL, "%s: failed to get xattr %s on %s: %m", + __func__, name, path); + free(xattrbuf); + return FEDFS_ERR_ACCESS; + } + xattrbuf[len] = '\0'; + + xlog(D_CALL, "%s: read xattr %s from path %s", + __func__, name, path); + *contents = xattrbuf; + return FEDFS_OK; +} + +/** * Retrieve the contents of xattr "name" * * @param fd an open file descriptor @@ -230,6 +278,9 @@ junction_is_xattr_present(int fd, const char *path, const char *name) * @param contentlen OUT: size of "contents" * @return a FedFsStatus code * + * If junction_get_xattr() returns FEDFS_OK, the caller must free "*contents" + * with free(3). + * * @note Access to trusted attributes requires CAP_SYS_ADMIN. */ FedFsStatus @@ -386,17 +437,15 @@ FedFsStatus junction_restore_mode(const char *pathname) { FedFsStatus retval; + char *buf = NULL; mode_t mode; - size_t len; - void *buf; int fd; retval = junction_open_path(pathname, &fd); if (retval != FEDFS_OK) return retval; - retval = junction_get_xattr(fd, pathname, JUNCTION_XATTR_NAME_MODE, - &buf, &len); + retval = junction_read_xattr(fd, pathname, JUNCTION_XATTR_NAME_MODE, &buf); if (retval != FEDFS_OK) goto out;