···215215 no chance of AB-BA deadlock involving its f->sem). */216216 mutex_unlock(&f->sem);217217218218- ret = jffs2_do_create(c, dir_f, f, ri,219219- dentry->d_name.name, dentry->d_name.len);218218+ ret = jffs2_do_create(c, dir_f, f, ri, &dentry->d_name);220219 if (ret)221220 goto fail;222221···385386386387 jffs2_complete_reservation(c);387388388388- ret = jffs2_init_security(inode, dir_i);389389+ ret = jffs2_init_security(inode, dir_i, &dentry->d_name);389390 if (ret)390391 goto fail;391392···529530530531 jffs2_complete_reservation(c);531532532532- ret = jffs2_init_security(inode, dir_i);533533+ ret = jffs2_init_security(inode, dir_i, &dentry->d_name);533534 if (ret)534535 goto fail;535536···702703703704 jffs2_complete_reservation(c);704705705705- ret = jffs2_init_security(inode, dir_i);706706+ ret = jffs2_init_security(inode, dir_i, &dentry->d_name);706707 if (ret)707708 goto fail;708709
···17671767 if (path->dentry != path->mnt->mnt_root)17681768 return -EINVAL;1769176917701770+ err = security_sb_remount(sb, data);17711771+ if (err)17721772+ return err;17731773+17701774 down_write(&sb->s_umount);17711775 if (flags & MS_BIND)17721776 err = change_mount_flags(path->mnt, flags);
+2-2
fs/ocfs2/namei.c
···293293 }294294295295 /* get security xattr */296296- status = ocfs2_init_security_get(inode, dir, &si);296296+ status = ocfs2_init_security_get(inode, dir, &dentry->d_name, &si);297297 if (status) {298298 if (status == -EOPNOTSUPP)299299 si.enable = 0;···16651665 }1666166616671667 /* get security xattr */16681668- status = ocfs2_init_security_get(inode, dir, &si);16681668+ status = ocfs2_init_security_get(inode, dir, &dentry->d_name, &si);16691669 if (status) {16701670 if (status == -EOPNOTSUPP)16711671 si.enable = 0;
+2-1
fs/ocfs2/refcounttree.c
···4328432843294329 /* If the security isn't preserved, we need to re-initialize them. */43304330 if (!preserve) {43314331- error = ocfs2_init_security_and_acl(dir, new_orphan_inode);43314331+ error = ocfs2_init_security_and_acl(dir, new_orphan_inode,43324332+ &new_dentry->d_name);43324333 if (error)43334334 mlog_errno(error);43344335 }
+6-4
fs/ocfs2/xattr.c
···71857185 * must not hold any lock expect i_mutex.71867186 */71877187int ocfs2_init_security_and_acl(struct inode *dir,71887188- struct inode *inode)71887188+ struct inode *inode,71897189+ const struct qstr *qstr)71897190{71907191 int ret = 0;71917192 struct buffer_head *dir_bh = NULL;···71947193 .enable = 1,71957194 };7196719571977197- ret = ocfs2_init_security_get(inode, dir, &si);71967196+ ret = ocfs2_init_security_get(inode, dir, qstr, &si);71987197 if (!ret) {71997198 ret = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,72007199 si.name, si.value, si.value_len,···7262726172637262int ocfs2_init_security_get(struct inode *inode,72647263 struct inode *dir,72647264+ const struct qstr *qstr,72657265 struct ocfs2_security_xattr_info *si)72667266{72677267 /* check whether ocfs2 support feature xattr */72687268 if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb)))72697269 return -EOPNOTSUPP;72707270- return security_inode_init_security(inode, dir, &si->name, &si->value,72717271- &si->value_len);72707270+ return security_inode_init_security(inode, dir, qstr, &si->name,72717271+ &si->value, &si->value_len);72727272}7273727372747274int ocfs2_init_security_set(handle_t *handle,
···5454 * of blocks needed for the transaction. If successful, reiserfs_security5555 * must be released using reiserfs_security_free when the caller is done. */5656int reiserfs_security_init(struct inode *dir, struct inode *inode,5757+ const struct qstr *qstr,5758 struct reiserfs_security_handle *sec)5859{5960 int blocks = 0;···6665 if (IS_PRIVATE(dir))6766 return 0;68676969- error = security_inode_init_security(inode, dir, &sec->name,6868+ error = security_inode_init_security(inode, dir, qstr, &sec->name,7069 &sec->value, &sec->length);7170 if (error) {7271 if (error == -EOPNOTSUPP)
···2525#include <linux/fs.h>2626#include <linux/fsnotify.h>2727#include <linux/binfmts.h>2828+#include <linux/dcache.h>2829#include <linux/signal.h>2930#include <linux/resource.h>3031#include <linux/sem.h>···268267 * @orig the original mount data copied from userspace.269268 * @copy copied data which will be passed to the security module.270269 * Returns 0 if the copy was successful.270270+ * @sb_remount:271271+ * Extracts security system specifc mount options and verifys no changes272272+ * are being made to those options.273273+ * @sb superblock being remounted274274+ * @data contains the filesystem-specific data.275275+ * Return 0 if permission is granted.271276 * @sb_umount:272277 * Check permission before the @mnt file system is unmounted.273278 * @mnt contains the mounted file system.···322315 * then it should return -EOPNOTSUPP to skip this processing.323316 * @inode contains the inode structure of the newly created inode.324317 * @dir contains the inode structure of the parent directory.318318+ * @qstr contains the last path component of the new object325319 * @name will be set to the allocated name suffix (e.g. selinux).326320 * @value will be set to the allocated attribute value.327321 * @len will be set to the length of the value.···12651257 * @cap contains the capability <include/linux/capability.h>.12661258 * @audit: Whether to write an audit message or not12671259 * Return 0 if the capability is granted for @tsk.12681268- * @sysctl:12691269- * Check permission before accessing the @table sysctl variable in the12701270- * manner specified by @op.12711271- * @table contains the ctl_table structure for the sysctl variable.12721272- * @op contains the operation (001 = search, 002 = write, 004 = read).12731273- * Return 0 if permission is granted.12741260 * @syslog:12751261 * Check permission before accessing the kernel message ring or changing12761262 * logging to the console.···13851383 const kernel_cap_t *permitted);13861384 int (*capable) (struct task_struct *tsk, const struct cred *cred,13871385 int cap, int audit);13881388- int (*sysctl) (struct ctl_table *table, int op);13891386 int (*quotactl) (int cmds, int type, int id, struct super_block *sb);13901387 int (*quota_on) (struct dentry *dentry);13911388 int (*syslog) (int type);···14001399 int (*sb_alloc_security) (struct super_block *sb);14011400 void (*sb_free_security) (struct super_block *sb);14021401 int (*sb_copy_data) (char *orig, char *copy);14021402+ int (*sb_remount) (struct super_block *sb, void *data);14031403 int (*sb_kern_mount) (struct super_block *sb, int flags, void *data);14041404 int (*sb_show_options) (struct seq_file *m, struct super_block *sb);14051405 int (*sb_statfs) (struct dentry *dentry);···14371435 int (*inode_alloc_security) (struct inode *inode);14381436 void (*inode_free_security) (struct inode *inode);14391437 int (*inode_init_security) (struct inode *inode, struct inode *dir,14401440- char **name, void **value, size_t *len);14381438+ const struct qstr *qstr, char **name,14391439+ void **value, size_t *len);14411440 int (*inode_create) (struct inode *dir,14421441 struct dentry *dentry, int mode);14431442 int (*inode_link) (struct dentry *old_dentry,···16681665int security_capable(const struct cred *cred, int cap);16691666int security_real_capable(struct task_struct *tsk, int cap);16701667int security_real_capable_noaudit(struct task_struct *tsk, int cap);16711671-int security_sysctl(struct ctl_table *table, int op);16721668int security_quotactl(int cmds, int type, int id, struct super_block *sb);16731669int security_quota_on(struct dentry *dentry);16741670int security_syslog(int type);···16831681int security_sb_alloc(struct super_block *sb);16841682void security_sb_free(struct super_block *sb);16851683int security_sb_copy_data(char *orig, char *copy);16841684+int security_sb_remount(struct super_block *sb, void *data);16861685int security_sb_kern_mount(struct super_block *sb, int flags, void *data);16871686int security_sb_show_options(struct seq_file *m, struct super_block *sb);16881687int security_sb_statfs(struct dentry *dentry);···16991696int security_inode_alloc(struct inode *inode);17001697void security_inode_free(struct inode *inode);17011698int security_inode_init_security(struct inode *inode, struct inode *dir,17021702- char **name, void **value, size_t *len);16991699+ const struct qstr *qstr, char **name,17001700+ void **value, size_t *len);17031701int security_inode_create(struct inode *dir, struct dentry *dentry, int mode);17041702int security_inode_link(struct dentry *old_dentry, struct inode *dir,17051703 struct dentry *new_dentry);···18871883 return ret;18881884}1889188518901890-static inline int security_sysctl(struct ctl_table *table, int op)18911891-{18921892- return 0;18931893-}18941894-18951886static inline int security_quotactl(int cmds, int type, int id,18961887 struct super_block *sb)18971888{···19631964 return 0;19641965}1965196619671967+static inline int security_sb_remount(struct super_block *sb, void *data)19681968+{19691969+ return 0;19701970+}19711971+19661972static inline int security_sb_kern_mount(struct super_block *sb, int flags, void *data)19671973{19681974 return 0;···2027202320282024static inline int security_inode_init_security(struct inode *inode,20292025 struct inode *dir,20262026+ const struct qstr *qstr,20302027 char **name,20312028 void **value,20322029 size_t *len)
-5
kernel/sysctl.c
···1685168516861686int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op)16871687{16881688- int error;16891688 int mode;16901690-16911691- error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));16921692- if (error)16931693- return error;1694168916951690 if (root->permissions)16961691 mode = root->permissions(root, current->nsproxy, table);
···2424 */25252626#include <linux/init.h>2727+#include <linux/kd.h>2728#include <linux/kernel.h>2829#include <linux/tracehook.h>2930#include <linux/errno.h>3131+#include <linux/ext2_fs.h>3032#include <linux/sched.h>3133#include <linux/security.h>3234#include <linux/xattr.h>···3836#include <linux/mman.h>3937#include <linux/slab.h>4038#include <linux/pagemap.h>3939+#include <linux/proc_fs.h>4140#include <linux/swap.h>4241#include <linux/spinlock.h>4342#include <linux/syscalls.h>4343+#include <linux/dcache.h>4444#include <linux/file.h>4545#include <linux/fdtable.h>4646#include <linux/namei.h>4747#include <linux/mount.h>4848-#include <linux/proc_fs.h>4948#include <linux/netfilter_ipv4.h>5049#include <linux/netfilter_ipv6.h>5150#include <linux/tty.h>···7370#include <net/ipv6.h>7471#include <linux/hugetlb.h>7572#include <linux/personality.h>7676-#include <linux/sysctl.h>7773#include <linux/audit.h>7874#include <linux/string.h>7975#include <linux/selinux.h>···11221120}1123112111241122#ifdef CONFIG_PROC_FS11251125-static int selinux_proc_get_sid(struct proc_dir_entry *de,11231123+static int selinux_proc_get_sid(struct dentry *dentry,11261124 u16 tclass,11271125 u32 *sid)11281126{11291129- int buflen, rc;11301130- char *buffer, *path, *end;11271127+ int rc;11281128+ char *buffer, *path;1131112911321130 buffer = (char *)__get_free_page(GFP_KERNEL);11331131 if (!buffer)11341132 return -ENOMEM;1135113311361136- buflen = PAGE_SIZE;11371137- end = buffer+buflen;11381138- *--end = '\0';11391139- buflen--;11401140- path = end-1;11411141- *path = '/';11421142- while (de && de != de->parent) {11431143- buflen -= de->namelen + 1;11441144- if (buflen < 0)11451145- break;11461146- end -= de->namelen;11471147- memcpy(end, de->name, de->namelen);11481148- *--end = '/';11491149- path = end;11501150- de = de->parent;11341134+ path = dentry_path_raw(dentry, buffer, PAGE_SIZE);11351135+ if (IS_ERR(path))11361136+ rc = PTR_ERR(path);11371137+ else {11381138+ /* each process gets a /proc/PID/ entry. Strip off the11391139+ * PID part to get a valid selinux labeling.11401140+ * e.g. /proc/1/net/rpc/nfs -> /net/rpc/nfs */11411141+ while (path[1] >= '0' && path[1] <= '9') {11421142+ path[1] = '/';11431143+ path++;11441144+ }11451145+ rc = security_genfs_sid("proc", path, tclass, sid);11511146 }11521152- rc = security_genfs_sid("proc", path, tclass, sid);11531147 free_page((unsigned long)buffer);11541148 return rc;11551149}11561150#else11571157-static int selinux_proc_get_sid(struct proc_dir_entry *de,11511151+static int selinux_proc_get_sid(struct dentry *dentry,11581152 u16 tclass,11591153 u32 *sid)11601154{···1298130012991301 /* Try to obtain a transition SID. */13001302 isec->sclass = inode_mode_to_security_class(inode->i_mode);13011301- rc = security_transition_sid(isec->task_sid,13021302- sbsec->sid,13031303- isec->sclass,13041304- &sid);13031303+ rc = security_transition_sid(isec->task_sid, sbsec->sid,13041304+ isec->sclass, NULL, &sid);13051305 if (rc)13061306 goto out_unlock;13071307 isec->sid = sid;···13121316 isec->sid = sbsec->sid;1313131713141318 if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) {13151315- struct proc_inode *proci = PROC_I(inode);13161316- if (proci->pde) {13191319+ if (opt_dentry) {13171320 isec->sclass = inode_mode_to_security_class(inode->i_mode);13181318- rc = selinux_proc_get_sid(proci->pde,13211321+ rc = selinux_proc_get_sid(opt_dentry,13191322 isec->sclass,13201323 &sid);13211324 if (rc)···15731578 return rc;1574157915751580 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {15761576- rc = security_transition_sid(sid, dsec->sid, tclass, &newsid);15811581+ rc = security_transition_sid(sid, dsec->sid, tclass, NULL, &newsid);15771582 if (rc)15781583 return rc;15791584 }···18571862 return task_has_capability(tsk, cred, cap, audit);18581863}1859186418601860-static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid)18611861-{18621862- int buflen, rc;18631863- char *buffer, *path, *end;18641864-18651865- rc = -ENOMEM;18661866- buffer = (char *)__get_free_page(GFP_KERNEL);18671867- if (!buffer)18681868- goto out;18691869-18701870- buflen = PAGE_SIZE;18711871- end = buffer+buflen;18721872- *--end = '\0';18731873- buflen--;18741874- path = end-1;18751875- *path = '/';18761876- while (table) {18771877- const char *name = table->procname;18781878- size_t namelen = strlen(name);18791879- buflen -= namelen + 1;18801880- if (buflen < 0)18811881- goto out_free;18821882- end -= namelen;18831883- memcpy(end, name, namelen);18841884- *--end = '/';18851885- path = end;18861886- table = table->parent;18871887- }18881888- buflen -= 4;18891889- if (buflen < 0)18901890- goto out_free;18911891- end -= 4;18921892- memcpy(end, "/sys", 4);18931893- path = end;18941894- rc = security_genfs_sid("proc", path, tclass, sid);18951895-out_free:18961896- free_page((unsigned long)buffer);18971897-out:18981898- return rc;18991899-}19001900-19011901-static int selinux_sysctl(ctl_table *table, int op)19021902-{19031903- int error = 0;19041904- u32 av;19051905- u32 tsid, sid;19061906- int rc;19071907-19081908- sid = current_sid();19091909-19101910- rc = selinux_sysctl_get_sid(table, (op == 0001) ?19111911- SECCLASS_DIR : SECCLASS_FILE, &tsid);19121912- if (rc) {19131913- /* Default to the well-defined sysctl SID. */19141914- tsid = SECINITSID_SYSCTL;19151915- }19161916-19171917- /* The op values are "defined" in sysctl.c, thereby creating19181918- * a bad coupling between this module and sysctl.c */19191919- if (op == 001) {19201920- error = avc_has_perm(sid, tsid,19211921- SECCLASS_DIR, DIR__SEARCH, NULL);19221922- } else {19231923- av = 0;19241924- if (op & 004)19251925- av |= FILE__READ;19261926- if (op & 002)19271927- av |= FILE__WRITE;19281928- if (av)19291929- error = avc_has_perm(sid, tsid,19301930- SECCLASS_FILE, av, NULL);19311931- }19321932-19331933- return error;19341934-}19351935-19361865static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)19371866{19381867 const struct cred *cred = current_cred();···19792060 } else {19802061 /* Check for a default transition on this program. */19812062 rc = security_transition_sid(old_tsec->sid, isec->sid,19821982- SECCLASS_PROCESS, &new_tsec->sid);20632063+ SECCLASS_PROCESS, NULL,20642064+ &new_tsec->sid);19832065 if (rc)19842066 return rc;19852067 }···23632443 return rc;23642444}2365244524462446+static int selinux_sb_remount(struct super_block *sb, void *data)24472447+{24482448+ int rc, i, *flags;24492449+ struct security_mnt_opts opts;24502450+ char *secdata, **mount_options;24512451+ struct superblock_security_struct *sbsec = sb->s_security;24522452+24532453+ if (!(sbsec->flags & SE_SBINITIALIZED))24542454+ return 0;24552455+24562456+ if (!data)24572457+ return 0;24582458+24592459+ if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)24602460+ return 0;24612461+24622462+ security_init_mnt_opts(&opts);24632463+ secdata = alloc_secdata();24642464+ if (!secdata)24652465+ return -ENOMEM;24662466+ rc = selinux_sb_copy_data(data, secdata);24672467+ if (rc)24682468+ goto out_free_secdata;24692469+24702470+ rc = selinux_parse_opts_str(secdata, &opts);24712471+ if (rc)24722472+ goto out_free_secdata;24732473+24742474+ mount_options = opts.mnt_opts;24752475+ flags = opts.mnt_opts_flags;24762476+24772477+ for (i = 0; i < opts.num_mnt_opts; i++) {24782478+ u32 sid;24792479+ size_t len;24802480+24812481+ if (flags[i] == SE_SBLABELSUPP)24822482+ continue;24832483+ len = strlen(mount_options[i]);24842484+ rc = security_context_to_sid(mount_options[i], len, &sid);24852485+ if (rc) {24862486+ printk(KERN_WARNING "SELinux: security_context_to_sid"24872487+ "(%s) failed for (dev %s, type %s) errno=%d\n",24882488+ mount_options[i], sb->s_id, sb->s_type->name, rc);24892489+ goto out_free_opts;24902490+ }24912491+ rc = -EINVAL;24922492+ switch (flags[i]) {24932493+ case FSCONTEXT_MNT:24942494+ if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid))24952495+ goto out_bad_option;24962496+ break;24972497+ case CONTEXT_MNT:24982498+ if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid))24992499+ goto out_bad_option;25002500+ break;25012501+ case ROOTCONTEXT_MNT: {25022502+ struct inode_security_struct *root_isec;25032503+ root_isec = sb->s_root->d_inode->i_security;25042504+25052505+ if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid))25062506+ goto out_bad_option;25072507+ break;25082508+ }25092509+ case DEFCONTEXT_MNT:25102510+ if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid))25112511+ goto out_bad_option;25122512+ break;25132513+ default:25142514+ goto out_free_opts;25152515+ }25162516+ }25172517+25182518+ rc = 0;25192519+out_free_opts:25202520+ security_free_mnt_opts(&opts);25212521+out_free_secdata:25222522+ free_secdata(secdata);25232523+ return rc;25242524+out_bad_option:25252525+ printk(KERN_WARNING "SELinux: unable to change security options "25262526+ "during remount (dev %s, type=%s)\n", sb->s_id,25272527+ sb->s_type->name);25282528+ goto out_free_opts;25292529+}25302530+23662531static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)23672532{23682533 const struct cred *cred = current_cred();···25142509}2515251025162511static int selinux_inode_init_security(struct inode *inode, struct inode *dir,25172517- char **name, void **value,25182518- size_t *len)25122512+ const struct qstr *qstr, char **name,25132513+ void **value, size_t *len)25192514{25202515 const struct task_security_struct *tsec = current_security();25212516 struct inode_security_struct *dsec;···25362531 else if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {25372532 rc = security_transition_sid(sid, dsec->sid,25382533 inode_mode_to_security_class(inode->i_mode),25392539- &newsid);25342534+ qstr, &newsid);25402535 if (rc) {25412536 printk(KERN_WARNING "%s: "25422537 "security_transition_sid failed, rc=%d (dev=%s "···29372932 unsigned long arg)29382933{29392934 const struct cred *cred = current_cred();29402940- u32 av = 0;29352935+ int error = 0;2941293629422942- if (_IOC_DIR(cmd) & _IOC_WRITE)29432943- av |= FILE__WRITE;29442944- if (_IOC_DIR(cmd) & _IOC_READ)29452945- av |= FILE__READ;29462946- if (!av)29472947- av = FILE__IOCTL;29372937+ switch (cmd) {29382938+ case FIONREAD:29392939+ /* fall through */29402940+ case FIBMAP:29412941+ /* fall through */29422942+ case FIGETBSZ:29432943+ /* fall through */29442944+ case EXT2_IOC_GETFLAGS:29452945+ /* fall through */29462946+ case EXT2_IOC_GETVERSION:29472947+ error = file_has_perm(cred, file, FILE__GETATTR);29482948+ break;2948294929492949- return file_has_perm(cred, file, av);29502950+ case EXT2_IOC_SETFLAGS:29512951+ /* fall through */29522952+ case EXT2_IOC_SETVERSION:29532953+ error = file_has_perm(cred, file, FILE__SETATTR);29542954+ break;29552955+29562956+ /* sys_ioctl() checks */29572957+ case FIONBIO:29582958+ /* fall through */29592959+ case FIOASYNC:29602960+ error = file_has_perm(cred, file, 0);29612961+ break;29622962+29632963+ case KDSKBENT:29642964+ case KDSKBSENT:29652965+ error = task_has_capability(current, cred, CAP_SYS_TTY_CONFIG,29662966+ SECURITY_CAP_AUDIT);29672967+ break;29682968+29692969+ /* default case assumes that the command will go29702970+ * to the file's ioctl() function.29712971+ */29722972+ default:29732973+ error = file_has_perm(cred, file, FILE__IOCTL);29742974+ }29752975+ return error;29502976}2951297729522978static int default_noexec;···3680364436813645/* socket security operations */3682364636833683-static u32 socket_sockcreate_sid(const struct task_security_struct *tsec)36473647+static int socket_sockcreate_sid(const struct task_security_struct *tsec,36483648+ u16 secclass, u32 *socksid)36843649{36853685- return tsec->sockcreate_sid ? : tsec->sid;36503650+ if (tsec->sockcreate_sid > SECSID_NULL) {36513651+ *socksid = tsec->sockcreate_sid;36523652+ return 0;36533653+ }36543654+36553655+ return security_transition_sid(tsec->sid, tsec->sid, secclass, NULL,36563656+ socksid);36863657}3687365836883659static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms)···37133670 const struct task_security_struct *tsec = current_security();37143671 u32 newsid;37153672 u16 secclass;36733673+ int rc;3716367437173675 if (kern)37183676 return 0;3719367737203720- newsid = socket_sockcreate_sid(tsec);37213678 secclass = socket_type_to_security_class(family, type, protocol);36793679+ rc = socket_sockcreate_sid(tsec, secclass, &newsid);36803680+ if (rc)36813681+ return rc;36823682+37223683 return avc_has_perm(tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);37233684}37243685···37343687 struct sk_security_struct *sksec;37353688 int err = 0;3736368936903690+ isec->sclass = socket_type_to_security_class(family, type, protocol);36913691+37373692 if (kern)37383693 isec->sid = SECINITSID_KERNEL;37393739- else37403740- isec->sid = socket_sockcreate_sid(tsec);36943694+ else {36953695+ err = socket_sockcreate_sid(tsec, isec->sclass, &(isec->sid));36963696+ if (err)36973697+ return err;36983698+ }3741369937423742- isec->sclass = socket_type_to_security_class(family, type, protocol);37433700 isec->initialized = 1;3744370137453702 if (sock->sk) {···40534002{40544003 int err = 0;40554004 struct sk_security_struct *sksec = sk->sk_security;40564056- u32 peer_sid;40574005 u32 sk_sid = sksec->sid;40584006 struct common_audit_data ad;40594007 char *addrp;···40714021 return err;40724022 }4073402340744074- if (selinux_policycap_netpeer) {40754075- err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);40764076- if (err)40774077- return err;40784078- err = avc_has_perm(sk_sid, peer_sid,40794079- SECCLASS_PEER, PEER__RECV, &ad);40804080- if (err)40814081- selinux_netlbl_err(skb, err, 0);40824082- } else {40834083- err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);40844084- if (err)40854085- return err;40864086- err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);40874087- }40244024+ err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);40254025+ if (err)40264026+ return err;40274027+ err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);4088402840894029 return err;40904030}···45694529 SECCLASS_PACKET, PACKET__SEND, &ad))45704530 return NF_DROP_ERR(-ECONNREFUSED);4571453145724572- if (selinux_policycap_netpeer)45734573- if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))45744574- return NF_DROP_ERR(-ECONNREFUSED);45324532+ if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))45334533+ return NF_DROP_ERR(-ECONNREFUSED);4575453445764535 return NF_ACCEPT;45774536}···46134574 * from the sending socket, otherwise use the kernel's sid */46144575 sk = skb->sk;46154576 if (sk == NULL) {46164616- switch (family) {46174617- case PF_INET:46184618- if (IPCB(skb)->flags & IPSKB_FORWARDED)46194619- secmark_perm = PACKET__FORWARD_OUT;46204620- else46214621- secmark_perm = PACKET__SEND;46224622- break;46234623- case PF_INET6:46244624- if (IP6CB(skb)->flags & IP6SKB_FORWARDED)46254625- secmark_perm = PACKET__FORWARD_OUT;46264626- else46274627- secmark_perm = PACKET__SEND;46284628- break;46294629- default:46304630- return NF_DROP_ERR(-ECONNREFUSED);46314631- }46324632- if (secmark_perm == PACKET__FORWARD_OUT) {45774577+ if (skb->skb_iif) {45784578+ secmark_perm = PACKET__FORWARD_OUT;46334579 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))46344580 return NF_DROP;46354635- } else45814581+ } else {45824582+ secmark_perm = PACKET__SEND;46364583 peer_sid = SECINITSID_KERNEL;45844584+ }46374585 } else {46384586 struct sk_security_struct *sksec = sk->sk_security;46394587 peer_sid = sksec->sid;···48744848 * message queue this message will be stored in48754849 */48764850 rc = security_transition_sid(sid, isec->sid, SECCLASS_MSG,48774877- &msec->sid);48514851+ NULL, &msec->sid);48784852 if (rc)48794853 return rc;48804854 }···54285402 .ptrace_traceme = selinux_ptrace_traceme,54295403 .capget = selinux_capget,54305404 .capset = selinux_capset,54315431- .sysctl = selinux_sysctl,54325405 .capable = selinux_capable,54335406 .quotactl = selinux_quotactl,54345407 .quota_on = selinux_quota_on,···54455420 .sb_alloc_security = selinux_sb_alloc_security,54465421 .sb_free_security = selinux_sb_free_security,54475422 .sb_copy_data = selinux_sb_copy_data,54235423+ .sb_remount = selinux_sb_remount,54485424 .sb_kern_mount = selinux_sb_kern_mount,54495425 .sb_show_options = selinux_sb_show_options,54505426 .sb_statfs = selinux_sb_statfs,
+5-2
security/selinux/include/classmap.h
···1212#define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \1313 "write", "associate", "unix_read", "unix_write"14141515+/*1616+ * Note: The name for any socket class should be suffixed by "socket",1717+ * and doesn't contain more than one substr of "socket".1818+ */1519struct security_class_mapping secclass_map[] = {1620 { "security",1721 { "compute_av", "compute_create", "compute_member",···136132 { "appletalk_socket",137133 { COMMON_SOCK_PERMS, NULL } },138134 { "packet",139139- { "send", "recv", "relabelto", "flow_in", "flow_out",140140- "forward_in", "forward_out", NULL } },135135+ { "send", "recv", "relabelto", "forward_in", "forward_out", NULL } },141136 { "key",142137 { "view", "read", "write", "search", "link", "setattr", "create",143138 NULL } },
+5-3
security/selinux/include/security.h
···88#ifndef _SELINUX_SECURITY_H_99#define _SELINUX_SECURITY_H_10101111+#include <linux/dcache.h>1112#include <linux/magic.h>1213#include <linux/types.h>1314#include "flask.h"···2928#define POLICYDB_VERSION_POLCAP 223029#define POLICYDB_VERSION_PERMISSIVE 233130#define POLICYDB_VERSION_BOUNDARY 243131+#define POLICYDB_VERSION_FILENAME_TRANS 2532323333/* Range of policy versions we understand*/3434#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE3535#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX3636#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE3737#else3838-#define POLICYDB_VERSION_MAX POLICYDB_VERSION_BOUNDARY3838+#define POLICYDB_VERSION_MAX POLICYDB_VERSION_FILENAME_TRANS3939#endif40404141/* Mask for just the mount related flags */···108106void security_compute_av_user(u32 ssid, u32 tsid,109107 u16 tclass, struct av_decision *avd);110108111111-int security_transition_sid(u32 ssid, u32 tsid,112112- u16 tclass, u32 *out_sid);109109+int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,110110+ const struct qstr *qstr, u32 *out_sid);113111114112int security_transition_sid_user(u32 ssid, u32 tsid,115113 u16 tclass, u32 *out_sid);
+11-11
security/selinux/ss/avtab.h
···1414 *1515 * Copyright (C) 2003 Tresys Technology, LLC1616 * This program is free software; you can redistribute it and/or modify1717- * it under the terms of the GNU General Public License as published by1717+ * it under the terms of the GNU General Public License as published by1818 * the Free Software Foundation, version 2.1919 *2020 * Updated: Yuichi Nakamura <ynakam@hitachisoft.jp>···2727 u16 source_type; /* source type */2828 u16 target_type; /* target type */2929 u16 target_class; /* target object class */3030-#define AVTAB_ALLOWED 13131-#define AVTAB_AUDITALLOW 23232-#define AVTAB_AUDITDENY 43333-#define AVTAB_AV (AVTAB_ALLOWED | AVTAB_AUDITALLOW | AVTAB_AUDITDENY)3434-#define AVTAB_TRANSITION 163535-#define AVTAB_MEMBER 323636-#define AVTAB_CHANGE 643737-#define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE)3838-#define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */3939-#define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */3030+#define AVTAB_ALLOWED 0x00013131+#define AVTAB_AUDITALLOW 0x00023232+#define AVTAB_AUDITDENY 0x00043333+#define AVTAB_AV (AVTAB_ALLOWED | AVTAB_AUDITALLOW | AVTAB_AUDITDENY)3434+#define AVTAB_TRANSITION 0x00103535+#define AVTAB_MEMBER 0x00203636+#define AVTAB_CHANGE 0x00403737+#define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE)3838+#define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */3939+#define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */4040 u16 specified; /* what field is specified */4141};4242
+3-2
security/selinux/ss/mls.c
···512512 struct context *tcontext,513513 u16 tclass,514514 u32 specified,515515- struct context *newcontext)515515+ struct context *newcontext,516516+ bool sock)516517{517518 struct range_trans rtr;518519 struct mls_range *r;···532531 return mls_range_set(newcontext, r);533532 /* Fallthrough */534533 case AVTAB_CHANGE:535535- if (tclass == policydb.process_class)534534+ if ((tclass == policydb.process_class) || (sock == true))536535 /* Use the process MLS attributes. */537536 return mls_context_cpy(newcontext, scontext);538537 else
···123123 .sym_num = SYM_NUM,124124 .ocon_num = OCON_NUM,125125 },126126+ {127127+ .version = POLICYDB_VERSION_FILENAME_TRANS,128128+ .sym_num = SYM_NUM,129129+ .ocon_num = OCON_NUM,130130+ },126131};127132128133static struct policydb_compat_info *policydb_lookup_compat(int version)···709704 int i;710705 struct role_allow *ra, *lra = NULL;711706 struct role_trans *tr, *ltr = NULL;707707+ struct filename_trans *ft, *nft;712708713709 for (i = 0; i < SYM_NUM; i++) {714710 cond_resched();···787781 }788782 flex_array_free(p->type_attr_map_array);789783 }784784+785785+ ft = p->filename_trans;786786+ while (ft) {787787+ nft = ft->next;788788+ kfree(ft->name);789789+ kfree(ft);790790+ ft = nft;791791+ }792792+790793 ebitmap_destroy(&p->policycaps);791794 ebitmap_destroy(&p->permissive_map);792795···18031788 return rc;18041789}1805179017911791+static int filename_trans_read(struct policydb *p, void *fp)17921792+{17931793+ struct filename_trans *ft, *last;17941794+ u32 nel, len;17951795+ char *name;17961796+ __le32 buf[4];17971797+ int rc, i;17981798+17991799+ if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS)18001800+ return 0;18011801+18021802+ rc = next_entry(buf, fp, sizeof(u32));18031803+ if (rc)18041804+ goto out;18051805+ nel = le32_to_cpu(buf[0]);18061806+18071807+ printk(KERN_ERR "%s: nel=%d\n", __func__, nel);18081808+18091809+ last = p->filename_trans;18101810+ while (last && last->next)18111811+ last = last->next;18121812+18131813+ for (i = 0; i < nel; i++) {18141814+ rc = -ENOMEM;18151815+ ft = kzalloc(sizeof(*ft), GFP_KERNEL);18161816+ if (!ft)18171817+ goto out;18181818+18191819+ /* add it to the tail of the list */18201820+ if (!last)18211821+ p->filename_trans = ft;18221822+ else18231823+ last->next = ft;18241824+ last = ft;18251825+18261826+ /* length of the path component string */18271827+ rc = next_entry(buf, fp, sizeof(u32));18281828+ if (rc)18291829+ goto out;18301830+ len = le32_to_cpu(buf[0]);18311831+18321832+ rc = -ENOMEM;18331833+ name = kmalloc(len + 1, GFP_KERNEL);18341834+ if (!name)18351835+ goto out;18361836+18371837+ ft->name = name;18381838+18391839+ /* path component string */18401840+ rc = next_entry(name, fp, len);18411841+ if (rc)18421842+ goto out;18431843+ name[len] = 0;18441844+18451845+ printk(KERN_ERR "%s: ft=%p ft->name=%p ft->name=%s\n", __func__, ft, ft->name, ft->name);18461846+18471847+ rc = next_entry(buf, fp, sizeof(u32) * 4);18481848+ if (rc)18491849+ goto out;18501850+18511851+ ft->stype = le32_to_cpu(buf[0]);18521852+ ft->ttype = le32_to_cpu(buf[1]);18531853+ ft->tclass = le32_to_cpu(buf[2]);18541854+ ft->otype = le32_to_cpu(buf[3]);18551855+ }18561856+ rc = 0;18571857+out:18581858+ return rc;18591859+}18601860+18061861static int genfs_read(struct policydb *p, void *fp)18071862{18081863 int i, j, rc;···23352250 goto bad;23362251 lra = ra;23372252 }22532253+22542254+ rc = filename_trans_read(p, fp);22552255+ if (rc)22562256+ goto bad;2338225723392258 rc = policydb_index(p);23402259 if (rc)···31143025 return 0;31153026}3116302730283028+static int filename_trans_write(struct policydb *p, void *fp)30293029+{30303030+ struct filename_trans *ft;30313031+ u32 len, nel = 0;30323032+ __le32 buf[4];30333033+ int rc;30343034+30353035+ for (ft = p->filename_trans; ft; ft = ft->next)30363036+ nel++;30373037+30383038+ buf[0] = cpu_to_le32(nel);30393039+ rc = put_entry(buf, sizeof(u32), 1, fp);30403040+ if (rc)30413041+ return rc;30423042+30433043+ for (ft = p->filename_trans; ft; ft = ft->next) {30443044+ len = strlen(ft->name);30453045+ buf[0] = cpu_to_le32(len);30463046+ rc = put_entry(buf, sizeof(u32), 1, fp);30473047+ if (rc)30483048+ return rc;30493049+30503050+ rc = put_entry(ft->name, sizeof(char), len, fp);30513051+ if (rc)30523052+ return rc;30533053+30543054+ buf[0] = ft->stype;30553055+ buf[1] = ft->ttype;30563056+ buf[2] = ft->tclass;30573057+ buf[3] = ft->otype;30583058+30593059+ rc = put_entry(buf, sizeof(u32), 4, fp);30603060+ if (rc)30613061+ return rc;30623062+ }30633063+ return 0;30643064+}31173065/*31183066 * Write the configuration data in a policy database31193067 * structure to a policy database binary representation···32583132 return rc;3259313332603134 rc = role_allow_write(p->role_allow, fp);31353135+ if (rc)31363136+ return rc;31373137+31383138+ rc = filename_trans_write(p, fp);32613139 if (rc)32623140 return rc;32633141
+13-1
security/selinux/ss/policydb.h
···7777 struct role_trans *next;7878};79798080+struct filename_trans {8181+ struct filename_trans *next;8282+ u32 stype; /* current process */8383+ u32 ttype; /* parent dir context */8484+ u16 tclass; /* class of new object */8585+ const char *name; /* last path component */8686+ u32 otype; /* expected of new object */8787+};8888+8089struct role_allow {8190 u32 role; /* current role */8291 u32 new_role; /* new role */···226217 /* role transitions */227218 struct role_trans *role_tr;228219220220+ /* file transitions with the last path component */221221+ struct filename_trans *filename_trans;222222+229223 /* bools indexed by (value - 1) */230224 struct cond_bool_datum **bool_val_to_struct;231225 /* type enforcement conditional access vectors and transitions */···314302 return 0;315303}316304317317-static inline int put_entry(void *buf, size_t bytes, int num, struct policy_file *fp)305305+static inline int put_entry(const void *buf, size_t bytes, int num, struct policy_file *fp)318306{319307 size_t len = bytes * num;320308
+55-18
security/selinux/ss/services.c
···201201 return tclass;202202}203203204204+/*205205+ * Get kernel value for class from its policy value206206+ */207207+static u16 map_class(u16 pol_value)208208+{209209+ u16 i;210210+211211+ for (i = 1; i < current_mapping_size; i++) {212212+ if (current_mapping[i].value == pol_value)213213+ return i;214214+ }215215+216216+ return pol_value;217217+}218218+204219static void map_decision(u16 tclass, struct av_decision *avd,205220 int allow_unknown)206221{···13581343 return -EACCES;13591344}1360134513461346+static void filename_compute_type(struct policydb *p, struct context *newcontext,13471347+ u32 scon, u32 tcon, u16 tclass,13481348+ const struct qstr *qstr)13491349+{13501350+ struct filename_trans *ft;13511351+ for (ft = p->filename_trans; ft; ft = ft->next) {13521352+ if (ft->stype == scon &&13531353+ ft->ttype == tcon &&13541354+ ft->tclass == tclass &&13551355+ !strcmp(ft->name, qstr->name)) {13561356+ newcontext->type = ft->otype;13571357+ return;13581358+ }13591359+ }13601360+}13611361+13611362static int security_compute_sid(u32 ssid,13621363 u32 tsid,13631364 u16 orig_tclass,13641365 u32 specified,13661366+ const struct qstr *qstr,13651367 u32 *out_sid,13661368 bool kern)13671369{···13891357 struct avtab_node *node;13901358 u16 tclass;13911359 int rc = 0;13601360+ bool sock;1392136113931362 if (!ss_initialized) {13941363 switch (orig_tclass) {···1407137414081375 read_lock(&policy_rwlock);1409137614101410- if (kern)13771377+ if (kern) {14111378 tclass = unmap_class(orig_tclass);14121412- else13791379+ sock = security_is_socket_class(orig_tclass);13801380+ } else {14131381 tclass = orig_tclass;13821382+ sock = security_is_socket_class(map_class(tclass));13831383+ }1414138414151385 scontext = sidtab_search(&sidtab, ssid);14161386 if (!scontext) {···14441408 }1445140914461410 /* Set the role and type to default values. */14471447- if (tclass == policydb.process_class) {14111411+ if ((tclass == policydb.process_class) || (sock == true)) {14481412 /* Use the current role and type of process. */14491413 newcontext.role = scontext->role;14501414 newcontext.type = scontext->type;···14781442 newcontext.type = avdatum->data;14791443 }1480144414451445+ /* if we have a qstr this is a file trans check so check those rules */14461446+ if (qstr)14471447+ filename_compute_type(&policydb, &newcontext, scontext->type,14481448+ tcontext->type, tclass, qstr);14491449+14811450 /* Check for class-specific changes. */14821451 if (tclass == policydb.process_class) {14831452 if (specified & AVTAB_TRANSITION) {···1501146015021461 /* Set the MLS attributes.15031462 This is done last because it may allocate memory. */15041504- rc = mls_compute_sid(scontext, tcontext, tclass, specified, &newcontext);14631463+ rc = mls_compute_sid(scontext, tcontext, tclass, specified,14641464+ &newcontext, sock);15051465 if (rc)15061466 goto out_unlock;15071467···15371495 * if insufficient memory is available, or %0 if the new SID was15381496 * computed successfully.15391497 */15401540-int security_transition_sid(u32 ssid,15411541- u32 tsid,15421542- u16 tclass,15431543- u32 *out_sid)14981498+int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,14991499+ const struct qstr *qstr, u32 *out_sid)15441500{15451501 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,15461546- out_sid, true);15021502+ qstr, out_sid, true);15471503}1548150415491549-int security_transition_sid_user(u32 ssid,15501550- u32 tsid,15511551- u16 tclass,15521552- u32 *out_sid)15051505+int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid)15531506{15541507 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,15551555- out_sid, false);15081508+ NULL, out_sid, false);15561509}1557151015581511/**···15681531 u16 tclass,15691532 u32 *out_sid)15701533{15711571- return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid,15721572- false);15341534+ return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, NULL,15351535+ out_sid, false);15731536}1574153715751538/**···15901553 u16 tclass,15911554 u32 *out_sid)15921555{15931593- return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid,15941594- false);15561556+ return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, NULL,15571557+ out_sid, false);15951558}1596155915971560/* Clone the SID into the new SID table. */
+1-1
security/selinux/xfrm.c
···208208 if (!uctx)209209 goto not_from_user;210210211211- if (uctx->ctx_doi != XFRM_SC_ALG_SELINUX)211211+ if (uctx->ctx_alg != XFRM_SC_ALG_SELINUX)212212 return -EINVAL;213213214214 str_len = uctx->ctx_len;
+4-1
security/smack/smack_lsm.c
···3333#include <net/cipso_ipv4.h>3434#include <linux/audit.h>3535#include <linux/magic.h>3636+#include <linux/dcache.h>3637#include "smack.h"37383839#define task_security(task) (task_cred_xxx((task), security))···502501 * smack_inode_init_security - copy out the smack from an inode503502 * @inode: the inode504503 * @dir: unused504504+ * @qstr: unused505505 * @name: where to put the attribute name506506 * @value: where to put the attribute value507507 * @len: where to put the length of the attribute···510508 * Returns 0 if it all works out, -ENOMEM if there's no memory511509 */512510static int smack_inode_init_security(struct inode *inode, struct inode *dir,513513- char **name, void **value, size_t *len)511511+ const struct qstr *qstr, char **name,512512+ void **value, size_t *len)514513{515514 char *isp = smk_of_inode(inode);516515 char *dsp = smk_of_inode(dir);