From 9eb6d9d0ac17dca210ccbf05476a925a6b379dfb Mon Sep 17 00:00:00 2001 From: Daniel Markstedt Date: Thu, 5 Oct 2023 19:41:44 +0900 Subject: [PATCH] CVE-2022-22995: Harden create_appledesktop_folder() (#509) * Check that source path is a dir before moving .AppleDesktop * Use C APIs for renaming files rather than a system call to mv * Call become_root() before the first lstat() call Signed-off-by: Daniel Markstedt --- etc/afpd/desktop.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/etc/afpd/desktop.c b/etc/afpd/desktop.c index 7f43ffbbc84..8615bb95ff8 100644 --- a/etc/afpd/desktop.c +++ b/etc/afpd/desktop.c @@ -12,8 +12,10 @@ #endif /* HAVE_CONFIG_H */ #include +#include #include #include +#include #include @@ -212,7 +214,6 @@ static void create_appledesktop_folder(const struct vol * vol) { bstring olddtpath = NULL, dtpath = NULL; struct stat st; - char *cmd_argv[4]; olddtpath = bfromcstr(vol->v_path); bcatcstr(olddtpath, "/" APPLEDESKTOP); @@ -220,27 +221,24 @@ static void create_appledesktop_folder(const struct vol * vol) dtpath = bfromcstr(vol->v_dbpath); bcatcstr(dtpath, "/" APPLEDESKTOP); - if (lstat(cfrombstr(dtpath), &st) != 0) { - - become_root(); + become_root(); - if (lstat(cfrombstr(olddtpath), &st) == 0) { - cmd_argv[0] = "mv"; - cmd_argv[1] = bdata(olddtpath); - cmd_argv[2] = bdata(dtpath); - cmd_argv[3] = NULL; - if (run_cmd("mv", cmd_argv) != 0) { - LOG(log_error, logtype_afpd, "moving .AppleDesktop from \"%s\" to \"%s\" failed", + if (lstat(cfrombstr(dtpath), &st) != 0) { + if ((lstat(cfrombstr(olddtpath), &st) == 0) && (S_ISDIR(st.st_mode) != 0)) { + if (rename(bdata(olddtpath), bdata(dtpath)) != 0) { + LOG(log_error, logtype_afpd, "moving .AppleDesktop from \"%s\" failed; creating new dir \"%s\"", bdata(olddtpath), bdata(dtpath)); mkdir(cfrombstr(dtpath), 0777); } } else { + LOG(log_debug, logtype_afpd, "no valid .AppleDesktop dir found; creating new dir \"%s\"", + bdata(dtpath)); mkdir(cfrombstr(dtpath), 0777); } - - unbecome_root(); } + unbecome_root(); + bdestroy(dtpath); bdestroy(olddtpath); }