Patchwork [5/7] libjunction: Don't treat opaque byte array as NUL-terminated

login
register
mail settings
Submitter Chuck Lever
Date Jan. 4, 2012, 9:06 p.m.
Message ID <20120104210657.8810.73069.stgit@degas.1015granger.net>
Download mbox | patch
Permalink /patch/134361/
State Accepted
Headers show

Comments

Chuck Lever - Jan. 4, 2012, 9:06 p.m.
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@oracle.com>
---

 src/libjunction/junction-internal.h |    2 +
 src/libjunction/junction.c          |   57 +++++++++++++++++++++++++++++++++--
 2 files changed, 55 insertions(+), 4 deletions(-)

Patch

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;