1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001 4f08c3bdfSopenharmony_ci * 07/2001 ported by John George 5f08c3bdfSopenharmony_ci * Copyright (C) 2021 SUSE LLC <mdoucha@suse.cz> 6f08c3bdfSopenharmony_ci */ 7f08c3bdfSopenharmony_ci 8f08c3bdfSopenharmony_ci/*\ 9f08c3bdfSopenharmony_ci * [Description] 10f08c3bdfSopenharmony_ci * 11f08c3bdfSopenharmony_ci * Verify that the system call utime() successfully sets the modification 12f08c3bdfSopenharmony_ci * and access times of a file to the current time, under the following 13f08c3bdfSopenharmony_ci * constraints: 14f08c3bdfSopenharmony_ci * 15f08c3bdfSopenharmony_ci * - The times argument is NULL. 16f08c3bdfSopenharmony_ci * - The user ID of the process is not "root". 17f08c3bdfSopenharmony_ci * - The file is not owned by the user ID of the process. 18f08c3bdfSopenharmony_ci * - The user ID of the process has write access to the file. 19f08c3bdfSopenharmony_ci */ 20f08c3bdfSopenharmony_ci 21f08c3bdfSopenharmony_ci#include <pwd.h> 22f08c3bdfSopenharmony_ci#include <utime.h> 23f08c3bdfSopenharmony_ci#include <time.h> 24f08c3bdfSopenharmony_ci 25f08c3bdfSopenharmony_ci#include "tst_test.h" 26f08c3bdfSopenharmony_ci#include "tst_uid.h" 27f08c3bdfSopenharmony_ci#include "tst_clocks.h" 28f08c3bdfSopenharmony_ci 29f08c3bdfSopenharmony_ci#define MNTPOINT "mntpoint" 30f08c3bdfSopenharmony_ci#define TEMP_FILE MNTPOINT"/tmp_file" 31f08c3bdfSopenharmony_ci#define FILE_MODE 0766 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_cistatic uid_t root_uid, user_uid; 34f08c3bdfSopenharmony_ci 35f08c3bdfSopenharmony_cistatic void setup(void) 36f08c3bdfSopenharmony_ci{ 37f08c3bdfSopenharmony_ci struct passwd *pw; 38f08c3bdfSopenharmony_ci uid_t test_users[2]; 39f08c3bdfSopenharmony_ci int fd; 40f08c3bdfSopenharmony_ci 41f08c3bdfSopenharmony_ci root_uid = getuid(); 42f08c3bdfSopenharmony_ci pw = SAFE_GETPWNAM("nobody"); 43f08c3bdfSopenharmony_ci test_users[0] = pw->pw_uid; 44f08c3bdfSopenharmony_ci tst_get_uids(test_users, 1, 2); 45f08c3bdfSopenharmony_ci user_uid = test_users[1]; 46f08c3bdfSopenharmony_ci 47f08c3bdfSopenharmony_ci fd = SAFE_CREAT(TEMP_FILE, FILE_MODE); 48f08c3bdfSopenharmony_ci SAFE_CLOSE(fd); 49f08c3bdfSopenharmony_ci 50f08c3bdfSopenharmony_ci /* Override umask */ 51f08c3bdfSopenharmony_ci SAFE_CHMOD(TEMP_FILE, FILE_MODE); 52f08c3bdfSopenharmony_ci SAFE_CHOWN(TEMP_FILE, pw->pw_uid, pw->pw_gid); 53f08c3bdfSopenharmony_ci} 54f08c3bdfSopenharmony_ci 55f08c3bdfSopenharmony_cistatic void run(void) 56f08c3bdfSopenharmony_ci{ 57f08c3bdfSopenharmony_ci struct utimbuf utbuf; 58f08c3bdfSopenharmony_ci struct stat statbuf; 59f08c3bdfSopenharmony_ci time_t mintime, maxtime; 60f08c3bdfSopenharmony_ci 61f08c3bdfSopenharmony_ci utbuf.modtime = time(0) - 5; 62f08c3bdfSopenharmony_ci utbuf.actime = utbuf.modtime + 1; 63f08c3bdfSopenharmony_ci TST_EXP_PASS_SILENT(utime(TEMP_FILE, &utbuf)); 64f08c3bdfSopenharmony_ci SAFE_STAT(TEMP_FILE, &statbuf); 65f08c3bdfSopenharmony_ci 66f08c3bdfSopenharmony_ci if (statbuf.st_atime != utbuf.actime || 67f08c3bdfSopenharmony_ci statbuf.st_mtime != utbuf.modtime) { 68f08c3bdfSopenharmony_ci tst_res(TFAIL, "Could not set initial file times"); 69f08c3bdfSopenharmony_ci return; 70f08c3bdfSopenharmony_ci } 71f08c3bdfSopenharmony_ci 72f08c3bdfSopenharmony_ci SAFE_SETEUID(user_uid); 73f08c3bdfSopenharmony_ci mintime = tst_get_fs_timestamp(); 74f08c3bdfSopenharmony_ci TST_EXP_PASS(utime(TEMP_FILE, NULL)); 75f08c3bdfSopenharmony_ci maxtime = tst_get_fs_timestamp(); 76f08c3bdfSopenharmony_ci SAFE_SETEUID(root_uid); 77f08c3bdfSopenharmony_ci SAFE_STAT(TEMP_FILE, &statbuf); 78f08c3bdfSopenharmony_ci 79f08c3bdfSopenharmony_ci if (statbuf.st_atime < mintime || statbuf.st_atime > maxtime) 80f08c3bdfSopenharmony_ci tst_res(TFAIL, "utime() did not set expected atime, " 81f08c3bdfSopenharmony_ci "mintime: %ld, maxtime: %ld, st_atime: %ld", 82f08c3bdfSopenharmony_ci mintime, maxtime, statbuf.st_atime); 83f08c3bdfSopenharmony_ci 84f08c3bdfSopenharmony_ci if (statbuf.st_mtime < mintime || statbuf.st_mtime > maxtime) 85f08c3bdfSopenharmony_ci tst_res(TFAIL, "utime() did not set expected mtime, " 86f08c3bdfSopenharmony_ci "mintime: %ld, maxtime: %ld, st_mtime: %ld", 87f08c3bdfSopenharmony_ci mintime, maxtime, statbuf.st_mtime); 88f08c3bdfSopenharmony_ci} 89f08c3bdfSopenharmony_ci 90f08c3bdfSopenharmony_cistatic struct tst_test test = { 91f08c3bdfSopenharmony_ci .test_all = run, 92f08c3bdfSopenharmony_ci .setup = setup, 93f08c3bdfSopenharmony_ci .needs_root = 1, 94f08c3bdfSopenharmony_ci .mount_device = 1, 95f08c3bdfSopenharmony_ci .mntpoint = MNTPOINT, 96f08c3bdfSopenharmony_ci .all_filesystems = 1, 97f08c3bdfSopenharmony_ci .skip_filesystems = (const char *const[]) { 98f08c3bdfSopenharmony_ci "vfat", 99f08c3bdfSopenharmony_ci "exfat", 100f08c3bdfSopenharmony_ci NULL 101f08c3bdfSopenharmony_ci } 102f08c3bdfSopenharmony_ci}; 103