[fedfs-utils] [PATCH 5/7] libjunction: Don't treat opaque byte array as NUL-terminated
Chuck Lever
chuck.lever at oracle.com
Wed Jan 4 13:06:57 PST 2012
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 <chuck.lever at oracle.com>
---
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;
More information about the fedfs-utils-devel
mailing list