From 40e4c9031652731622315e778a9bcace6cea6cb3 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Tue, 13 Oct 2026 21:11:23 +0900 Subject: internal/acl: use O_PATH descriptor This avoids TOCTOU during hakurei_update_acl. Signed-off-by: Ophestra --- internal/acl/acl.go | 19 +++++++++++++++++-- internal/acl/libacl-helper.c | 10 ++++++---- internal/acl/libacl-helper.h | 2 +- 3 files changed, 24 insertions(+), 7 deletions(-) (limited to 'internal') diff --git a/internal/acl/acl.go b/internal/acl/acl.go index 7718ba3c..8b862ba2 100644 --- a/internal/acl/acl.go +++ b/internal/acl/acl.go @@ -7,7 +7,12 @@ package acl #include "libacl-helper.h" */ import "C" -import "os" + +import ( + "os" + + "hakurei.app/container" +) // Perm represents acl_perm_t. type Perm C.acl_perm_t @@ -83,11 +88,21 @@ func (e Error) Error() string { // Update replaces ACL_USER entry with qualifier uid. func Update(name string, uid int, perms Perm) error { + f, _err := os.OpenFile(name, container.O_PATH, 0) + if _err != nil { + return _err + } + r, err := C.hakurei_update_acl( - C.CString(name), + C.int(f.Fd()), C.uid_t(uid), C.acl_perm_t(perms), ) + + if _err = f.Close(); _err != nil { + return _err + } + if r == C.HAKUREI_ACL_OK { return nil } diff --git a/internal/acl/libacl-helper.c b/internal/acl/libacl-helper.c index 065c1928..5fa35c18 100644 --- a/internal/acl/libacl-helper.c +++ b/internal/acl/libacl-helper.c @@ -1,11 +1,14 @@ +#define _GNU_SOURCE /* Definition of AT_* constants */ + #include "libacl-helper.h" #include #include #include +#include #include enum hakurei_acl_status hakurei_update_acl( - const char *path_p, + int fd, uid_t uid, acl_perm_t perms) { enum hakurei_acl_status ret; @@ -20,7 +23,7 @@ enum hakurei_acl_status hakurei_update_acl( acl_perm_t has_perms; ret = HAKUREI_ACL_GET_FILE; - acl = acl_get_file(path_p, ACL_TYPE_ACCESS); + acl = acl_get_file_at(fd, "", AT_EMPTY_PATH, ACL_TYPE_ACCESS); if (acl == NULL) goto out; @@ -120,11 +123,10 @@ set: goto out; ret = HAKUREI_ACL_SET_FILE; - if (acl_set_file(path_p, ACL_TYPE_ACCESS, acl) == 0) + if (acl_set_file_at(fd, "", AT_EMPTY_PATH, ACL_TYPE_ACCESS, acl) == 0) ret = HAKUREI_ACL_OK; out: - free((void *)path_p); if (acl != NULL) acl_free((void *)acl); if (acl_d != NULL) diff --git a/internal/acl/libacl-helper.h b/internal/acl/libacl-helper.h index 753e1109..10711dd3 100644 --- a/internal/acl/libacl-helper.h +++ b/internal/acl/libacl-helper.h @@ -19,6 +19,6 @@ enum hakurei_acl_status { }; enum hakurei_acl_status hakurei_update_acl( - const char *path_p, + int fd, uid_t uid, acl_perm_t perms); -- cgit v1.3.1