Darren J Moffat
2005-Nov-24 14:05 UTC
[zfs-discuss] ZFS ACL: append_data didn''t do what I expected
I think I''m missing something with respect to how some parts of the NFSv4/ZFS ACLs work. I want to have some files that are append only to a given user, lets call them log files or audit trail files :-) I have file "a" with content "line1", it is owned, readable and writable by daemon and nobody else using standard POSIX file perms. I then added an ACL to allow me to append do it: # chmod A0=user:darrenm:append_data:allow a $ ls -lv a -rw-r--r--+ 1 daemon daemon 6 Nov 24 06:01 a 0:user:darrenm:append_data:allow 1:owner@:execute:deny 2:owner@:read_data/write_data/append_data/write_xattr/write_attributes /write_acl/write_owner:allow 3:group@:write_data/append_data/execute:deny 4:group@:read_data:allow 5:everyone@:write_data/append_data/write_xattr/execute/write_attributes /write_acl/write_owner:deny 6:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize :allow The ACL config for the fs is the default: $ zfs get aclmode,aclinherit cube/projects NAME PROPERTY VALUE SOURCE cube/projects aclmode groupmask local cube/projects aclinherit secure default Looks like I should be able to append but not read file a, nor should I be able to overwrite existing data - exactly what you want for log/audit trails. I have the following simple program: #include <unistd.h> #include <stdio.h> #include <strings.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> int main(int argc, char **argv) { int fd; ssize_t nbyte = 0; char buf[8192]; size_t buflen; buflen = strlcpy(buf, argv[2], sizeof (buf)); fd = open(argv[1], O_WRONLY | O_APPEND); /* <=== APPEND */ if (fd == -1) { fprintf(stderr, "open \"%s\" failed: %s\n", argv[1], strerror(errno)); return (1); } nbyte = write(fd, buf, buflen); if (nbyte != buflen) { fprintf(stderr, "write fail: %d %s\n", nbyte, strerror(errno)); return (1); } (void) close(fd); } This doesn''t work and I thought it should do. The open fails with EPERM [file_dac_read], which seems very strange if anything I''d be expecting a file_dac_write. open("a", O_WRONLY|O_APPEND) Err#13 EACCES [file_dac_read] If I change the ACL to have write_data in it the program works, BUT I can now also replace all of the contents of the file with a simple: `echo foo > a` which is not what I wanted. If I change the ACL so that the traditional UNIX perms for group and other read are present my program still fails the same way. # dtrace -n ''syscall::open:,fbt::zfs_zaccess*:,fbt::secpolicy_vnode_access: /execname == "append"/ { ; }'' dtrace: description ''syscall::open:,fbt::zfs_zaccess*:,fbt::secpolicy_vnode_access: '' matched 16 probes CPU ID FUNCTION:NAME 7 16 open:entry 7 17 open:return 7 16 open:entry 7 17 open:return 7 16 open:entry 7 37678 zfs_zaccess:entry 7 37276 zfs_zaccess_common:entry 7 37277 zfs_zaccess_common:return 7 37679 zfs_zaccess:return 7 37678 zfs_zaccess:entry 7 37276 zfs_zaccess_common:entry 7 37277 zfs_zaccess_common:return 7 37679 zfs_zaccess:return 7 38040 zfs_zaccess_rwx:entry 7 38041 zfs_zaccess_rwx:return 7 37678 zfs_zaccess:entry 7 37276 zfs_zaccess_common:entry 7 37277 zfs_zaccess_common:return 7 10866 secpolicy_vnode_access:entry 7 10867 secpolicy_vnode_access:return 7 37679 zfs_zaccess:return 7 17 open:return 7 16 open:entry 7 17 open:return This shows that the zfs_zaccess_* is failing to find an allowed match and thus we go on to see if we can do this with privilege - which this process can''t. So just for fun I did this to the shell where I start the process from: `ppriv -s I=file_dac_read,basic 419571` So that it will give file_dac_read to the append program. Now it says: open("a", O_WRONLY|O_APPEND) Err#13 EACCES [file_dac_write] So what am I missing ? The ACL seems to be valid since it got set. -- Darren J Moffat
Mark Shellenbaum
2005-Nov-27 20:40 UTC
[zfs-discuss] ZFS ACL: append_data didn''t do what I expected
Darren J Moffat wrote:> I think I''m missing something with respect to how some parts of > the NFSv4/ZFS ACLs work. > > I want to have some files that are append only to a given user, lets > call them log files or audit trail files :-)Append only files are not yet implemented. We have a problem with the NFS server, where there is no notion of O_APPEND. An open operation over NFS does not convey whether the client wishes to append or do a general write; only at the time of a write operation can the server see whether the client is appending. Therefore, a process could receive an error, e.g. ERANGE, EOVERFLOW, or ENOSPC, upon issuing an attempted write() somewhere other than at EOF. This adds unwanted overhead in the write path.> > I have file "a" with content "line1", it is owned, readable and > writable by daemon and nobody else using standard POSIX file perms. > > I then added an ACL to allow me to append do it: > > # chmod A0=user:darrenm:append_data:allow a > > $ ls -lv a > -rw-r--r--+ 1 daemon daemon 6 Nov 24 06:01 a > 0:user:darrenm:append_data:allow > 1:owner@:execute:deny > > 2:owner@:read_data/write_data/append_data/write_xattr/write_attributes > /write_acl/write_owner:allow > 3:group@:write_data/append_data/execute:deny > 4:group@:read_data:allow > > 5:everyone@:write_data/append_data/write_xattr/execute/write_attributes > /write_acl/write_owner:deny > > 6:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize > :allow > > The ACL config for the fs is the default: > > $ zfs get aclmode,aclinherit cube/projects > NAME PROPERTY VALUE SOURCE > cube/projects aclmode groupmask local > cube/projects aclinherit secure default > > > Looks like I should be able to append but not read file a, nor > should I be able to overwrite existing data - exactly what you > want for log/audit trails. > > I have the following simple program: > > #include <unistd.h> > #include <stdio.h> > #include <strings.h> > #include <sys/types.h> > #include <sys/stat.h> > #include <fcntl.h> > #include <errno.h> > > int > main(int argc, char **argv) > { > int fd; > ssize_t nbyte = 0; > char buf[8192]; > size_t buflen; > > buflen = strlcpy(buf, argv[2], sizeof (buf)); > > fd = open(argv[1], O_WRONLY | O_APPEND); /* <=== APPEND */ > if (fd == -1) { > fprintf(stderr, "open \"%s\" failed: %s\n", argv[1], > strerror(errno)); > return (1); > } > > nbyte = write(fd, buf, buflen); > if (nbyte != buflen) { > fprintf(stderr, "write fail: %d %s\n", nbyte, > strerror(errno)); > return (1); > } > > (void) close(fd); > } > > > This doesn''t work and I thought it should do. The open fails > with EPERM [file_dac_read], which seems very strange if anything > I''d be expecting a file_dac_write. > > open("a", O_WRONLY|O_APPEND) Err#13 EACCES [file_dac_read] > > If I change the ACL to have write_data in it the program works, BUT > I can now also replace all of the contents of the file with a simple: > `echo foo > a` which is not what I wanted. > > If I change the ACL so that the traditional UNIX perms for group > and other read are present my program still fails the same way. > > # dtrace -n > ''syscall::open:,fbt::zfs_zaccess*:,fbt::secpolicy_vnode_access: > /execname == "append"/ { ; }'' > dtrace: description > ''syscall::open:,fbt::zfs_zaccess*:,fbt::secpolicy_vnode_access: '' > matched 16 probes > CPU ID FUNCTION:NAME > 7 16 open:entry > 7 17 open:return > 7 16 open:entry > 7 17 open:return > 7 16 open:entry > 7 37678 zfs_zaccess:entry > 7 37276 zfs_zaccess_common:entry > 7 37277 zfs_zaccess_common:return > 7 37679 zfs_zaccess:return > 7 37678 zfs_zaccess:entry > 7 37276 zfs_zaccess_common:entry > 7 37277 zfs_zaccess_common:return > 7 37679 zfs_zaccess:return > 7 38040 zfs_zaccess_rwx:entry > 7 38041 zfs_zaccess_rwx:return > 7 37678 zfs_zaccess:entry > 7 37276 zfs_zaccess_common:entry > 7 37277 zfs_zaccess_common:return > 7 10866 secpolicy_vnode_access:entry > 7 10867 secpolicy_vnode_access:return > 7 37679 zfs_zaccess:return > 7 17 open:return > 7 16 open:entry > 7 17 open:return > > This shows that the zfs_zaccess_* is failing to find > an allowed match and thus we go on to see if we can do this > with privilege - which this process can''t. > > So just for fun I did this to the shell where I start the process > from: `ppriv -s I=file_dac_read,basic 419571` > > So that it will give file_dac_read to the append program. Now > it says: > > open("a", O_WRONLY|O_APPEND) Err#13 EACCES [file_dac_write] > > So what am I missing ? The ACL seems to be valid since it got set. >
Martin Englund
2005-Nov-27 21:47 UTC
[zfs-discuss] ZFS ACL: append_data didn''t do what I expected
Hi Mark! Mark Shellenbaum wrote:> Append only files are not yet implemented. We have a problem with the > NFS server, where there is no notion of O_APPEND. An open operation > over NFS does not convey whether the client wishes to append or do a > general write; only at the time of a write operation can the server see > whether the client is appending. Therefore, a process could receive an > error, e.g. ERANGE, EOVERFLOW, or ENOSPC, upon issuing an attempted > write() somewhere other than at EOF. This adds unwanted overhead in the > write path. >What is the bug# for this? cheers, /Martin -- Martin Englund, Senior Security Engineer, Sun IT Security Office Email: martin.englund at sun.com Time Zone: GMT+2 PGP: 1024D/4F4ABC26 "The question is not if you are paranoid, it is if you are paranoid enough."
Mark Shellenbaum
2005-Nov-27 21:52 UTC
[zfs-discuss] ZFS ACL: append_data didn''t do what I expected
Martin Englund wrote:> Hi Mark! > > Mark Shellenbaum wrote: > >> Append only files are not yet implemented. We have a problem with the >> NFS server, where there is no notion of O_APPEND. An open operation >> over NFS does not convey whether the client wishes to append or do a >> general write; only at the time of a write operation can the server >> see whether the client is appending. Therefore, a process could >> receive an error, e.g. ERANGE, EOVERFLOW, or ENOSPC, upon issuing an >> attempted write() somewhere other than at EOF. This adds unwanted >> overhead in the write path. >> > What is the bug# for this?The RFE for append only files is 4890717. We don''t have a bug as far as I know about the issues with NFS. If it wasn''t for NFS this would already be implemented. -Mark> > cheers, > /Martin
Ivan Buetler
2006-Jun-16 14:38 UTC
[zfs-discuss] Re: ZFS ACL: append_data didn''t do what I expected
Hi there, Any news here? I am hunting for a solution of a "immutable" apache log. Thought the append_data will solve the requirement. Unfortunately - i came to your page and it looks it will not work with append_data. Or am I wrong? Regards ibuetler This message posted from opensolaris.org
ethan gunword
2006-Aug-17 14:04 UTC
[zfs-discuss] Re: ZFS ACL: append_data didn''t do what I expected
Dear Mark, You say: Append_data does not work and it is not a bug issue. it is not implemented. OK?! What i am asking is " If you did not implemented append_data function, why do you specify or define it as file permission". If you planning some feature for future release please do not add it as a working function to the software. it is simple solution. Otherwise we do waste our time for not working function. Thanks, This message posted from opensolaris.org