All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2 RESEND] POSIX-compliant version of fchmodat with flag argument
@ 2012-01-13  1:53 Andrew Ayer
  2012-01-13  1:53 ` [PATCH 1/2] vfs: Add fchmodat4 syscall: " Andrew Ayer
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Andrew Ayer @ 2012-01-13  1:53 UTC (permalink / raw)
  To: Alexander Viro; +Cc: linux-fsdevel, linux-kernel

Hi,

The below patches implement a 4 argument version of fchmodat (fchmodat4)
that has a flag argument, as specified by POSIX.  This is needed to
implement a proper glibc wrapper.

fchmodat4 supports the same two flags as fchownat: AT_SYMLINK_NOFOLLOW
and AT_EMPTY_PATH.

Besides the POSIX-compliance, this patch will make it possible to
ensure, in a race-free way, that you do not follow symlinks when
chmodding. Previously, you could open a file with O_NOFOLLOW and fchmod
it, but this only worked if you had read or write permissions on the
file.  Now you can open the file with O_PATH|O_NOFOLLOW and do fchmodat
with AT_EMPTY_PATH.

Could this patch be applied?  Any feedback is welcome.

Cheers, 
Andrew

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/2] vfs: Add fchmodat4 syscall: fchmodat with flag argument
  2012-01-13  1:53 [PATCH 0/2 RESEND] POSIX-compliant version of fchmodat with flag argument Andrew Ayer
@ 2012-01-13  1:53 ` Andrew Ayer
  2014-01-21  7:30   ` Florian Weimer
  2012-01-13  1:53 ` [PATCH 2/2] x86: Hook up new fchmodat4 syscall Andrew Ayer
  2012-09-18 20:39 ` [PATCH 0/2 RESEND] POSIX-compliant version of fchmodat with flag argument Kenny Root
  2 siblings, 1 reply; 7+ messages in thread
From: Andrew Ayer @ 2012-01-13  1:53 UTC (permalink / raw)
  To: Alexander Viro; +Cc: linux-fsdevel, linux-kernel

This adds a 4 argument version of fchmodat (fchmodat4) that
supports a flag argument, as specified by POSIX.  It supports
the same two flags as fchownat: AT_SYMLINK_NOFOLLOW and AT_EMPTY_PATH.

Signed-off-by: Andrew Ayer <agwa@andrewayer.name>
---
 fs/open.c                |   21 +++++++++++++++++++--
 include/linux/syscalls.h |    2 ++
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/fs/open.c b/fs/open.c
index 77becc0..4f087e7 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -452,6 +452,9 @@ static int chmod_common(struct path *path, umode_t mode)
 	struct iattr newattrs;
 	int error;
 
+	if (S_ISLNK(inode->i_mode))
+		return -EOPNOTSUPP;
+
 	error = mnt_want_write(path->mnt);
 	if (error)
 		return error;
@@ -484,10 +487,24 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, umode_t, mode)
 
 SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode)
 {
+	return sys_fchmodat4(dfd, filename, mode, 0);
+}
+
+SYSCALL_DEFINE4(fchmodat4, int, dfd, const char __user *, filename,
+		umode_t, mode, int, flag)
+{
 	struct path path;
 	int error;
+	int lookup_flags;
+
+	if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
+		return -EINVAL;
 
-	error = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path);
+	lookup_flags = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
+	if (flag & AT_EMPTY_PATH)
+		lookup_flags |= LOOKUP_EMPTY;
+
+	error = user_path_at(dfd, filename, lookup_flags, &path);
 	if (!error) {
 		error = chmod_common(&path, mode);
 		path_put(&path);
@@ -497,7 +514,7 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode
 
 SYSCALL_DEFINE2(chmod, const char __user *, filename, umode_t, mode)
 {
-	return sys_fchmodat(AT_FDCWD, filename, mode);
+	return sys_fchmodat4(AT_FDCWD, filename, mode, 0);
 }
 
 static int chown_common(struct path *path, uid_t user, gid_t group)
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 515669f..4834904 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -770,6 +770,8 @@ asmlinkage long sys_futimesat(int dfd, const char __user *filename,
 asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode);
 asmlinkage long sys_fchmodat(int dfd, const char __user * filename,
 			     umode_t mode);
+asmlinkage long sys_fchmodat4(int dfd, const char __user * filename,
+			     umode_t mode, int flag);
 asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user,
 			     gid_t group, int flag);
 asmlinkage long sys_openat(int dfd, const char __user *filename, int flags,
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/2] x86: Hook up new fchmodat4 syscall
  2012-01-13  1:53 [PATCH 0/2 RESEND] POSIX-compliant version of fchmodat with flag argument Andrew Ayer
  2012-01-13  1:53 ` [PATCH 1/2] vfs: Add fchmodat4 syscall: " Andrew Ayer
@ 2012-01-13  1:53 ` Andrew Ayer
  2012-09-18 20:39 ` [PATCH 0/2 RESEND] POSIX-compliant version of fchmodat with flag argument Kenny Root
  2 siblings, 0 replies; 7+ messages in thread
From: Andrew Ayer @ 2012-01-13  1:53 UTC (permalink / raw)
  To: Alexander Viro; +Cc: linux-fsdevel, linux-kernel

Signed-off-by: Andrew Ayer <agwa@andrewayer.name>
---
 arch/x86/ia32/ia32entry.S          |    1 +
 arch/x86/include/asm/unistd_32.h   |    3 ++-
 arch/x86/include/asm/unistd_64.h   |    2 ++
 arch/x86/kernel/syscall_table_32.S |    1 +
 4 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index 3e27456..f026e9f 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -847,4 +847,5 @@ ia32_sys_call_table:
 	.quad sys_setns
 	.quad compat_sys_process_vm_readv
 	.quad compat_sys_process_vm_writev
+	.quad sys_fchmodat4
 ia32_syscall_end:
diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h
index 599c77d..112b299 100644
--- a/arch/x86/include/asm/unistd_32.h
+++ b/arch/x86/include/asm/unistd_32.h
@@ -354,10 +354,11 @@
 #define __NR_setns		346
 #define __NR_process_vm_readv	347
 #define __NR_process_vm_writev	348
+#define __NR_fchmodat4		349
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 349
+#define NR_syscalls 350
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h
index 0431f19..21564f9 100644
--- a/arch/x86/include/asm/unistd_64.h
+++ b/arch/x86/include/asm/unistd_64.h
@@ -686,6 +686,8 @@ __SYSCALL(__NR_getcpu, sys_getcpu)
 __SYSCALL(__NR_process_vm_readv, sys_process_vm_readv)
 #define __NR_process_vm_writev			311
 __SYSCALL(__NR_process_vm_writev, sys_process_vm_writev)
+#define __NR_fchmodat4				312
+__SYSCALL(__NR_fchmodat4, sys_fchmodat4)
 
 #ifndef __NO_STUBS
 #define __ARCH_WANT_OLD_READDIR
diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S
index 9a0e312..bff82a6 100644
--- a/arch/x86/kernel/syscall_table_32.S
+++ b/arch/x86/kernel/syscall_table_32.S
@@ -348,3 +348,4 @@ ENTRY(sys_call_table)
 	.long sys_setns
 	.long sys_process_vm_readv
 	.long sys_process_vm_writev
+	.long sys_fchmodat4
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/2 RESEND] POSIX-compliant version of fchmodat with flag argument
  2012-01-13  1:53 [PATCH 0/2 RESEND] POSIX-compliant version of fchmodat with flag argument Andrew Ayer
  2012-01-13  1:53 ` [PATCH 1/2] vfs: Add fchmodat4 syscall: " Andrew Ayer
  2012-01-13  1:53 ` [PATCH 2/2] x86: Hook up new fchmodat4 syscall Andrew Ayer
@ 2012-09-18 20:39 ` Kenny Root
  2 siblings, 0 replies; 7+ messages in thread
From: Kenny Root @ 2012-09-18 20:39 UTC (permalink / raw)
  To: Alexander Viro; +Cc: linux-fsdevel, linux-kernel, Andrew Ayer

On Thu, Jan 12, 2012 at 05:53:44PM -0800, Andrew Ayer wrote:
> Besides the POSIX-compliance, this patch will make it possible to
> ensure, in a race-free way, that you do not follow symlinks when
> chmodding. Previously, you could open a file with O_NOFOLLOW and fchmod
> it, but this only worked if you had read or write permissions on the
> file.  Now you can open the file with O_PATH|O_NOFOLLOW and do fchmodat
> with AT_EMPTY_PATH.

Alexander, this patch solves a particular problem in a useful way. I
find it useful and I would be happy to see it included in mainline.

Thanks,
Kenny

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] vfs: Add fchmodat4 syscall: fchmodat with flag argument
  2012-01-13  1:53 ` [PATCH 1/2] vfs: Add fchmodat4 syscall: " Andrew Ayer
@ 2014-01-21  7:30   ` Florian Weimer
  2014-01-21 18:57     ` Andrew Ayer
  0 siblings, 1 reply; 7+ messages in thread
From: Florian Weimer @ 2014-01-21  7:30 UTC (permalink / raw)
  To: Andrew Ayer, Alexander Viro; +Cc: linux-fsdevel, linux-kernel

On 01/13/2012 02:53 AM, Andrew Ayer wrote:
> This adds a 4 argument version of fchmodat (fchmodat4) that
> supports a flag argument, as specified by POSIX.  It supports
> the same two flags as fchownat: AT_SYMLINK_NOFOLLOW and AT_EMPTY_PATH.

I don't think it's possible to emulate AT_EMPTY_PATH in user space, so I 
wonder if this could be applied, and if not, why.  Thanks.

-- 
Florian Weimer / Red Hat Product Security Team

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] vfs: Add fchmodat4 syscall: fchmodat with flag argument
  2014-01-21  7:30   ` Florian Weimer
@ 2014-01-21 18:57     ` Andrew Ayer
  2014-01-21 18:58       ` [PATCH] vfs: Add version of " Andrew Ayer
  0 siblings, 1 reply; 7+ messages in thread
From: Andrew Ayer @ 2014-01-21 18:57 UTC (permalink / raw)
  To: Florian Weimer, Alexander Viro; +Cc: linux-fsdevel, linux-kernel

On Tue, 21 Jan 2014 08:30:16 +0100
Florian Weimer <fweimer@redhat.com> wrote:

> On 01/13/2012 02:53 AM, Andrew Ayer wrote:
> > This adds a 4 argument version of fchmodat (fchmodat4) that
> > supports a flag argument, as specified by POSIX.  It supports
> > the same two flags as fchownat: AT_SYMLINK_NOFOLLOW and AT_EMPTY_PATH.
> 
> I don't think it's possible to emulate AT_EMPTY_PATH in user space, so I 
> wonder if this could be applied, and if not, why.  Thanks.

The original patch no longer applies because there were some
minor changes to fs/open.c.  I'll fix up the patch and send it in.

I too would very much like to see this applied, or to know why it can't
be.

Thanks,
Andrew

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH] vfs: Add version of fchmodat with flag argument
  2014-01-21 18:57     ` Andrew Ayer
@ 2014-01-21 18:58       ` Andrew Ayer
  0 siblings, 0 replies; 7+ messages in thread
From: Andrew Ayer @ 2014-01-21 18:58 UTC (permalink / raw)
  To: viro; +Cc: linux-fsdevel, linux-kernel, fweimer

This adds a 4 argument version of fchmodat (fchmodat4) that
supports a flag argument, as specified by POSIX.  It supports
the same two flags as fchownat: AT_SYMLINK_NOFOLLOW and AT_EMPTY_PATH.

Signed-off-by: Andrew Ayer <agwa@andrewayer.name>
---
 fs/open.c                |   23 ++++++++++++++++++++---
 include/linux/syscalls.h |    2 ++
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/fs/open.c b/fs/open.c
index 4b3e1ed..6f661f9 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -469,6 +469,9 @@ static int chmod_common(struct path *path, umode_t mode)
 	struct iattr newattrs;
 	int error;
 
+	if (S_ISLNK(inode->i_mode))
+		return -EOPNOTSUPP;
+
 	error = mnt_want_write(path->mnt);
 	if (error)
 		return error;
@@ -506,9 +509,22 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, umode_t, mode)
 
 SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode)
 {
+	return sys_fchmodat4(dfd, filename, mode, 0);
+}
+
+SYSCALL_DEFINE4(fchmodat4, int, dfd, const char __user *, filename,
+		umode_t, mode, int, flag)
+{
 	struct path path;
-	int error;
-	unsigned int lookup_flags = LOOKUP_FOLLOW;
+	int error = -EINVAL;
+	unsigned int lookup_flags;
+
+	if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
+		goto out;
+
+	lookup_flags = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
+	if (flag & AT_EMPTY_PATH)
+		lookup_flags |= LOOKUP_EMPTY;
 retry:
 	error = user_path_at(dfd, filename, lookup_flags, &path);
 	if (!error) {
@@ -519,12 +535,13 @@ retry:
 			goto retry;
 		}
 	}
+out:
 	return error;
 }
 
 SYSCALL_DEFINE2(chmod, const char __user *, filename, umode_t, mode)
 {
-	return sys_fchmodat(AT_FDCWD, filename, mode);
+	return sys_fchmodat4(AT_FDCWD, filename, mode, 0);
 }
 
 static int chown_common(struct path *path, uid_t user, gid_t group)
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 40ed9e9..32811df 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -747,6 +747,8 @@ asmlinkage long sys_futimesat(int dfd, const char __user *filename,
 asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode);
 asmlinkage long sys_fchmodat(int dfd, const char __user * filename,
 			     umode_t mode);
+asmlinkage long sys_fchmodat4(int dfd, const char __user *filename,
+			     umode_t mode, int flag);
 asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user,
 			     gid_t group, int flag);
 asmlinkage long sys_openat(int dfd, const char __user *filename, int flags,
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-01-21 19:06 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-13  1:53 [PATCH 0/2 RESEND] POSIX-compliant version of fchmodat with flag argument Andrew Ayer
2012-01-13  1:53 ` [PATCH 1/2] vfs: Add fchmodat4 syscall: " Andrew Ayer
2014-01-21  7:30   ` Florian Weimer
2014-01-21 18:57     ` Andrew Ayer
2014-01-21 18:58       ` [PATCH] vfs: Add version of " Andrew Ayer
2012-01-13  1:53 ` [PATCH 2/2] x86: Hook up new fchmodat4 syscall Andrew Ayer
2012-09-18 20:39 ` [PATCH 0/2 RESEND] POSIX-compliant version of fchmodat with flag argument Kenny Root

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.