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