Commit 905f90fe authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] disallow utime{s}() on immutable or append-only files

From: Ethan Benson <erbenson@alaska.net>

Currently Linux allows the use of the utime() and utimes() syscalls on
immutable or append-only files, this is incorrect.

utime{s}() is not supposed to work if you lack write access to a file,
in the case of an immutable file NOBODY has write access.

for an append-only file it only makes sense to be able to update its
time to present, not the past.

I have checked BSD, and they implement the behavior I propose, for
immutable files utime() and utimes() fail.  for append-only files they
fail if the time argument is not NULL.
parent 535231e8
......@@ -354,6 +354,10 @@ asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times)
/* Don't worry, the checks are done in inode_change_ok() */
newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
if (times) {
error = -EPERM;
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
goto dput_and_out;
error = get_user(newattrs.ia_atime.tv_sec, &times->actime);
newattrs.ia_atime.tv_nsec = 0;
if (!error)
......@@ -364,6 +368,10 @@ asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times)
newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
} else {
error = -EACCES;
if (IS_IMMUTABLE(inode))
goto dput_and_out;
if (current->fsuid != inode->i_uid &&
(error = permission(inode,MAY_WRITE,&nd)) != 0)
goto dput_and_out;
......@@ -403,12 +411,20 @@ long do_utimes(char __user * filename, struct timeval * times)
/* Don't worry, the checks are done in inode_change_ok() */
newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
if (times) {
error = -EPERM;
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
goto dput_and_out;
newattrs.ia_atime.tv_sec = times[0].tv_sec;
newattrs.ia_atime.tv_nsec = times[0].tv_usec * 1000;
newattrs.ia_mtime.tv_sec = times[1].tv_sec;
newattrs.ia_mtime.tv_nsec = times[1].tv_usec * 1000;
newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
} else {
error = -EACCES;
if (IS_IMMUTABLE(inode))
goto dput_and_out;
if (current->fsuid != inode->i_uid &&
(error = permission(inode,MAY_WRITE,&nd)) != 0)
goto dput_and_out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment