commit c4adf1697bd4a83156306fb9df9870bf233c9cc0 Author: Arkadiusz MiĆkiewicz <ar...@maven.pl> Date: Fri Jun 15 12:21:41 2018 +0200
- up to 4.17.1; drop apparmor unix mediation (until it is merged upstream) 0002-apparmor-af_unix-mediation.patch | 1382 --------------------------------- kernel-aufs4.patch | 114 +-- kernel.spec | 17 +- 3 files changed, 66 insertions(+), 1447 deletions(-) --- diff --git a/kernel.spec b/kernel.spec index b52abf55..f79fde81 100644 --- a/kernel.spec +++ b/kernel.spec @@ -29,7 +29,6 @@ %bcond_without ipv6 # ipv6 support %bcond_without aufs # aufs4 support -%bcond_without apparmor # UBUNTU SAUCE apparmor patches %bcond_with vserver # support for VServer @@ -68,9 +67,9 @@ %define have_pcmcia 0 %endif -%define rel 0.1 +%define rel 1 %define basever 4.17 -%define postver .0 +%define postver .1 # define this to '-%{basever}' for longterm branch %define versuffix %{nil} @@ -122,7 +121,7 @@ Source0: https://www.kernel.org/pub/linux/kernel/v4.x/linux-%{basever}.tar.xz # Source0-md5: 5bb13a03274b66b56c85b26682e407d7 %if "%{postver}" != ".0" Patch0: https://www.kernel.org/pub/linux/kernel/v4.x/patch-%{version}.xz -# Patch0-md5: ace51349b2f09e3731709b95b8053289 +# Patch0-md5: 8f430fc5bf2fd5a6ec5da8b4a08473d8 %endif Source1: kernel.sysconfig @@ -196,7 +195,7 @@ Patch101: kernel-vserver-fixes.patch # Patch creation: # git clone git://github.com/sfjro/aufs4-standalone.git # cd aufs4-standalone -# git checkout -b aufs4.14 origin/aufs4.14 +# git checkout -b aufs4.17 origin/aufs4.17 # cat aufs4-kbuild.patch aufs4-base.patch aufs4-mmap.patch aufs4-standalone.patch > ~/rpm/packages/kernel/kernel-aufs4.patch # rm -rf linux && mkdir linux; cp -a Documentation fs include linux # diff -urN /usr/share/empty linux | filterdiff -x linux/include/uapi/linux/Kbuild >> ~/rpm/packages/kernel/kernel-aufs4.patch @@ -216,9 +215,6 @@ Patch2000: kernel-small_fixes.patch Patch2001: kernel-pwc-uncompress.patch Patch2003: kernel-regressions.patch -# https://gitlab.com/apparmor/apparmor/tree/master/kernel-patches/v4.15 -Patch5001: 0002-apparmor-af_unix-mediation.patch - # for rescuecd # based on ftp://ftp.leg.uct.ac.za/pub/linux/rip/tmpfs_root-2.6.30.diff.gz Patch7000: kernel-inittmpfs.patch @@ -681,11 +677,6 @@ cd linux-%{basever} rm -f localversion-rt %endif -# apparmor -%if %{with apparmor} -%patch5001 -p1 -%endif - %patch250 -p1 %endif # vanilla diff --git a/0002-apparmor-af_unix-mediation.patch b/0002-apparmor-af_unix-mediation.patch deleted file mode 100644 index 95228c41..00000000 --- a/0002-apparmor-af_unix-mediation.patch +++ /dev/null @@ -1,1382 +0,0 @@ -From 8f0a917911fe19f9911d972fe85c43243f7eaa37 Mon Sep 17 00:00:00 2001 -From: John Johansen <john.johan...@canonical.com> -Date: Tue, 18 Jul 2017 23:27:23 -0700 -Subject: [PATCH 2/2] apparmor: af_unix mediation - -af_socket mediation did not make it into 4.14 so add remaining out -of tree patch - -Signed-off-by: John Johansen <john.johan...@canonical.com> -Signed-off-by: Seth Forshee <seth.fors...@canonical.com> ---- - security/apparmor/Makefile | 3 +- - security/apparmor/af_unix.c | 651 ++++++++++++++++++++++++++++++++++++ - security/apparmor/apparmorfs.c | 6 + - security/apparmor/file.c | 4 +- - security/apparmor/include/af_unix.h | 114 +++++++ - security/apparmor/include/net.h | 16 +- - security/apparmor/include/path.h | 1 + - security/apparmor/include/policy.h | 2 +- - security/apparmor/lsm.c | 169 ++++++---- - security/apparmor/net.c | 174 +++++++++- - 10 files changed, 1072 insertions(+), 68 deletions(-) - create mode 100644 security/apparmor/af_unix.c - create mode 100644 security/apparmor/include/af_unix.h - -diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile -index e7ff2183532a..90c118f39e13 100644 ---- a/security/apparmor/Makefile -+++ b/security/apparmor/Makefile -@@ -5,7 +5,8 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o - - apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \ - path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \ -- resource.o secid.o file.o policy_ns.o label.o mount.o net.o -+ resource.o secid.o file.o policy_ns.o label.o mount.o net.o \ -+ af_unix.o - apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o - - clean-files := capability_names.h rlim_names.h net_names.h -diff --git a/security/apparmor/af_unix.c b/security/apparmor/af_unix.c -new file mode 100644 -index 000000000000..c6876db2dbde ---- /dev/null -+++ b/security/apparmor/af_unix.c -@@ -0,0 +1,651 @@ -+/* -+ * AppArmor security module -+ * -+ * This file contains AppArmor af_unix fine grained mediation -+ * -+ * Copyright 2014 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation, version 2 of the -+ * License. -+ */ -+ -+#include <net/tcp_states.h> -+ -+#include "include/af_unix.h" -+#include "include/apparmor.h" -+#include "include/context.h" -+#include "include/file.h" -+#include "include/label.h" -+#include "include/path.h" -+#include "include/policy.h" -+ -+static inline struct sock *aa_sock(struct unix_sock *u) -+{ -+ return &u->sk; -+} -+ -+static inline int unix_fs_perm(const char *op, u32 mask, struct aa_label *label, -+ struct unix_sock *u, int flags) -+{ -+ AA_BUG(!label); -+ AA_BUG(!u); -+ AA_BUG(!UNIX_FS(aa_sock(u))); -+ -+ if (unconfined(label) || !LABEL_MEDIATES(label, AA_CLASS_FILE)) -+ return 0; -+ -+ mask &= NET_FS_PERMS; -+ if (!u->path.dentry) { -+ struct path_cond cond = { }; -+ struct aa_perms perms = { }; -+ struct aa_profile *profile; -+ -+ /* socket path has been cleared because it is being shutdown -+ * can only fall back to original sun_path request -+ */ -+ struct aa_sk_ctx *ctx = SK_CTX(&u->sk); -+ if (ctx->path.dentry) -+ return aa_path_perm(op, label, &ctx->path, flags, mask, -+ &cond); -+ return fn_for_each_confined(label, profile, -+ ((flags | profile->path_flags) & PATH_MEDIATE_DELETED) ? -+ __aa_path_perm(op, profile, -+ u->addr->name->sun_path, mask, -+ &cond, flags, &perms) : -+ aa_audit_file(profile, &nullperms, op, mask, -+ u->addr->name->sun_path, NULL, -+ NULL, cond.uid, -+ "Failed name lookup - " -+ "deleted entry", -EACCES)); -+ } else { -+ /* the sunpath may not be valid for this ns so use the path */ -+ struct path_cond cond = { u->path.dentry->d_inode->i_uid, -+ u->path.dentry->d_inode->i_mode -+ }; -+ -+ return aa_path_perm(op, label, &u->path, flags, mask, &cond); -+ } -+ -+ return 0; -+} -+ -+/* passing in state returned by PROFILE_MEDIATES_AF */ -+static unsigned int match_to_prot(struct aa_profile *profile, -+ unsigned int state, int type, int protocol, -+ const char **info) -+{ -+ __be16 buffer[2]; -+ buffer[0] = cpu_to_be16(type); -+ buffer[1] = cpu_to_be16(protocol); -+ state = aa_dfa_match_len(profile->policy.dfa, state, (char *) &buffer, -+ 4); -+ if (!state) -+ *info = "failed type and protocol match"; -+ return state; -+} -+ -+static unsigned int match_addr(struct aa_profile *profile, unsigned int state, -+ struct sockaddr_un *addr, int addrlen) -+{ -+ if (addr) -+ /* include leading \0 */ -+ state = aa_dfa_match_len(profile->policy.dfa, state, -+ addr->sun_path, -+ unix_addr_len(addrlen)); -+ else -+ /* anonymous end point */ -+ state = aa_dfa_match_len(profile->policy.dfa, state, "\x01", -+ 1); -+ /* todo change to out of band */ -+ state = aa_dfa_null_transition(profile->policy.dfa, state); -+ return state; -+} -+ -+static unsigned int match_to_local(struct aa_profile *profile, -+ unsigned int state, int type, int protocol, -+ struct sockaddr_un *addr, int addrlen, -+ const char **info) -+{ -+ state = match_to_prot(profile, state, type, protocol, info); -+ if (state) { -+ state = match_addr(profile, state, addr, addrlen); -+ if (state) { -+ /* todo: local label matching */ -+ state = aa_dfa_null_transition(profile->policy.dfa, -+ state); -+ if (!state) -+ *info = "failed local label match"; -+ } else -+ *info = "failed local address match"; -+ } -+ -+ return state; -+} -+ -+static unsigned int match_to_sk(struct aa_profile *profile, -+ unsigned int state, struct unix_sock *u, -+ const char **info) -+{ -+ struct sockaddr_un *addr = NULL; -+ int addrlen = 0; -+ -+ if (u->addr) { -+ addr = u->addr->name; -+ addrlen = u->addr->len; -+ } -+ -+ return match_to_local(profile, state, u->sk.sk_type, u->sk.sk_protocol, -+ addr, addrlen, info); -+} -+ -+#define CMD_ADDR 1 -+#define CMD_LISTEN 2 -+#define CMD_OPT 4 -+ -+static inline unsigned int match_to_cmd(struct aa_profile *profile, -+ unsigned int state, struct unix_sock *u, -+ char cmd, const char **info) -+{ -+ state = match_to_sk(profile, state, u, info); -+ if (state) { -+ state = aa_dfa_match_len(profile->policy.dfa, state, &cmd, 1); -+ if (!state) -+ *info = "failed cmd selection match"; -+ } -+ -+ return state; -+} -+ -+static inline unsigned int match_to_peer(struct aa_profile *profile, -+ unsigned int state, -+ struct unix_sock *u, -+ struct sockaddr_un *peer_addr, -+ int peer_addrlen, -+ const char **info) -+{ -+ state = match_to_cmd(profile, state, u, CMD_ADDR, info); -+ if (state) { -+ state = match_addr(profile, state, peer_addr, peer_addrlen); -+ if (!state) -+ *info = "failed peer address match"; -+ } -+ return state; -+} -+ -+static int do_perms(struct aa_profile *profile, unsigned int state, u32 request, -+ struct common_audit_data *sa) -+{ -+ struct aa_perms perms; -+ -+ AA_BUG(!profile); -+ -+ aa_compute_perms(profile->policy.dfa, state, &perms); -+ aa_apply_modes_to_perms(profile, &perms); -+ return aa_check_perms(profile, &perms, request, sa, -+ audit_net_cb); -+} -+ -+static int match_label(struct aa_profile *profile, struct aa_profile *peer, -+ unsigned int state, u32 request, -+ struct common_audit_data *sa) -+{ -+ AA_BUG(!profile); -+ AA_BUG(!peer); -+ -+ aad(sa)->peer = &peer->label; -+ -+ if (state) { -+ state = aa_dfa_match(profile->policy.dfa, state, -+ peer->base.hname); -+ if (!state) -+ aad(sa)->info = "failed peer label match"; -+ } -+ return do_perms(profile, state, request, sa); -+} -+ -+ -+/* unix sock creation comes before we know if the socket will be an fs -+ * socket -+ * v6 - semantics are handled by mapping in profile load -+ * v7 - semantics require sock create for tasks creating an fs socket. -+ */ -+static int profile_create_perm(struct aa_profile *profile, int family, -+ int type, int protocol) -+{ -+ unsigned int state; -+ DEFINE_AUDIT_NET(sa, OP_CREATE, NULL, family, type, protocol); -+ -+ AA_BUG(!profile); -+ AA_BUG(profile_unconfined(profile)); -+ -+ if ((state = PROFILE_MEDIATES_AF(profile, AF_UNIX))) { -+ state = match_to_prot(profile, state, type, protocol, -+ &aad(&sa)->info); -+ return do_perms(profile, state, AA_MAY_CREATE, &sa); -+ } -+ -+ return aa_profile_af_perm(profile, &sa, AA_MAY_CREATE, family, type); -+} -+ -+int aa_unix_create_perm(struct aa_label *label, int family, int type, -+ int protocol) -+{ -+ struct aa_profile *profile; -+ -+ if (unconfined(label)) -+ return 0; -+ -+ return fn_for_each_confined(label, profile, -+ profile_create_perm(profile, family, type, protocol)); -+} -+ -+ -+static inline int profile_sk_perm(struct aa_profile *profile, const char *op, -+ u32 request, struct sock *sk) -+{ -+ unsigned int state; -+ DEFINE_AUDIT_SK(sa, op, sk); -+ -+ AA_BUG(!profile); -+ AA_BUG(!sk); -+ AA_BUG(UNIX_FS(sk)); -+ AA_BUG(profile_unconfined(profile)); -+ -+ state = PROFILE_MEDIATES_AF(profile, AF_UNIX); -+ if (state) { -+ state = match_to_sk(profile, state, unix_sk(sk), -+ &aad(&sa)->info); -+ return do_perms(profile, state, request, &sa); -+ } -+ -+ return aa_profile_af_sk_perm(profile, &sa, request, sk); -+} -+ -+int aa_unix_label_sk_perm(struct aa_label *label, const char *op, u32 request, -+ struct sock *sk) -+{ -+ struct aa_profile *profile; -+ -+ return fn_for_each_confined(label, profile, -+ profile_sk_perm(profile, op, request, sk)); -+} -+ -+static int unix_label_sock_perm(struct aa_label *label, const char *op, u32 request, -+ struct socket *sock) -+{ -+ if (unconfined(label)) -+ return 0; -+ if (UNIX_FS(sock->sk)) -+ return unix_fs_perm(op, request, label, unix_sk(sock->sk), 0); -+ -+ return aa_unix_label_sk_perm(label, op, request, sock->sk); -+} -+ -+/* revaliation, get/set attr */ -+int aa_unix_sock_perm(const char *op, u32 request, struct socket *sock) -+{ -+ struct aa_label *label; -+ int error; -+ -+ label = begin_current_label_crit_section(); -+ error = unix_label_sock_perm(label, op, request, sock); -+ end_current_label_crit_section(label); -+ -+ return error; -+} -+ -+static int profile_bind_perm(struct aa_profile *profile, struct sock *sk, -+ struct sockaddr *addr, int addrlen) -+{ -+ unsigned int state; -+ DEFINE_AUDIT_SK(sa, OP_BIND, sk); -+ -+ AA_BUG(!profile); -+ AA_BUG(!sk); -+ AA_BUG(addr->sa_family != AF_UNIX); -+ AA_BUG(profile_unconfined(profile)); -+ AA_BUG(unix_addr_fs(addr, addrlen)); -+ -+ state = PROFILE_MEDIATES_AF(profile, AF_UNIX); -+ if (state) { -+ /* bind for abstract socket */ -+ aad(&sa)->net.addr = unix_addr(addr); -+ aad(&sa)->net.addrlen = addrlen; -+ -+ state = match_to_local(profile, state, -+ sk->sk_type, sk->sk_protocol, -+ unix_addr(addr), addrlen, -+ &aad(&sa)->info); -+ return do_perms(profile, state, AA_MAY_BIND, &sa); -+ } -+ -+ return aa_profile_af_sk_perm(profile, &sa, AA_MAY_BIND, sk); -+} -+ -+int aa_unix_bind_perm(struct socket *sock, struct sockaddr *address, -+ int addrlen) -+{ -+ struct aa_profile *profile; -+ struct aa_label *label; -+ int error = 0; -+ -+ label = begin_current_label_crit_section(); -+ /* fs bind is handled by mknod */ -+ if (!(unconfined(label) || unix_addr_fs(address, addrlen))) -+ error = fn_for_each_confined(label, profile, -+ profile_bind_perm(profile, sock->sk, address, -+ addrlen)); -+ end_current_label_crit_section(label); -+ -+ return error; -+} -+ -+int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address, -+ int addrlen) -+{ -+ /* unix connections are covered by the -+ * - unix_stream_connect (stream) and unix_may_send hooks (dgram) -+ * - fs connect is handled by open -+ */ -+ return 0; -+} -+ -+static int profile_listen_perm(struct aa_profile *profile, struct sock *sk, -+ int backlog) -+{ -+ unsigned int state; -+ DEFINE_AUDIT_SK(sa, OP_LISTEN, sk); -+ -+ AA_BUG(!profile); -+ AA_BUG(!sk); -+ AA_BUG(UNIX_FS(sk)); -+ AA_BUG(profile_unconfined(profile)); -+ -+ state = PROFILE_MEDIATES_AF(profile, AF_UNIX); -+ if (state) { -+ __be16 b = cpu_to_be16(backlog); -+ -+ state = match_to_cmd(profile, state, unix_sk(sk), CMD_LISTEN, -+ &aad(&sa)->info); -+ if (state) { -+ state = aa_dfa_match_len(profile->policy.dfa, state, -+ (char *) &b, 2); -+ if (!state) -+ aad(&sa)->info = "failed listen backlog match"; -+ } -+ return do_perms(profile, state, AA_MAY_LISTEN, &sa); -+ } -+ -+ return aa_profile_af_sk_perm(profile, &sa, AA_MAY_LISTEN, sk); -+} -+ -+int aa_unix_listen_perm(struct socket *sock, int backlog) -+{ -+ struct aa_profile *profile; -+ struct aa_label *label; -+ int error = 0; -+ -+ label = begin_current_label_crit_section(); -+ if (!(unconfined(label) || UNIX_FS(sock->sk))) -+ error = fn_for_each_confined(label, profile, -+ profile_listen_perm(profile, sock->sk, -+ backlog)); -+ end_current_label_crit_section(label); -+ -+ return error; -+} -+ -+ -+static inline int profile_accept_perm(struct aa_profile *profile, -+ struct sock *sk, -+ struct sock *newsk) -+{ -+ unsigned int state; -+ DEFINE_AUDIT_SK(sa, OP_ACCEPT, sk); -+ -+ AA_BUG(!profile); -+ AA_BUG(!sk); -+ AA_BUG(UNIX_FS(sk)); -+ AA_BUG(profile_unconfined(profile)); -+ -+ state = PROFILE_MEDIATES_AF(profile, AF_UNIX); -+ if (state) { -+ state = match_to_sk(profile, state, unix_sk(sk), -+ &aad(&sa)->info); -+ return do_perms(profile, state, AA_MAY_ACCEPT, &sa); -+ } -+ -+ return aa_profile_af_sk_perm(profile, &sa, AA_MAY_ACCEPT, sk); -+} -+ -+/* ability of sock to connect, not peer address binding */ -+int aa_unix_accept_perm(struct socket *sock, struct socket *newsock) -+{ -+ struct aa_profile *profile; -+ struct aa_label *label; -+ int error = 0; -+ -+ label = begin_current_label_crit_section(); -+ if (!(unconfined(label) || UNIX_FS(sock->sk))) -+ error = fn_for_each_confined(label, profile, -+ profile_accept_perm(profile, sock->sk, -+ newsock->sk)); -+ end_current_label_crit_section(label); -+ -+ return error; -+} -+ -+ -+/* dgram handled by unix_may_sendmsg, right to send on stream done at connect -+ * could do per msg unix_stream here -+ */ -+/* sendmsg, recvmsg */ -+int aa_unix_msg_perm(const char *op, u32 request, struct socket *sock, -+ struct msghdr *msg, int size) -+{ -+ return 0; -+} -+ -+ -+static int profile_opt_perm(struct aa_profile *profile, const char *op, u32 request, -+ struct sock *sk, int level, int optname) -+{ -+ unsigned int state; -+ DEFINE_AUDIT_SK(sa, op, sk); -+ -+ AA_BUG(!profile); -+ AA_BUG(!sk); -+ AA_BUG(UNIX_FS(sk)); -+ AA_BUG(profile_unconfined(profile)); -+ -+ state = PROFILE_MEDIATES_AF(profile, AF_UNIX); -+ if (state) { -+ __be16 b = cpu_to_be16(optname); -+ -+ state = match_to_cmd(profile, state, unix_sk(sk), CMD_OPT, -+ &aad(&sa)->info); -+ if (state) { -+ state = aa_dfa_match_len(profile->policy.dfa, state, -+ (char *) &b, 2); -+ if (!state) -+ aad(&sa)->info = "failed sockopt match"; -+ } -+ return do_perms(profile, state, request, &sa); -+ } -+ -+ return aa_profile_af_sk_perm(profile, &sa, request, sk); -+} -+ -+int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock, int level, -+ int optname) -+{ -+ struct aa_profile *profile; -+ struct aa_label *label; -+ int error = 0; -+ -+ label = begin_current_label_crit_section(); -+ if (!(unconfined(label) || UNIX_FS(sock->sk))) -+ error = fn_for_each_confined(label, profile, -+ profile_opt_perm(profile, op, request, -+ sock->sk, level, optname)); -+ end_current_label_crit_section(label); -+ -+ return error; -+} -+ -+/* null peer_label is allowed, in which case the peer_sk label is used */ -+static int profile_peer_perm(struct aa_profile *profile, const char *op, u32 request, -+ struct sock *sk, struct sock *peer_sk, -+ struct aa_label *peer_label, -+ struct common_audit_data *sa) -+{ -+ unsigned int state; -+ -+ AA_BUG(!profile); -+ AA_BUG(profile_unconfined(profile)); -+ AA_BUG(!sk); -+ AA_BUG(!peer_sk); -+ AA_BUG(UNIX_FS(peer_sk)); -+ -+ state = PROFILE_MEDIATES_AF(profile, AF_UNIX); -+ if (state) { -+ struct aa_sk_ctx *peer_ctx = SK_CTX(peer_sk); -+ struct aa_profile *peerp; -+ struct sockaddr_un *addr = NULL; -+ int len = 0; -+ if (unix_sk(peer_sk)->addr) { -+ addr = unix_sk(peer_sk)->addr->name; -+ len = unix_sk(peer_sk)->addr->len; -+ } -+ state = match_to_peer(profile, state, unix_sk(sk), -+ addr, len, &aad(sa)->info); -+ if (!peer_label) -+ peer_label = peer_ctx->label; -+ return fn_for_each_in_ns(peer_label, peerp, -+ match_label(profile, peerp, state, request, -+ sa)); -+ } -+ -+ return aa_profile_af_sk_perm(profile, sa, request, sk); -+} -+ -+/** -+ * -+ * Requires: lock held on both @sk and @peer_sk -+ */ -+int aa_unix_peer_perm(struct aa_label *label, const char *op, u32 request, -+ struct sock *sk, struct sock *peer_sk, -+ struct aa_label *peer_label) -+{ -+ struct unix_sock *peeru = unix_sk(peer_sk); -+ struct unix_sock *u = unix_sk(sk); -+ -+ AA_BUG(!label); -+ AA_BUG(!sk); -+ AA_BUG(!peer_sk); -+ -+ if (UNIX_FS(aa_sock(peeru))) -+ return unix_fs_perm(op, request, label, peeru, 0); -+ else if (UNIX_FS(aa_sock(u))) -+ return unix_fs_perm(op, request, label, u, 0); -+ else { -+ struct aa_profile *profile; -+ DEFINE_AUDIT_SK(sa, op, sk); -+ aad(&sa)->net.peer_sk = peer_sk; -+ -+ /* TODO: ns!!! */ -+ if (!net_eq(sock_net(sk), sock_net(peer_sk))) { -+ ; -+ } -+ -+ if (unconfined(label)) -+ return 0; -+ -+ return fn_for_each_confined(label, profile, -+ profile_peer_perm(profile, op, request, sk, -+ peer_sk, peer_label, &sa)); -+ } -+} -+ -+ -+/* from net/unix/af_unix.c */ -+static void unix_state_double_lock(struct sock *sk1, struct sock *sk2) -+{ -+ if (unlikely(sk1 == sk2) || !sk2) { -+ unix_state_lock(sk1); -+ return; -+ } -+ if (sk1 < sk2) { -+ unix_state_lock(sk1); -+ unix_state_lock_nested(sk2); -+ } else { -+ unix_state_lock(sk2); -+ unix_state_lock_nested(sk1); -+ } -+} -+ -+static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2) -+{ -+ if (unlikely(sk1 == sk2) || !sk2) { -+ unix_state_unlock(sk1); -+ return; -+ } -+ unix_state_unlock(sk1); -+ unix_state_unlock(sk2); -+} -+ -+int aa_unix_file_perm(struct aa_label *label, const char *op, u32 request, -+ struct socket *sock) -+{ -+ struct sock *peer_sk = NULL; -+ u32 sk_req = request & ~NET_PEER_MASK; -+ int error = 0; -+ -+ AA_BUG(!label); -+ AA_BUG(!sock); -+ AA_BUG(!sock->sk); -+ AA_BUG(sock->sk->sk_family != AF_UNIX); -+ -+ /* TODO: update sock label with new task label */ -+ unix_state_lock(sock->sk); -+ peer_sk = unix_peer(sock->sk); -+ if (peer_sk) -+ sock_hold(peer_sk); -+ if (!unix_connected(sock) && sk_req) { -+ error = unix_label_sock_perm(label, op, sk_req, sock); -+ if (!error) { -+ // update label -+ } -+ } -+ unix_state_unlock(sock->sk); -+ if (!peer_sk) -+ return error; -+ -+ unix_state_double_lock(sock->sk, peer_sk); -+ if (UNIX_FS(sock->sk)) { -+ error = unix_fs_perm(op, request, label, unix_sk(sock->sk), -+ PATH_SOCK_COND); -+ } else if (UNIX_FS(peer_sk)) { -+ error = unix_fs_perm(op, request, label, unix_sk(peer_sk), -+ PATH_SOCK_COND); -+ } else { -+ struct aa_sk_ctx *pctx = SK_CTX(peer_sk); -+ if (sk_req) -+ error = aa_unix_label_sk_perm(label, op, sk_req, -+ sock->sk); -+ last_error(error, -+ xcheck(aa_unix_peer_perm(label, op, -+ MAY_READ | MAY_WRITE, -+ sock->sk, peer_sk, NULL), -+ aa_unix_peer_perm(pctx->label, op, -+ MAY_READ | MAY_WRITE, -+ peer_sk, sock->sk, label))); -+ } -+ -+ unix_state_double_unlock(sock->sk, peer_sk); -+ sock_put(peer_sk); -+ -+ return error; -+} -diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c -index 694c4f48a975..850c401502f1 100644 ---- a/security/apparmor/apparmorfs.c -+++ b/security/apparmor/apparmorfs.c -@@ -2187,6 +2187,11 @@ static struct aa_sfs_entry aa_sfs_entry_ns[] = { - { } - }; - -+static struct aa_sfs_entry aa_sfs_entry_dbus[] = { -+ AA_SFS_FILE_STRING("mask", "acquire send receive"), -+ { } -+}; -+ - static struct aa_sfs_entry aa_sfs_entry_query_label[] = { - AA_SFS_FILE_STRING("perms", "allow deny audit quiet"), - AA_SFS_FILE_BOOLEAN("data", 1), -@@ -2210,6 +2215,7 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = { - AA_SFS_DIR("caps", aa_sfs_entry_caps), - AA_SFS_DIR("ptrace", aa_sfs_entry_ptrace), - AA_SFS_DIR("signal", aa_sfs_entry_signal), -+ AA_SFS_DIR("dbus", aa_sfs_entry_dbus), - AA_SFS_DIR("query", aa_sfs_entry_query), - { } - }; -diff --git a/security/apparmor/file.c b/security/apparmor/file.c -index 86d57e56fabe..348c9ff3da4e 100644 ---- a/security/apparmor/file.c -+++ b/security/apparmor/file.c -@@ -16,6 +16,7 @@ - #include <linux/fdtable.h> - #include <linux/file.h> - -+#include "include/af_unix.h" - #include "include/apparmor.h" - #include "include/audit.h" - #include "include/context.h" -@@ -283,7 +284,8 @@ int __aa_path_perm(const char *op, struct aa_profile *profile, const char *name, - { - int e = 0; - -- if (profile_unconfined(profile)) -+ if (profile_unconfined(profile) || -+ ((flags & PATH_SOCK_COND) && !PROFILE_MEDIATES_AF(profile, AF_UNIX))) - return 0; - aa_str_perms(profile->file.dfa, profile->file.start, name, cond, perms); - if (request & ~perms->allow) -diff --git a/security/apparmor/include/af_unix.h b/security/apparmor/include/af_unix.h -new file mode 100644 -index 000000000000..d1b7f2316be4 ---- /dev/null -+++ b/security/apparmor/include/af_unix.h -@@ -0,0 +1,114 @@ -+/* -+ * AppArmor security module -+ * -+ * This file contains AppArmor af_unix fine grained mediation -+ * -+ * Copyright 2014 Canonical Ltd. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation, version 2 of the -+ * License. -+ */ -+#ifndef __AA_AF_UNIX_H -+ -+#include <net/af_unix.h> -+ -+#include "label.h" -+//#include "include/net.h" -+ -+#define unix_addr_len(L) ((L) - sizeof(sa_family_t)) -+#define unix_abstract_name_len(L) (unix_addr_len(L) - 1) -+#define unix_abstract_len(U) (unix_abstract_name_len((U)->addr->len)) -+#define addr_unix_abstract_name(B) ((B)[0] == 0) -+#define addr_unix_anonymous(U) (addr_unix_len(U) <= 0) -+#define addr_unix_abstract(U) (!addr_unix_anonymous(U) && addr_unix_abstract_name((U)->addr)) -+//#define unix_addr_fs(U) (!unix_addr_anonymous(U) && !unix_addr_abstract_name((U)->addr)) -+ -+#define unix_addr(A) ((struct sockaddr_un *)(A)) -+#define unix_addr_anon(A, L) ((A) && unix_addr_len(L) <= 0) -+#define unix_addr_fs(A, L) (!unix_addr_anon(A, L) && !addr_unix_abstract_name(unix_addr(A)->sun_path)) -+ -+#define UNIX_ANONYMOUS(U) (!unix_sk(U)->addr) -+/* from net/unix/af_unix.c */ -+#define UNIX_ABSTRACT(U) (!UNIX_ANONYMOUS(U) && \ -+ unix_sk(U)->addr->hash < UNIX_HASH_SIZE) -+#define UNIX_FS(U) (!UNIX_ANONYMOUS(U) && unix_sk(U)->addr->name->sun_path[0]) -+#define unix_peer(sk) (unix_sk(sk)->peer) -+#define unix_connected(S) ((S)->state == SS_CONNECTED) -+ -+static inline void print_unix_addr(struct sockaddr_un *A, int L) -+{ -+ char *buf = (A) ? (char *) &(A)->sun_path : NULL; -+ int len = unix_addr_len(L); -+ if (!buf || len <= 0) -+ printk(" <anonymous>"); -+ else if (buf[0]) -+ printk(" %s", buf); -+ else -+ /* abstract name len includes leading \0 */ -+ printk(" %d @%.*s", len - 1, len - 1, buf+1); -+}; -+ -+/* -+ printk("%s: %s: f %d, t %d, p %d", __FUNCTION__, \ -+ #SK , \ -+*/ -+#define print_unix_sk(SK) \ -+do { \ -+ struct unix_sock *u = unix_sk(SK); \ -+ printk("%s: f %d, t %d, p %d", #SK , \ -+ (SK)->sk_family, (SK)->sk_type, (SK)->sk_protocol); \ -+ if (u->addr) \ -+ print_unix_addr(u->addr->name, u->addr->len); \ -+ else \ -+ print_unix_addr(NULL, sizeof(sa_family_t)); \ -+ /* printk("\n");*/ \ -+} while (0) -+ -+#define print_sk(SK) \ -+do { \ -+ if (!(SK)) { \ -+ printk("%s: %s is null\n", __FUNCTION__, #SK); \ -+ } else if ((SK)->sk_family == PF_UNIX) { \ -+ print_unix_sk(SK); \ -+ printk("\n"); \ -+ } else { \ -+ printk("%s: %s: family %d\n", __FUNCTION__, #SK , \ -+ (SK)->sk_family); \ -+ } \ -+} while (0) -+ -+#define print_sock_addr(U) \ -+do { \ -+ printk("%s:\n", __FUNCTION__); \ -+ printk(" sock %s:", sock_ctx && sock_ctx->label ? aa_label_printk(sock_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(sock); \ -+ printk(" other %s:", other_ctx && other_ctx->label ? aa_label_printk(other_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(other); \ -+ printk(" new %s", new_ctx && new_ctx->label ? aa_label_printk(new_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(newsk); \ -+} while (0) -+ -+ -+ -+ -+int aa_unix_peer_perm(struct aa_label *label, const char *op, u32 request, -+ struct sock *sk, struct sock *peer_sk, -+ struct aa_label *peer_label); -+int aa_unix_label_sk_perm(struct aa_label *label, const char *op, u32 request, -+ struct sock *sk); -+int aa_unix_sock_perm(const char *op, u32 request, struct socket *sock); -+int aa_unix_create_perm(struct aa_label *label, int family, int type, -+ int protocol); -+int aa_unix_bind_perm(struct socket *sock, struct sockaddr *address, -+ int addrlen); -+int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address, -+ int addrlen); -+int aa_unix_listen_perm(struct socket *sock, int backlog); -+int aa_unix_accept_perm(struct socket *sock, struct socket *newsock); -+int aa_unix_msg_perm(const char *op, u32 request, struct socket *sock, -+ struct msghdr *msg, int size); -+int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock, int level, -+ int optname); -+int aa_unix_file_perm(struct aa_label *label, const char *op, u32 request, -+ struct socket *sock); -+ -+#endif /* __AA_AF_UNIX_H */ -diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h -index 140c8efcf364..0ae45240c352 100644 ---- a/security/apparmor/include/net.h -+++ b/security/apparmor/include/net.h -@@ -90,8 +90,6 @@ extern struct aa_sfs_entry aa_sfs_entry_network[]; - void audit_net_cb(struct audit_buffer *ab, void *va); - int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa, - u32 request, u16 family, int type); --int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family, -- int type, int protocol); - static inline int aa_profile_af_sk_perm(struct aa_profile *profile, - struct common_audit_data *sa, - u32 request, -@@ -100,8 +98,20 @@ static inline int aa_profile_af_sk_perm(struct aa_profile *profile, - return aa_profile_af_perm(profile, sa, request, sk->sk_family, - sk->sk_type); - } --int aa_sk_perm(const char *op, u32 request, struct sock *sk); - -+int aa_sock_perm(const char *op, u32 request, struct socket *sock); -+int aa_sock_create_perm(struct aa_label *label, int family, int type, -+ int protocol); -+int aa_sock_bind_perm(struct socket *sock, struct sockaddr *address, -+ int addrlen); -+int aa_sock_connect_perm(struct socket *sock, struct sockaddr *address, -+ int addrlen); -+int aa_sock_listen_perm(struct socket *sock, int backlog); -+int aa_sock_accept_perm(struct socket *sock, struct socket *newsock); -+int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock, -+ struct msghdr *msg, int size); -+int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock, int level, -+ int optname); - int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, - struct socket *sock); - -diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h -index 05fb3305671e..26762db2207d 100644 ---- a/security/apparmor/include/path.h -+++ b/security/apparmor/include/path.h -@@ -18,6 +18,7 @@ - - enum path_flags { - PATH_IS_DIR = 0x1, /* path is a directory */ -+ PATH_SOCK_COND = 0x2, - PATH_CONNECT_PATH = 0x4, /* connect disconnected paths to / */ - PATH_CHROOT_REL = 0x8, /* do path lookup relative to chroot */ - PATH_CHROOT_NSCONNECT = 0x10, /* connect paths that are at ns root */ -diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c -index 0cd717614fd0..245c98ef311e 100644 ---- a/security/apparmor/lsm.c -+++ b/security/apparmor/lsm.c -@@ -26,6 +26,7 @@ - #include <linux/kmemleak.h> - #include <net/sock.h> - -+#include "include/af_unix.h" - #include "include/apparmor.h" - #include "include/apparmorfs.h" - #include "include/audit.h" -@@ -782,16 +783,96 @@ static void apparmor_sk_clone_security(const struct sock *sk, - path_get(&new->path); - } - --static int aa_sock_create_perm(struct aa_label *label, int family, int type, -- int protocol) -+static struct path *UNIX_FS_CONN_PATH(struct sock *sk, struct sock *newsk) - { -- AA_BUG(!label); -- AA_BUG(in_interrupt()); -+ if (sk->sk_family == PF_UNIX && UNIX_FS(sk)) -+ return &unix_sk(sk)->path; -+ else if (newsk->sk_family == PF_UNIX && UNIX_FS(newsk)) -+ return &unix_sk(newsk)->path; -+ return NULL; -+} -+ -+/** -+ * apparmor_unix_stream_connect - check perms before making unix domain conn -+ * -+ * peer is locked when this hook is called -+ */ -+static int apparmor_unix_stream_connect(struct sock *sk, struct sock *peer_sk, -+ struct sock *newsk) -+{ -+ struct aa_sk_ctx *sk_ctx = SK_CTX(sk); -+ struct aa_sk_ctx *peer_ctx = SK_CTX(peer_sk); -+ struct aa_sk_ctx *new_ctx = SK_CTX(newsk); -+ struct aa_label *label; -+ struct path *path; -+ int error; - -- return aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family, type, -- protocol); -+ label = __begin_current_label_crit_section(); -+ error = aa_unix_peer_perm(label, OP_CONNECT, -+ (AA_MAY_CONNECT | AA_MAY_SEND | AA_MAY_RECEIVE), -+ sk, peer_sk, NULL); -+ if (!UNIX_FS(peer_sk)) { -+ last_error(error, -+ aa_unix_peer_perm(peer_ctx->label, OP_CONNECT, -+ (AA_MAY_ACCEPT | AA_MAY_SEND | AA_MAY_RECEIVE), -+ peer_sk, sk, label)); -+ } -+ __end_current_label_crit_section(label); -+ -+ if (error) -+ return error; -+ -+ /* label newsk if it wasn't labeled in post_create. Normally this -+ * would be done in sock_graft, but because we are directly looking -+ * at the peer_sk to obtain peer_labeling for unix socks this -+ * does not work -+ */ -+ if (!new_ctx->label) -+ new_ctx->label = aa_get_label(peer_ctx->label); -+ -+ /* Cross reference the peer labels for SO_PEERSEC */ -+ if (new_ctx->peer) -+ aa_put_label(new_ctx->peer); -+ -+ if (sk_ctx->peer) -+ aa_put_label(sk_ctx->peer); -+ -+ new_ctx->peer = aa_get_label(sk_ctx->label); -+ sk_ctx->peer = aa_get_label(peer_ctx->label); -+ -+ path = UNIX_FS_CONN_PATH(sk, peer_sk); -+ if (path) { -+ new_ctx->path = *path; -+ sk_ctx->path = *path; -+ path_get(path); -+ path_get(path); -+ } -+ return 0; - } - -+/** -+ * apparmor_unix_may_send - check perms before conn or sending unix dgrams -+ * -+ * other is locked when this hook is called -+ * -+ * dgram connect calls may_send, peer setup but path not copied????? -+ */ -+static int apparmor_unix_may_send(struct socket *sock, struct socket *peer) -+{ -+ struct aa_sk_ctx *peer_ctx = SK_CTX(peer->sk); -+ struct aa_label *label; -+ int error; -+ -+ label = __begin_current_label_crit_section(); -+ error = xcheck(aa_unix_peer_perm(label, OP_SENDMSG, AA_MAY_SEND, -+ sock->sk, peer->sk, NULL), -+ aa_unix_peer_perm(peer_ctx->label, OP_SENDMSG, -+ AA_MAY_RECEIVE, -+ peer->sk, sock->sk, label)); -+ __end_current_label_crit_section(label); -+ -+ return error; -+} - - /** - * apparmor_socket_create - check perms before creating a new socket -@@ -849,12 +930,7 @@ static int apparmor_socket_post_create(struct socket *sock, int family, - static int apparmor_socket_bind(struct socket *sock, - struct sockaddr *address, int addrlen) - { -- AA_BUG(!sock); -- AA_BUG(!sock->sk); -- AA_BUG(!address); -- AA_BUG(in_interrupt()); -- -- return aa_sk_perm(OP_BIND, AA_MAY_BIND, sock->sk); -+ return aa_sock_bind_perm(sock, address, addrlen); - } - - /** -@@ -863,12 +939,7 @@ static int apparmor_socket_bind(struct socket *sock, - static int apparmor_socket_connect(struct socket *sock, - struct sockaddr *address, int addrlen) - { -- AA_BUG(!sock); -- AA_BUG(!sock->sk); -- AA_BUG(!address); -- AA_BUG(in_interrupt()); -- -- return aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk); -+ return aa_sock_connect_perm(sock, address, addrlen); - } - - /** -@@ -876,11 +947,7 @@ static int apparmor_socket_connect(struct socket *sock, - */ - static int apparmor_socket_listen(struct socket *sock, int backlog) - { -- AA_BUG(!sock); -- AA_BUG(!sock->sk); -- AA_BUG(in_interrupt()); -- -- return aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk); -+ return aa_sock_listen_perm(sock, backlog); - } - - /** -@@ -891,23 +958,7 @@ static int apparmor_socket_listen(struct socket *sock, int backlog) - */ - static int apparmor_socket_accept(struct socket *sock, struct socket *newsock) - { -- AA_BUG(!sock); -- AA_BUG(!sock->sk); -- AA_BUG(!newsock); -- AA_BUG(in_interrupt()); -- -- return aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk); --} -- --static int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock, -- struct msghdr *msg, int size) --{ -- AA_BUG(!sock); -- AA_BUG(!sock->sk); -- AA_BUG(!msg); -- AA_BUG(in_interrupt()); -- -- return aa_sk_perm(op, request, sock->sk); -+ return aa_sock_accept_perm(sock, newsock); - } - - /** -@@ -928,16 +979,6 @@ static int apparmor_socket_recvmsg(struct socket *sock, - return aa_sock_msg_perm(OP_RECVMSG, AA_MAY_RECEIVE, sock, msg, size); - } - --/* revaliation, get/set attr, shutdown */ --static int aa_sock_perm(const char *op, u32 request, struct socket *sock) --{ -- AA_BUG(!sock); -- AA_BUG(!sock->sk); -- AA_BUG(in_interrupt()); -- -- return aa_sk_perm(op, request, sock->sk); --} -- - /** - * apparmor_socket_getsockname - check perms before getting the local address - */ -@@ -954,17 +995,6 @@ static int apparmor_socket_getpeername(struct socket *sock) - return aa_sock_perm(OP_GETPEERNAME, AA_MAY_GETATTR, sock); - } - --/* revaliation, get/set attr, opt */ --static int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock, -- int level, int optname) --{ -- AA_BUG(!sock); -- AA_BUG(!sock->sk); -- AA_BUG(in_interrupt()); -- -- return aa_sk_perm(op, request, sock->sk); --} -- - /** - * apparmor_getsockopt - check perms before getting socket options - */ -@@ -1009,11 +1039,25 @@ static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) - - static struct aa_label *sk_peer_label(struct sock *sk) - { -+ struct sock *peer_sk; - struct aa_sk_ctx *ctx = SK_CTX(sk); - - if (ctx->peer) - return ctx->peer; - -+ if (sk->sk_family != PF_UNIX) -+ return ERR_PTR(-ENOPROTOOPT); -+ -+ /* check for sockpair peering which does not go through -+ * security_unix_stream_connect -+ */ -+ peer_sk = unix_peer(sk); -+ if (peer_sk) { -+ ctx = SK_CTX(peer_sk); -+ if (ctx->label) -+ return ctx->label; -+ } -+ - return ERR_PTR(-ENOPROTOOPT); - } - -@@ -1137,6 +1181,9 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { - LSM_HOOK_INIT(sk_free_security, apparmor_sk_free_security), - LSM_HOOK_INIT(sk_clone_security, apparmor_sk_clone_security), - -+ LSM_HOOK_INIT(unix_stream_connect, apparmor_unix_stream_connect), -+ LSM_HOOK_INIT(unix_may_send, apparmor_unix_may_send), -+ - LSM_HOOK_INIT(socket_create, apparmor_socket_create), - LSM_HOOK_INIT(socket_post_create, apparmor_socket_post_create), - LSM_HOOK_INIT(socket_bind, apparmor_socket_bind), -diff --git a/security/apparmor/net.c b/security/apparmor/net.c -index 33d54435f8d6..dd1953b08e58 100644 ---- a/security/apparmor/net.c -+++ b/security/apparmor/net.c -@@ -12,6 +12,7 @@ - * License. - */ - -+#include "include/af_unix.h" - #include "include/apparmor.h" - #include "include/audit.h" - #include "include/context.h" -@@ -24,6 +25,7 @@ - - struct aa_sfs_entry aa_sfs_entry_network[] = { - AA_SFS_FILE_STRING("af_mask", AA_SFS_AF_MASK), -+ AA_SFS_FILE_BOOLEAN("af_unix", 1), - { } - }; - -@@ -69,6 +71,36 @@ static const char * const net_mask_names[] = { - "unknown", - }; - -+static void audit_unix_addr(struct audit_buffer *ab, const char *str, -+ struct sockaddr_un *addr, int addrlen) -+{ -+ int len = unix_addr_len(addrlen); -+ -+ if (!addr || len <= 0) { -+ audit_log_format(ab, " %s=none", str); -+ } else if (addr->sun_path[0]) { -+ audit_log_format(ab, " %s=", str); -+ audit_log_untrustedstring(ab, addr->sun_path); -+ } else { -+ audit_log_format(ab, " %s=\"@", str); -+ if (audit_string_contains_control(&addr->sun_path[1], len - 1)) -+ audit_log_n_hex(ab, &addr->sun_path[1], len - 1); -+ else -+ audit_log_format(ab, "%.*s", len - 1, -+ &addr->sun_path[1]); -+ audit_log_format(ab, "\""); -+ } -+} -+ -+static void audit_unix_sk_addr(struct audit_buffer *ab, const char *str, -+ struct sock *sk) -+{ -+ struct unix_sock *u = unix_sk(sk); -+ if (u && u->addr) -+ audit_unix_addr(ab, str, u->addr->name, u->addr->len); -+ else -+ audit_unix_addr(ab, str, NULL, 0); -+} - - /* audit callback for net specific fields */ - void audit_net_cb(struct audit_buffer *ab, void *va) -@@ -98,6 +130,23 @@ void audit_net_cb(struct audit_buffer *ab, void *va) - net_mask_names, NET_PERMS_MASK); - } - } -+ if (sa->u.net->family == AF_UNIX) { -+ if ((aad(sa)->request & ~NET_PEER_MASK) && aad(sa)->net.addr) -+ audit_unix_addr(ab, "addr", -+ unix_addr(aad(sa)->net.addr), -+ aad(sa)->net.addrlen); -+ else -+ audit_unix_sk_addr(ab, "addr", sa->u.net->sk); -+ if (aad(sa)->request & NET_PEER_MASK) { -+ if (aad(sa)->net.addr) -+ audit_unix_addr(ab, "peer_addr", -+ unix_addr(aad(sa)->net.addr), -+ aad(sa)->net.addrlen); -+ else -+ audit_unix_sk_addr(ab, "peer_addr", -+ aad(sa)->net.peer_sk); -+ } -+ } - if (aad(sa)->peer) { - audit_log_format(ab, " peer="); - aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer, -@@ -172,6 +221,127 @@ int aa_sk_perm(const char *op, u32 request, struct sock *sk) - return error; - } - -+#define af_select(FAMILY, FN, DEF_FN) \ -+({ \ -+ int __e; \ -+ switch ((FAMILY)) { \ -+ case AF_UNIX: \ -+ __e = aa_unix_ ## FN; \ -+ break; \ -+ default: \ -+ __e = DEF_FN; \ -+ } \ -+ __e; \ -+}) -+ -+/* TODO: push into lsm.c ???? */ -+ -+/* revaliation, get/set attr, shutdown */ -+int aa_sock_perm(const char *op, u32 request, struct socket *sock) -+{ -+ AA_BUG(!sock); -+ AA_BUG(!sock->sk); -+ AA_BUG(in_interrupt()); -+ -+ return af_select(sock->sk->sk_family, -+ sock_perm(op, request, sock), -+ aa_sk_perm(op, request, sock->sk)); -+} -+ -+int aa_sock_create_perm(struct aa_label *label, int family, int type, -+ int protocol) -+{ -+ AA_BUG(!label); -+ /* TODO: .... */ -+ AA_BUG(in_interrupt()); -+ -+ return af_select(family, -+ create_perm(label, family, type, protocol), -+ aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family, -+ type, protocol)); -+} -+ -+int aa_sock_bind_perm(struct socket *sock, struct sockaddr *address, -+ int addrlen) -+{ -+ AA_BUG(!sock); -+ AA_BUG(!sock->sk); -+ AA_BUG(!address); -+ /* TODO: .... */ -+ AA_BUG(in_interrupt()); -+ -+ return af_select(sock->sk->sk_family, -+ bind_perm(sock, address, addrlen), -+ aa_sk_perm(OP_BIND, AA_MAY_BIND, sock->sk)); -+} -+ -+int aa_sock_connect_perm(struct socket *sock, struct sockaddr *address, -+ int addrlen) -+{ -+ AA_BUG(!sock); -+ AA_BUG(!sock->sk); -+ AA_BUG(!address); -+ /* TODO: .... */ -+ AA_BUG(in_interrupt()); -+ -+ return af_select(sock->sk->sk_family, -+ connect_perm(sock, address, addrlen), -+ aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk)); -+} -+ -+int aa_sock_listen_perm(struct socket *sock, int backlog) -+{ -+ AA_BUG(!sock); -+ AA_BUG(!sock->sk); -+ /* TODO: .... */ -+ AA_BUG(in_interrupt()); -+ -+ return af_select(sock->sk->sk_family, -+ listen_perm(sock, backlog), -+ aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk)); -+} -+ -+/* ability of sock to connect, not peer address binding */ -+int aa_sock_accept_perm(struct socket *sock, struct socket *newsock) -+{ -+ AA_BUG(!sock); -+ AA_BUG(!sock->sk); -+ AA_BUG(!newsock); -+ /* TODO: .... */ -+ AA_BUG(in_interrupt()); -+ -+ return af_select(sock->sk->sk_family, -+ accept_perm(sock, newsock), -+ aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk)); -+} -+ -+/* sendmsg, recvmsg */ -+int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock, -+ struct msghdr *msg, int size) -+{ -+ AA_BUG(!sock); -+ AA_BUG(!sock->sk); -+ AA_BUG(!msg); -+ /* TODO: .... */ -+ AA_BUG(in_interrupt()); -+ -+ return af_select(sock->sk->sk_family, -+ msg_perm(op, request, sock, msg, size), -+ aa_sk_perm(op, request, sock->sk)); -+} -+ -+/* revaliation, get/set attr, opt */ -+int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock, int level, -+ int optname) -+{ -+ AA_BUG(!sock); -+ AA_BUG(!sock->sk); -+ AA_BUG(in_interrupt()); -+ -+ return af_select(sock->sk->sk_family, -+ opt_perm(op, request, sock, level, optname), -+ aa_sk_perm(op, request, sock->sk)); -+} - - int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, - struct socket *sock) -@@ -180,5 +350,7 @@ int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, - AA_BUG(!sock); - AA_BUG(!sock->sk); - -- return aa_label_sk_perm(label, op, request, sock->sk); -+ return af_select(sock->sk->sk_family, -+ file_perm(label, op, request, sock), -+ aa_label_sk_perm(label, op, request, sock->sk)); - } --- -2.14.1 - diff --git a/kernel-aufs4.patch b/kernel-aufs4.patch index 40d9b916..aa18fc29 100644 --- a/kernel-aufs4.patch +++ b/kernel-aufs4.patch @@ -1,5 +1,5 @@ SPDX-License-Identifier: GPL-2.0 -aufs4.x-rcN kbuild patch +aufs4.17 kbuild patch diff --git a/fs/Kconfig b/fs/Kconfig index bc821a8..7ae814c 100644 @@ -23,13 +23,13 @@ index c9375fd..8af5671 100644 obj-$(CONFIG_EFIVAR_FS) += efivarfs/ +obj-$(CONFIG_AUFS_FS) += aufs/ SPDX-License-Identifier: GPL-2.0 -aufs4.x-rcN base patch +aufs4.17 base patch diff --git a/MAINTAINERS b/MAINTAINERS -index 92be777..138f5e6 100644 +index 9c125f7..4616bbf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -2517,6 +2517,19 @@ F: include/linux/audit.h +@@ -2519,6 +2519,19 @@ F: include/linux/audit.h F: include/uapi/linux/audit.h F: kernel/audit* @@ -50,10 +50,10 @@ index 92be777..138f5e6 100644 M: Miguel Ojeda Sandonis <miguel.ojeda.sando...@gmail.com> W: http://miguelojeda.es/auxdisplay.htm diff --git a/drivers/block/loop.c b/drivers/block/loop.c -index c9d0449..79902c1 100644 +index 55cf554..bc965e5 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c -@@ -691,6 +691,24 @@ static inline int is_loop_device(struct file *file) +@@ -713,6 +713,24 @@ static inline int is_loop_device(struct file *file) return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR; } @@ -79,7 +79,7 @@ index c9d0449..79902c1 100644 static ssize_t loop_attr_show(struct device *dev, char *page, diff --git a/fs/dcache.c b/fs/dcache.c -index 86d2de6..213ddcd 100644 +index 2acfc69..ff338e2 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1234,7 +1234,7 @@ enum d_walk_ret { @@ -114,10 +114,10 @@ index d737ff0..7550799 100644 return error; diff --git a/fs/inode.c b/fs/inode.c -index 13ceb98..68b3b45 100644 +index 3b55391..e0c5255 100644 --- a/fs/inode.c +++ b/fs/inode.c -@@ -1662,7 +1662,7 @@ EXPORT_SYMBOL(generic_update_time); +@@ -1663,7 +1663,7 @@ EXPORT_SYMBOL(generic_update_time); * This does the actual work of updating an inodes time or version. Must have * had called mnt_want_write() before calling this. */ @@ -355,10 +355,10 @@ index 0233863..06e0d7a 100644 #ifdef CONFIG_LOCK_STAT static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], cpu_lock_stats); SPDX-License-Identifier: GPL-2.0 -aufs4.x-rcN mmap patch +aufs4.17 mmap patch diff --git a/fs/proc/base.c b/fs/proc/base.c -index 1b2ede6..dc3fd6d 100644 +index 1a76d75..77f698e 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2024,7 +2024,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path) @@ -428,7 +428,7 @@ index 5b62f57..dfb4a3b 100644 ino = inode->i_ino; pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT; diff --git a/include/linux/mm.h b/include/linux/mm.h -index 1ac1f06..49997d9 100644 +index 02a616e..01b3bb9 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1380,6 +1380,28 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping, @@ -520,10 +520,10 @@ index 0604cb0..45d2369 100644 if (page->mapping != inode->i_mapping) { unlock_page(page); diff --git a/mm/mmap.c b/mm/mmap.c -index 188f195..3c1ca1d 100644 +index fc41c05..e376869 100644 --- a/mm/mmap.c +++ b/mm/mmap.c -@@ -171,7 +171,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) +@@ -180,7 +180,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) if (vma->vm_ops && vma->vm_ops->close) vma->vm_ops->close(vma); if (vma->vm_file) @@ -532,7 +532,7 @@ index 188f195..3c1ca1d 100644 mpol_put(vma_policy(vma)); kmem_cache_free(vm_area_cachep, vma); return next; -@@ -896,7 +896,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, +@@ -905,7 +905,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, if (remove_next) { if (file) { uprobe_munmap(next, next->vm_start, next->vm_end); @@ -541,7 +541,7 @@ index 188f195..3c1ca1d 100644 } if (next->anon_vma) anon_vma_merge(vma, next); -@@ -1779,8 +1779,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr, +@@ -1820,8 +1820,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr, return addr; unmap_and_free_vma: @@ -551,7 +551,7 @@ index 188f195..3c1ca1d 100644 /* Undo any partial mapping done by a device driver. */ unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); -@@ -2604,7 +2604,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2645,7 +2645,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, goto out_free_mpol; if (new->vm_file) @@ -560,7 +560,7 @@ index 188f195..3c1ca1d 100644 if (new->vm_ops && new->vm_ops->open) new->vm_ops->open(new); -@@ -2623,7 +2623,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2664,7 +2664,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, if (new->vm_ops && new->vm_ops->close) new->vm_ops->close(new); if (new->vm_file) @@ -569,7 +569,7 @@ index 188f195..3c1ca1d 100644 unlink_anon_vmas(new); out_free_mpol: mpol_put(vma_policy(new)); -@@ -2785,7 +2785,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, +@@ -2826,7 +2826,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, struct vm_area_struct *vma; unsigned long populate = 0; unsigned long ret = -EINVAL; @@ -578,7 +578,7 @@ index 188f195..3c1ca1d 100644 pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.txt.\n", current->comm, current->pid); -@@ -2860,10 +2860,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, +@@ -2901,10 +2901,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, } } @@ -607,7 +607,7 @@ index 188f195..3c1ca1d 100644 out: up_write(&mm->mmap_sem); if (populate) -@@ -3171,7 +3188,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -3220,7 +3237,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, if (anon_vma_clone(new_vma, vma)) goto out_free_mempol; if (new_vma->vm_file) @@ -753,10 +753,10 @@ index 0000000..14efc4f +} +#endif /* !CONFIG_MMU */ SPDX-License-Identifier: GPL-2.0 -aufs4.x-rcN standalone patch +aufs4.17 standalone patch diff --git a/fs/dcache.c b/fs/dcache.c -index 213ddcd..137176b 100644 +index ff338e2..3e2bae8 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1342,6 +1342,7 @@ void d_walk(struct dentry *parent, void *data, @@ -767,7 +767,7 @@ index 213ddcd..137176b 100644 struct check_mount { struct vfsmount *mnt; -@@ -2920,6 +2921,7 @@ void d_exchange(struct dentry *dentry1, struct dentry *dentry2) +@@ -2942,6 +2943,7 @@ void d_exchange(struct dentry *dentry1, struct dentry *dentry2) write_sequnlock(&rename_lock); } @@ -836,10 +836,10 @@ index 7ec0b3e..819ee07 100644 void __init files_init(void) { diff --git a/fs/inode.c b/fs/inode.c -index 68b3b45..af4551e 100644 +index e0c5255..ff36056 100644 --- a/fs/inode.c +++ b/fs/inode.c -@@ -1671,6 +1671,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags) +@@ -1672,6 +1672,7 @@ int update_time(struct inode *inode, struct timespec *time, int flags) return update_time(inode, time, flags); } @@ -948,7 +948,7 @@ index e9191b4..1f8ccfa 100644 /* * Destroy all marks in destroy_list, waits for SRCU period to finish before diff --git a/fs/open.c b/fs/open.c -index c5ee7cd..86bfe2d 100644 +index d0e955b..527bc1a 100644 --- a/fs/open.c +++ b/fs/open.c @@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, @@ -959,6 +959,14 @@ index c5ee7cd..86bfe2d 100644 long vfs_truncate(const struct path *path, loff_t length) { +@@ -723,6 +724,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group) + { + return ksys_fchown(fd, user, group); + } ++EXPORT_SYMBOL_GPL(open_check_o_direct); + + int open_check_o_direct(struct file *f) + { diff --git a/fs/read_write.c b/fs/read_write.c index ddd6e67..aabf92d 100644 --- a/fs/read_write.c @@ -1061,10 +1069,10 @@ index 0fef395..83fb1ec 100644 } +EXPORT_SYMBOL_GPL(task_work_run); diff --git a/security/commoncap.c b/security/commoncap.c -index 48620c9..4981104 100644 +index 1ce701f..a0d106e 100644 --- a/security/commoncap.c +++ b/security/commoncap.c -@@ -1330,12 +1330,14 @@ int cap_mmap_addr(unsigned long addr) +@@ -1332,12 +1332,14 @@ int cap_mmap_addr(unsigned long addr) } return ret; } @@ -2670,7 +2678,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/design/10dynop.txt lin +regular files only. diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documentation/filesystems/aufs/README --- /usr/share/empty/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100 -+++ linux/Documentation/filesystems/aufs/README 2017-07-29 12:14:25.893041746 +0200 ++++ linux/Documentation/filesystems/aufs/README 2018-06-15 11:15:15.400449109 +0200 @@ -0,0 +1,393 @@ + +Aufs4 -- advanced multi layered unification filesystem version 4.x @@ -3045,7 +3053,7 @@ diff -urN /usr/share/empty/Documentation/filesystems/aufs/README linux/Documenta +James B made a donation (2014/7 and 2015/7). +Stefano Di Biase made a donation (2014/8). +Daniel Epellei made a donation (2015/1). -+OmegaPhil made a donation (2016/1). ++OmegaPhil made a donation (2016/1, 2018/4). +Tomasz Szewczyk made a donation (2016/4). +James Burry made a donation (2016/12). + @@ -32378,8 +32386,8 @@ diff -urN /usr/share/empty/fs/aufs/vdir.c linux/fs/aufs/vdir.c +} diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c --- /usr/share/empty/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/vfsub.c 2018-06-04 09:08:11.628152835 +0200 -@@ -0,0 +1,893 @@ ++++ linux/fs/aufs/vfsub.c 2018-06-15 11:15:15.400449109 +0200 +@@ -0,0 +1,894 @@ +/* + * Copyright (C) 2005-2018 Junjiro R. Okajima + * @@ -32520,6 +32528,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c + + if (!err) { + /* todo: call VFS:may_open() here */ ++ err = open_check_o_direct(file); + /* todo: ima_file_check() too? */ + if (!err && (args->open_flag & __FMODE_EXEC)) + err = deny_write_access(file); @@ -33275,8 +33284,8 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.c linux/fs/aufs/vfsub.c +} diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h --- /usr/share/empty/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/fs/aufs/vfsub.h 2018-06-04 09:08:11.628152835 +0200 -@@ -0,0 +1,353 @@ ++++ linux/fs/aufs/vfsub.h 2018-06-15 11:15:15.400449109 +0200 +@@ -0,0 +1,354 @@ +/* + * Copyright (C) 2005-2018 Junjiro R. Okajima + * @@ -33313,6 +33322,7 @@ diff -urN /usr/share/empty/fs/aufs/vfsub.h linux/fs/aufs/vfsub.h +/* copied from linux/fs/internal.h */ +/* todo: BAD approach!! */ +extern void __mnt_drop_write(struct vfsmount *); ++extern int open_check_o_direct(struct file *f); + +/* ---------------------------------------------------------------------- */ + @@ -37943,7 +37953,7 @@ diff -urN /usr/share/empty/fs/aufs/xino.c linux/fs/aufs/xino.c +} diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/linux/aufs_type.h --- /usr/share/empty/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux/include/uapi/linux/aufs_type.h 2018-06-04 09:08:11.628152835 +0200 ++++ linux/include/uapi/linux/aufs_type.h 2018-06-15 11:15:32.107607516 +0200 @@ -0,0 +1,447 @@ +/* + * Copyright (C) 2005-2018 Junjiro R. Okajima @@ -37986,7 +37996,7 @@ diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/lin + +#include <linux/limits.h> + -+#define AUFS_VERSION "4.x-rcN-20180430" ++#define AUFS_VERSION "4.17-20180611" + +/* todo? move this to linux-2.6.19/include/magic.h */ +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') @@ -38393,13 +38403,13 @@ diff -urN /usr/share/empty/include/uapi/linux/aufs_type.h linux/include/uapi/lin + +#endif /* __AUFS_TYPE_H__ */ SPDX-License-Identifier: GPL-2.0 -aufs4.x-rcN loopback patch +aufs4.17 loopback patch diff --git a/drivers/block/loop.c b/drivers/block/loop.c -index 79902c1..40db6d1 100644 +index bc965e5..852868a 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c -@@ -600,6 +600,15 @@ static inline void loop_update_dio(struct loop_device *lo) +@@ -622,6 +622,15 @@ static inline void loop_update_dio(struct loop_device *lo) lo->use_dio); } @@ -38415,7 +38425,7 @@ index 79902c1..40db6d1 100644 static void loop_reread_partitions(struct loop_device *lo, struct block_device *bdev) { -@@ -634,6 +643,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, +@@ -656,6 +665,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, unsigned int arg) { struct file *file, *old_file; @@ -38423,7 +38433,7 @@ index 79902c1..40db6d1 100644 struct inode *inode; int error; -@@ -650,9 +660,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, +@@ -672,9 +682,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, file = fget(arg); if (!file) goto out; @@ -38440,7 +38450,7 @@ index 79902c1..40db6d1 100644 error = -EINVAL; -@@ -667,6 +684,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, +@@ -689,6 +706,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, blk_mq_freeze_queue(lo->lo_queue); mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask); lo->lo_backing_file = file; @@ -38448,7 +38458,7 @@ index 79902c1..40db6d1 100644 lo->old_gfp_mask = mapping_gfp_mask(file->f_mapping); mapping_set_gfp_mask(file->f_mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); -@@ -674,12 +692,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, +@@ -696,12 +714,16 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, blk_mq_unfreeze_queue(lo->lo_queue); fput(old_file); @@ -38465,7 +38475,7 @@ index 79902c1..40db6d1 100644 out: return error; } -@@ -873,7 +895,7 @@ static int loop_prepare_queue(struct loop_device *lo) +@@ -895,7 +917,7 @@ static int loop_prepare_queue(struct loop_device *lo) static int loop_set_fd(struct loop_device *lo, fmode_t mode, struct block_device *bdev, unsigned int arg) { @@ -38474,7 +38484,7 @@ index 79902c1..40db6d1 100644 struct inode *inode; struct address_space *mapping; int lo_flags = 0; -@@ -887,6 +909,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, +@@ -909,6 +931,12 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, file = fget(arg); if (!file) goto out; @@ -38487,7 +38497,7 @@ index 79902c1..40db6d1 100644 error = -EBUSY; if (lo->lo_state != Lo_unbound) -@@ -935,6 +963,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, +@@ -957,6 +985,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, lo->lo_device = bdev; lo->lo_flags = lo_flags; lo->lo_backing_file = file; @@ -38495,7 +38505,7 @@ index 79902c1..40db6d1 100644 lo->transfer = NULL; lo->ioctl = NULL; lo->lo_sizelimit = 0; -@@ -968,6 +997,8 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, +@@ -990,6 +1019,8 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, out_putf: fput(file); @@ -38504,7 +38514,7 @@ index 79902c1..40db6d1 100644 out: /* This is safe: open() is still holding a reference. */ module_put(THIS_MODULE); -@@ -1014,6 +1045,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer, +@@ -1036,6 +1067,7 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer, static int loop_clr_fd(struct loop_device *lo) { struct file *filp = lo->lo_backing_file; @@ -38512,7 +38522,7 @@ index 79902c1..40db6d1 100644 gfp_t gfp = lo->old_gfp_mask; struct block_device *bdev = lo->lo_device; -@@ -1045,6 +1077,7 @@ static int loop_clr_fd(struct loop_device *lo) +@@ -1067,6 +1099,7 @@ static int loop_clr_fd(struct loop_device *lo) spin_lock_irq(&lo->lo_lock); lo->lo_state = Lo_rundown; lo->lo_backing_file = NULL; @@ -38520,7 +38530,7 @@ index 79902c1..40db6d1 100644 spin_unlock_irq(&lo->lo_lock); loop_release_xfer(lo); -@@ -1092,6 +1125,8 @@ static int loop_clr_fd(struct loop_device *lo) +@@ -1115,6 +1148,8 @@ static int loop_clr_fd(struct loop_device *lo) * bd_mutex which is usually taken before lo_ctl_mutex. */ fput(filp); @@ -38530,7 +38540,7 @@ index 79902c1..40db6d1 100644 } diff --git a/drivers/block/loop.h b/drivers/block/loop.h -index 0f45416..101f193 100644 +index b78de98..2bbbd92 100644 --- a/drivers/block/loop.h +++ b/drivers/block/loop.h @@ -46,7 +46,7 @@ struct loop_device { ================================================================ ---- gitweb: http://git.pld-linux.org/gitweb.cgi/packages/kernel.git/commitdiff/c4adf1697bd4a83156306fb9df9870bf233c9cc0 _______________________________________________ pld-cvs-commit mailing list pld-cvs-commit@lists.pld-linux.org http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit