On 1/15/26 7:43 PM, Alison Schofield wrote:
> The close() system call may modify errno. In __sysfs_read_attr(),
> errno is used after close() for both logging and the return value,
> which can result in reporting the wrong error. In write_attr(),
> errno is saved before close(), but the saved value was not used
> for logging.
>
> Without this fix, if close() modifies errno, users may see incorrect
> error messages that don't reflect the actual failure and the function
> may return the wrong error code causing the calling code to handle
> the error incorrectly.
>
> Save errno immediately after read() in __sysfs_read_attr(), matching
> the existing write_attr() pattern, and use the saved values for both
> logging and return paths.
>
> Found while preparing a patch to expand the log messages in sysfs.c
>
> Signed-off-by: Alison Schofield <[email protected]>
Reviewed-by: Dave Jiang <[email protected]>
> ---
> util/sysfs.c | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/util/sysfs.c b/util/sysfs.c
> index 968683b19f4e..5a12c639fe4d 100644
> --- a/util/sysfs.c
> +++ b/util/sysfs.c
> @@ -21,18 +21,19 @@
> int __sysfs_read_attr(struct log_ctx *ctx, const char *path, char *buf)
> {
> int fd = open(path, O_RDONLY|O_CLOEXEC);
> - int n;
> + int n, rc;
>
> if (fd < 0) {
> log_dbg(ctx, "failed to open %s: %s\n", path, strerror(errno));
> return -errno;
> }
> n = read(fd, buf, SYSFS_ATTR_SIZE);
> + rc = -errno;
> close(fd);
> if (n < 0 || n >= SYSFS_ATTR_SIZE) {
> buf[0] = 0;
> - log_dbg(ctx, "failed to read %s: %s\n", path, strerror(errno));
> - return -errno;
> + log_dbg(ctx, "failed to read %s: %s\n", path, strerror(-rc));
> + return rc;
> }
> buf[n] = 0;
> if (n && buf[n-1] == '\n')
> @@ -57,7 +58,7 @@ static int write_attr(struct log_ctx *ctx, const char *path,
> if (n < len) {
> if (!quiet)
> log_dbg(ctx, "failed to write %s to %s: %s\n", buf,
> path,
> - strerror(errno));
> + strerror(-rc));
> return rc;
> }
> return 0;