Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753496Ab3FKG4D (ORCPT ); Tue, 11 Jun 2013 02:56:03 -0400 Received: from mailout4.samsung.com ([203.254.224.34]:30066 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752685Ab3FKG4A (ORCPT ); Tue, 11 Jun 2013 02:56:00 -0400 X-AuditID: cbfee68f-b7f436d000000f81-79-51b6c9fe5491 Message-id: <1370933681.3600.77.camel@kjgkr> Subject: Re: [PATCH 2/2 v4] f2fs: support xattr security labels From: Jaegeuk Kim Reply-to: jaegeuk.kim@samsung.com To: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net Date: Tue, 11 Jun 2013 15:54:41 +0900 In-reply-to: <1370653763.3600.55.camel@kjgkr> References: <1370584557-20592-1-git-send-email-jaegeuk.kim@samsung.com> <1370584557-20592-2-git-send-email-jaegeuk.kim@samsung.com> <1370592580.3600.42.camel@kjgkr> <1370653763.3600.55.camel@kjgkr> Organization: samsung Content-type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="=-Wez1pmqxIGYhr8CMEslI" X-Mailer: Evolution 3.2.3-0ubuntu6 MIME-version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrNIsWRmVeSWpSXmKPExsVy+t8zA91/J7cFGmxYY2lxaZG7xZ69J1ks Lu+aw+bA7LF7wWcmj8+b5AKYorhsUlJzMstSi/TtErgyNrUtYy44l1Hx5Ms9lgbG7eFdjJwc EgImEr8fd7FB2GISF+6tB7K5OIQEljFKPN51l7WLkQOs6PV0cYj4IkaJs/0HmSCc14wSW351 MIN08wroSBw4fpsdxBYWsJfY/2IOWDObgLbE5v0GIGEhAUWJt/shZooA2ZffO4GYzAIeEruO lYJUsAioSkxq+M4IYnMK6EpM3/MeatNJRok5fx+AJfgFRCVOtn4Cs5kFqiSu3uhjgrhfSWJ3 eyc7xDWCEj8m32MBaZYQ+MguceDeFRaIDQIS3yYfYoH4S1Zi0wFmiF5JiYMrbrBMYBSfhWTs LCSjIOKaEq3bf7ND2NoSyxa+ZoawbSXWrXsPVWMjsenqAkYIW15i+9s5zAsY2VcxiqYWJBcU J6UXGesVJ+YWl+al6yXn525ihMRo/w7GuwesDzFWAZ04kVlKNDkfGON5JfGGxmZGFqYmpsZG 5pZmVBFWEudVa7EOFBJITyxJzU5NLUgtii8qzUktPsTIxMEp1cB45FaVs9Snu/su+Lz2KZPP O/+eV3r5vuy1dU+XPQiV3uk7XTRYZ52lygZVo+v3Y988uLY/v997QVbp8TW/9pTulVZRZXye 6dThJLQm+aKoHs9yoaeTuErmH/u+tOwIF2/mgo9K3w7qRi+vqOubZbMz78i61RzczrO5v69W 2bBcWf/h0pyIPavYlFiKMxINtZiLihMBEnhIaf4CAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrDKsWRmVeSWpSXmKPExsVy+t9jAd1/J7cFGlyda2xxaZG7xZ69J1ks Lu+aw+bA7LF7wWcmj8+b5AKYohoYbTJSE1NSixRS85LzUzLz0m2VvIPjneNNzQwMdQ0tLcyV FPISc1NtlVx8AnTdMnOAdigplCXmlAKFAhKLi5X07TBNCA1x07WAaYzQ9Q0JgusxMkADCesY Mza1LWMuOJdR8eTLPZYGxu3hXYwcHBICJhKvp4t3MXICmWISF+6tZ+ti5OIQEljEKHG2/yAT hPOaUWLLrw5mkCpeAR2JA8dvs4PYwgL2EvtfzGEFGcQmoC2xeb8BSFhIQFHi7f67YGERIPvy eycQk1nAQ2LXsVKQChYBVYlJDd8ZQWxOAV2J6XveQ206ySgx5+8DsAS/gKjEydZPYDazQJXE 1Rt9TBB3Kknsbu9kh7hGUOLH5HssExgFZyEpm4UkBRHXlGjd/psdwtaWWLbwNTOEbSuxbt17 qBobiU1XFzBC2PIS29/OYV7AyL6KUTS1ILmgOCk910ivODG3uDQvXS85P3cTIzgBPJPewbiq weIQowAHoxIPbwLjtkAh1sSy4srcQ4wqQHMebVh9gVGKJS8/L1VJhNd0O1CaNyWxsiq1KD++ qDQntfgQ40RGYHhMZJYSTc4Hpq28knhDYxMzI0sjMwsjE3NzWgorifMebLUOFBJITyxJzU5N LUgtgjmKiYNTqoFxBtfmz/suLHuosn6Ld+/zm2dt1ko+3BWj8l37qdS2iGWTi/l3bJ7WMuWF k2JRlWLktEsenlatWz9/s3Gdcj/uVcG0f0kqC/YfenrxslOi86RSde8nbX1Ffb8Wnvh9br/2 kV1v01dO2XT5sepC5VV7T1769e/K5PeiKg84r4fsTbhwZdkVxuv9HyKUWIozEg21mIuKEwHM KiYNfwMAAA== DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 13221 Lines: 421 --=-Wez1pmqxIGYhr8CMEslI Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Change log from v3: o fix deadlock condition for inode block page (tested on SElinux) Change log from v2: o fix description and simplify a code line (commented by Casey Schaufler) Change log from v1: o fix a bug =46rom 2065a7282f65eb1b395c675d4a1f9c8967e60385 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 3 Jun 2013 19:46:19 +0900 Subject: [PATCH] f2fs: support xattr security labels Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net This patch adds the support of security labels for f2fs, which will be used by Linus Security Models (LSMs). Quote from http://en.wikipedia.org/wiki/Linux_Security_Modules: "Linux Security Modules (LSM) is a framework that allows the Linux kernel to support a variety of computer security models while avoiding favoritism toward any single security implementation. The framework is licensed under the terms of the GNU General Public License and is standard part of the Linux kernel since Linux 2.6. AppArmor, SELinux, Smack and TOMOYO Linux are the currently accepted modules in the official kernel.". Signed-off-by: Jaegeuk Kim --- fs/f2fs/Kconfig | 12 +++++++++++ fs/f2fs/dir.c | 5 +++++ fs/f2fs/f2fs.h | 2 +- fs/f2fs/node.c | 12 +++++++---- fs/f2fs/xattr.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++------- fs/f2fs/xattr.h | 24 ++++++++++++++-------- 6 files changed, 99 insertions(+), 20 deletions(-) diff --git a/fs/f2fs/Kconfig b/fs/f2fs/Kconfig index fd27e7e..e06e099 100644 --- a/fs/f2fs/Kconfig +++ b/fs/f2fs/Kconfig @@ -51,3 +51,15 @@ config F2FS_FS_POSIX_ACL Linux website . =20 If you don't know what Access Control Lists are, say N + +config F2FS_FS_SECURITY + bool "F2FS Security Labels" + depends on F2FS_FS_XATTR + help + Security labels provide an access control facility to support Linux + Security Models (LSMs) accepted by AppArmor, SELinux, Smack and TOMOYO + Linux. This option enables an extended attribute handler for file + security labels in the f2fs filesystem, so that it requires enabling + the extended attribute support in advance. + + If you are not using a security module, say N. diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 67e2d13..eaea5b5 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -13,6 +13,7 @@ #include "f2fs.h" #include "node.h" #include "acl.h" +#include "xattr.h" =20 static unsigned long dir_blocks(struct inode *inode) { @@ -334,6 +335,10 @@ static struct page *init_inode_metadata(struct inode *inode, if (err) goto error; =20 + err =3D f2fs_init_security(inode, dir, name, page); + if (err) + goto error; + wait_on_page_writeback(page); } else { page =3D get_node_page(F2FS_SB(dir->i_sb), inode->i_ino); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index d6e63da..4f2c209 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -968,7 +968,7 @@ int get_dnode_of_data(struct dnode_of_data *, pgoff_t, int); int truncate_inode_blocks(struct inode *, pgoff_t); int remove_inode_page(struct inode *); struct page *new_inode_page(struct inode *, const struct qstr *); -struct page *new_node_page(struct dnode_of_data *, unsigned int); +struct page *new_node_page(struct dnode_of_data *, unsigned int, struct page *); void ra_node_page(struct f2fs_sb_info *, nid_t); struct page *get_node_page(struct f2fs_sb_info *, pgoff_t); struct page *get_node_page_ra(struct page *, int); diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 5a59780..b02440c 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -433,7 +433,7 @@ int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode) } =20 dn->nid =3D nids[i]; - npage[i] =3D new_node_page(dn, noffset[i]); + npage[i] =3D new_node_page(dn, noffset[i], NULL); if (IS_ERR(npage[i])) { alloc_nid_failed(sbi, nids[i]); err =3D PTR_ERR(npage[i]); @@ -814,10 +814,11 @@ struct page *new_inode_page(struct inode *inode, const struct qstr *name) set_new_dnode(&dn, inode, NULL, NULL, inode->i_ino); =20 /* caller should f2fs_put_page(page, 1); */ - return new_node_page(&dn, 0); + return new_node_page(&dn, 0, NULL); } =20 -struct page *new_node_page(struct dnode_of_data *dn, unsigned int ofs) +struct page *new_node_page(struct dnode_of_data *dn, + unsigned int ofs, struct page *ipage) { struct f2fs_sb_info *sbi =3D F2FS_SB(dn->inode->i_sb); struct address_space *mapping =3D sbi->node_inode->i_mapping; @@ -850,7 +851,10 @@ struct page *new_node_page(struct dnode_of_data *dn, unsigned int ofs) set_cold_node(dn->inode, page); =20 dn->node_page =3D page; - sync_inode_page(dn); + if (ipage) + update_inode(dn->inode, ipage); + else + sync_inode_page(dn); set_page_dirty(page); if (ofs =3D=3D 0) inc_valid_inode_count(sbi); diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index ae61f35..3ab07ec 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -20,6 +20,7 @@ */ #include #include +#include #include "f2fs.h" #include "xattr.h" =20 @@ -43,6 +44,10 @@ static size_t f2fs_xattr_generic_list(struct dentry *dentry, char *list, prefix =3D XATTR_TRUSTED_PREFIX; prefix_len =3D XATTR_TRUSTED_PREFIX_LEN; break; + case F2FS_XATTR_INDEX_SECURITY: + prefix =3D XATTR_SECURITY_PREFIX; + prefix_len =3D XATTR_SECURITY_PREFIX_LEN; + break; default: return -EINVAL; } @@ -50,7 +55,7 @@ static size_t f2fs_xattr_generic_list(struct dentry *dentry, char *list, total_len =3D prefix_len + name_len + 1; if (list && total_len <=3D list_size) { memcpy(list, prefix, prefix_len); - memcpy(list+prefix_len, name, name_len); + memcpy(list + prefix_len, name, name_len); list[prefix_len + name_len] =3D '\0'; } return total_len; @@ -70,13 +75,14 @@ static int f2fs_xattr_generic_get(struct dentry *dentry, const char *name, if (!capable(CAP_SYS_ADMIN)) return -EPERM; break; + case F2FS_XATTR_INDEX_SECURITY: + break; default: return -EINVAL; } if (strcmp(name, "") =3D=3D 0) return -EINVAL; - return f2fs_getxattr(dentry->d_inode, type, name, - buffer, size); + return f2fs_getxattr(dentry->d_inode, type, name, buffer, size); } =20 static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name, @@ -93,13 +99,15 @@ static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name, if (!capable(CAP_SYS_ADMIN)) return -EPERM; break; + case F2FS_XATTR_INDEX_SECURITY: + break; default: return -EINVAL; } if (strcmp(name, "") =3D=3D 0) return -EINVAL; =20 - return f2fs_setxattr(dentry->d_inode, type, name, value, size); + return f2fs_setxattr(dentry->d_inode, type, name, value, size, NULL); } =20 static size_t f2fs_xattr_advise_list(struct dentry *dentry, char *list, @@ -145,6 +153,31 @@ static int f2fs_xattr_advise_set(struct dentry *dentry, const char *name, return 0; } =20 +#ifdef CONFIG_F2FS_FS_SECURITY +static int f2fs_initxattrs(struct inode *inode, const struct xattr *xattr_array, + void *page) +{ + const struct xattr *xattr; + int err =3D 0; + + for (xattr =3D xattr_array; xattr->name !=3D NULL; xattr++) { + err =3D f2fs_setxattr(inode, F2FS_XATTR_INDEX_SECURITY, + xattr->name, xattr->value, + xattr->value_len, (struct page *)page); + if (err < 0) + break; + } + return err; +} + +int f2fs_init_security(struct inode *inode, struct inode *dir, + const struct qstr *qstr, struct page *ipage) +{ + return security_inode_init_security(inode, dir, qstr, + &f2fs_initxattrs, ipage); +} +#endif + const struct xattr_handler f2fs_xattr_user_handler =3D { .prefix =3D XATTR_USER_PREFIX, .flags =3D F2FS_XATTR_INDEX_USER, @@ -169,6 +202,14 @@ const struct xattr_handler f2fs_xattr_advise_handler =3D { .set =3D f2fs_xattr_advise_set, }; =20 +const struct xattr_handler f2fs_xattr_security_handler =3D { + .prefix =3D XATTR_SECURITY_PREFIX, + .flags =3D F2FS_XATTR_INDEX_SECURITY, + .list =3D f2fs_xattr_generic_list, + .get =3D f2fs_xattr_generic_get, + .set =3D f2fs_xattr_generic_set, +}; + static const struct xattr_handler *f2fs_xattr_handler_map[] =3D { [F2FS_XATTR_INDEX_USER] =3D &f2fs_xattr_user_handler, #ifdef CONFIG_F2FS_FS_POSIX_ACL @@ -176,6 +217,9 @@ static const struct xattr_handler *f2fs_xattr_handler_map[] =3D { [F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] =3D &f2fs_xattr_acl_default_handler, #endif [F2FS_XATTR_INDEX_TRUSTED] =3D &f2fs_xattr_trusted_handler, +#ifdef CONFIG_F2FS_FS_SECURITY + [F2FS_XATTR_INDEX_SECURITY] =3D &f2fs_xattr_security_handler, +#endif [F2FS_XATTR_INDEX_ADVISE] =3D &f2fs_xattr_advise_handler, }; =20 @@ -186,6 +230,9 @@ const struct xattr_handler *f2fs_xattr_handlers[] =3D { &f2fs_xattr_acl_default_handler, #endif &f2fs_xattr_trusted_handler, +#ifdef CONFIG_F2FS_FS_SECURITY + &f2fs_xattr_security_handler, +#endif &f2fs_xattr_advise_handler, NULL, }; @@ -300,7 +347,7 @@ cleanup: } =20 int f2fs_setxattr(struct inode *inode, int name_index, const char *name, - const void *value, size_t value_len) + const void *value, size_t value_len, struct page *ipage) { struct f2fs_sb_info *sbi =3D F2FS_SB(inode->i_sb); struct f2fs_inode_info *fi =3D F2FS_I(inode); @@ -339,7 +386,7 @@ int f2fs_setxattr(struct inode *inode, int name_index, const char *name, set_new_dnode(&dn, inode, NULL, NULL, fi->i_xattr_nid); mark_inode_dirty(inode); =20 - page =3D new_node_page(&dn, XATTR_NODE_OFFSET); + page =3D new_node_page(&dn, XATTR_NODE_OFFSET, ipage); if (IS_ERR(page)) { alloc_nid_failed(sbi, fi->i_xattr_nid); fi->i_xattr_nid =3D 0; @@ -439,7 +486,10 @@ int f2fs_setxattr(struct inode *inode, int name_index, const char *name, inode->i_ctime =3D CURRENT_TIME; clear_inode_flag(fi, FI_ACL_MODE); } - update_inode_page(inode); + if (ipage) + update_inode(inode, ipage); + else + update_inode_page(inode); mutex_unlock_op(sbi, ilock); =20 return 0; diff --git a/fs/f2fs/xattr.h b/fs/f2fs/xattr.h index 49c9558..3c0817b 100644 --- a/fs/f2fs/xattr.h +++ b/fs/f2fs/xattr.h @@ -112,21 +112,19 @@ extern const struct xattr_handler f2fs_xattr_trusted_handler; extern const struct xattr_handler f2fs_xattr_acl_access_handler; extern const struct xattr_handler f2fs_xattr_acl_default_handler; extern const struct xattr_handler f2fs_xattr_advise_handler; +extern const struct xattr_handler f2fs_xattr_security_handler; =20 extern const struct xattr_handler *f2fs_xattr_handlers[]; =20 -extern int f2fs_setxattr(struct inode *inode, int name_index, const char *name, - const void *value, size_t value_len); -extern int f2fs_getxattr(struct inode *inode, int name_index, const char *name, - void *buffer, size_t buffer_size); -extern ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, - size_t buffer_size); - +extern int f2fs_setxattr(struct inode *, int, const char *, + const void *, size_t, struct page *); +extern int f2fs_getxattr(struct inode *, int, const char *, void *, size_t); +extern ssize_t f2fs_listxattr(struct dentry *, char *, size_t); #else =20 #define f2fs_xattr_handlers NULL static inline int f2fs_setxattr(struct inode *inode, int name_index, - const char *name, const void *value, size_t value_len) + const char *name, const void *value, size_t value_len) { return -EOPNOTSUPP; } @@ -142,4 +140,14 @@ static inline ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, } #endif =20 +#ifdef CONFIG_F2FS_FS_SECURITY +extern int f2fs_init_security(struct inode *, struct inode *, + const struct qstr *, struct page *); +#else +static inline int f2fs_init_security(struct inode *inode, struct inode *dir, + const struct qstr *qstr, struct page *ipage) +{ + return 0; +} +#endif #endif /* __F2FS_XATTR_H__ */ --=20 1.8.1.3.566.gaa39828 --=20 Jaegeuk Kim Samsung --=-Wez1pmqxIGYhr8CMEslI Content-Type: application/pgp-signature; name="signature.asc" Content-Description: This is a digitally signed message part Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJRtsmxAAoJEEAUqH6CSFDScvgP/i+XRaAAkZgKp+6MXpg3L7WH aySX9E7nCctDWftxzPyGXPUDGnaq+67qThy3/RibKFAQm0AQPjC3/LTXygGlYDDY zvldAzhTBDiN9HmsIJuBg2TWhRf+yCiIoXzV72vLFJ3aymGM1nhaquOTboN0fpD1 twhbj9SKmNDmn/bfQNDJaHJcJxE8all8yd7pRQatUWjGz/Lmg90r3sBB2/ckSuQp u7bVQRnaLWFnDBzE2mK15izK+uGmxL/GzGJb5tGU4li43OLi1C8hBdyDqVFrucm4 afS77kg5YCSGlfESsmq99Z+CJt4kASbgsBHVw2wvZdTyiiHVFhjdBiAMv2I2LoAO hhAO3wPbeENXG4hAe9303JfX/mY9T2indk23+WJqgUKgWfogxLyaWRtdQC0xaG6t BOLhKK+Gp0dPHRvNqPp9a3cQKeoWhoCs17lGS6vjEpvvSMyvqpun6aI8FMuIRCvx tpVUD/3CelsyL95MAVJZbLyScg+P4JCmav85U8US2UTUn5dUr/6NNARBSkiouZve c2UybpfVjbbKIo9cdPQOfIhkmnY6d0CzF1LjgCw9IDwBcp/GES5jvSYDsht1SE5D ojZav+APv8bYMm4I155zgaxYLwEDFMXdxR28Lb2XTve0/vpbsrCI9ZDzsKS44qRk 7UGqfb+Guvn6z/f8yBCi =Db2t -----END PGP SIGNATURE----- --=-Wez1pmqxIGYhr8CMEslI-- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/