diff options
-rw-r--r-- | source3/lib/xattr_tdb.c | 12 | ||||
-rw-r--r-- | source3/lib/xattr_tdb.h | 3 | ||||
-rw-r--r-- | source3/modules/vfs_xattr_tdb.c | 43 |
3 files changed, 47 insertions, 11 deletions
diff --git a/source3/lib/xattr_tdb.c b/source3/lib/xattr_tdb.c index 21223f04b8..6f33163ed6 100644 --- a/source3/lib/xattr_tdb.c +++ b/source3/lib/xattr_tdb.c @@ -169,8 +169,9 @@ static NTSTATUS xattr_tdb_save_attrs(struct db_record *rec, */ ssize_t xattr_tdb_getattr(struct db_context *db_ctx, + TALLOC_CTX *mem_ctx, const struct file_id *id, - const char *name, void *value, size_t size) + const char *name, DATA_BLOB *blob) { struct tdb_xattrs *attribs; uint32_t i; @@ -200,13 +201,8 @@ ssize_t xattr_tdb_getattr(struct db_context *db_ctx, goto fail; } - if (attribs->eas[i].value.length > size) { - errno = ERANGE; - goto fail; - } - - memcpy(value, attribs->eas[i].value.data, - attribs->eas[i].value.length); + *blob = attribs->eas[i].value; + talloc_steal(mem_ctx, blob->data); result = attribs->eas[i].value.length; fail: diff --git a/source3/lib/xattr_tdb.h b/source3/lib/xattr_tdb.h index 0a54833f51..03bc43a38c 100644 --- a/source3/lib/xattr_tdb.h +++ b/source3/lib/xattr_tdb.h @@ -26,8 +26,9 @@ /* The following definitions come from lib/util/xattr_tdb.c */ ssize_t xattr_tdb_getattr(struct db_context *db_ctx, + TALLOC_CTX *mem_ctx, const struct file_id *id, - const char *name, void *value, size_t size); + const char *name, DATA_BLOB *blob); int xattr_tdb_setattr(struct db_context *db_ctx, const struct file_id *id, const char *name, const void *value, size_t size, int flags); diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c index f5e5440e16..5c105b5194 100644 --- a/source3/modules/vfs_xattr_tdb.c +++ b/source3/modules/vfs_xattr_tdb.c @@ -34,16 +34,35 @@ static ssize_t xattr_tdb_getxattr(struct vfs_handle_struct *handle, SMB_STRUCT_STAT sbuf; struct file_id id; struct db_context *db; + ssize_t xattr_size; + DATA_BLOB blob; + TALLOC_CTX *frame = talloc_stackframe(); + if (!frame) { + errno = ENOMEM; + return -1; + } SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); if (vfs_stat_smb_fname(handle->conn, path, &sbuf) == -1) { + TALLOC_FREE(frame); return -1; } id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf); - return xattr_tdb_getattr(db, &id, name, value, size); + xattr_size = xattr_tdb_getattr(db, frame, &id, name, &blob); + if (xattr_size < 0) { + TALLOC_FREE(frame); + return -1; + } + if (blob.length > size) { + TALLOC_FREE(frame); + errno = ERANGE; + return -1; + } + memcpy(value, blob.data, size); + return xattr_size; } static ssize_t xattr_tdb_fgetxattr(struct vfs_handle_struct *handle, @@ -53,16 +72,36 @@ static ssize_t xattr_tdb_fgetxattr(struct vfs_handle_struct *handle, SMB_STRUCT_STAT sbuf; struct file_id id; struct db_context *db; + ssize_t xattr_size; + DATA_BLOB blob; + TALLOC_CTX *frame = talloc_stackframe(); + if (!frame) { + errno = ENOMEM; + return -1; + } SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) { + TALLOC_FREE(frame); return -1; } id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf); - return xattr_tdb_getattr(db, &id, name, value, size); + xattr_size = xattr_tdb_getattr(db, frame, &id, name, &blob); + if (xattr_size < 0) { + TALLOC_FREE(frame); + return -1; + } + if (blob.length > size) { + TALLOC_FREE(frame); + errno = ERANGE; + return -1; + } + memcpy(value, blob.data, size); + TALLOC_FREE(frame); + return xattr_size; } static int xattr_tdb_setxattr(struct vfs_handle_struct *handle, |