diff --git a/baseband_guard.c b/baseband_guard.c index fa9756e..5784812 100644 --- a/baseband_guard.c +++ b/baseband_guard.c @@ -74,11 +74,18 @@ extern char *saved_command_line; static const char *slot_suffix_from_cmdline(void) { const char *p = saved_command_line; - if (!p) return NULL; + + if (!p) + return NULL; + p = strstr(p, "androidboot.slot_suffix="); - if (!p) return NULL; + if (!p) + return NULL; + p += strlen("androidboot.slot_suffix="); - if (p[0] == '_' && (p[1] == 'a' || p[1] == 'b')) return (p[1] == 'a') ? "_a" : "_b"; + if (p[0] == '_' && (p[1] == 'a' || p[1] == 'b')) + return (p[1] == 'a') ? "_a" : "_b"; + return NULL; } @@ -88,38 +95,55 @@ static bool inline resolve_byname_dev(const char *name, dev_t *out) dev_t dev; int ret; - if (!name || !out) return false; + if (!name || !out) + return false; path = kasprintf(GFP_KERNEL, "%s/%s", BB_BYNAME_DIR, name); - if (!path) return false; + if (!path) + return false; ret = lookup_bdev_compat(path, &dev); kfree(path); - if (ret) return false; + if (ret) + return false; *out = dev; + return true; } -struct allow_node { dev_t dev; struct hlist_node h; }; +struct allow_node { + dev_t dev; + struct hlist_node h; +}; DEFINE_HASHTABLE(allowed_devs, 7); static bool allow_has(dev_t dev) { struct allow_node *p; - hash_for_each_possible(allowed_devs, p, h, (u64)dev) - if (p->dev == dev) return true; + + hash_for_each_possible(allowed_devs, p, h, (u64)dev) { + if (p->dev == dev) + return true; + } + return false; } static void allow_add(dev_t dev) { struct allow_node *n; - if (!dev || allow_has(dev)) return; + + if (!dev || allow_has(dev)) + return; + n = kmalloc(sizeof(*n), GFP_ATOMIC); - if (!n) return; + if (!n) + return; + n->dev = dev; hash_add(allowed_devs, &n->h, (u64)dev); + #if BB_DEBUG bb_pr("allow-cache dev %u:%u\n", MAJOR(dev), MINOR(dev)); #endif @@ -135,31 +159,42 @@ static inline bool is_allowed_partition_dev_resolve(dev_t cur) const char *n = allowlist_names[i]; bool ok = false; - if (resolve_byname_dev(n, &dev) && dev == cur) return true; + if (resolve_byname_dev(n, &dev) && dev == cur) + return true; if (!ok && suf) { char *nm = kasprintf(GFP_ATOMIC, "%s%s", n, suf); if (nm) { ok = resolve_byname_dev(nm, &dev); kfree(nm); - if (ok && dev == cur) return true; + if (ok && dev == cur) + return true; } } + if (!ok) { char *na = kasprintf(GFP_ATOMIC, "%s_a", n); char *nb = kasprintf(GFP_ATOMIC, "%s_b", n); + if (na) { ok = resolve_byname_dev(na, &dev); kfree(na); - if (ok && dev == cur) { if (nb) kfree(nb); return true; } + if (ok && dev == cur) { + if (nb) + kfree(nb); + return true; + } } + if (nb) { ok = resolve_byname_dev(nb, &dev); kfree(nb); - if (ok && dev == cur) return true; + if (ok && dev == cur) + return true; } } } + return false; } @@ -183,20 +218,25 @@ static bool is_zram_device(dev_t dev) } blkdev_put_compat(bdev, FMODE_READ, THIS_MODULE); + return is_zram; } static bool reverse_allow_match_and_cache(dev_t cur) { - if (!cur) return false; + if (!cur) + return false; + if (is_zram_device(cur)) { allow_add(cur); return true; } + if (is_allowed_partition_dev_resolve(cur)) { allow_add(cur); return true; } + return false; } @@ -214,21 +254,31 @@ static bool current_domain_allowed(void) size_t i; #if BB_ANTI_SPOOF_NO_TRUST_PERMISSIVE_ONCE - if (unlikely(bbg_recently_permissive)) return false; + if (unlikely(bbg_recently_permissive)) + return false; #endif security_cred_getsecid_compat(current_cred(), &sid); - if (!sid) return false; - if (security_secid_to_secctx(sid, &ctx, &len)) return false; - if (!ctx || !len) goto out; + if (!sid) + return false; + + if (security_secid_to_secctx(sid, &ctx, &len)) + return false; + + if (!ctx || !len) + goto out; for (i = 0; i < allowed_domain_substrings_cnt; i++) { const char *needle = allowed_domain_substrings[i]; if (needle && *needle) { - if (strnstr(ctx, needle, len)) { ok = true; break; } + if (strnstr(ctx, needle, len)) { + ok = true; + break; + } } } + out: security_release_secctx(ctx, len); return ok; @@ -240,21 +290,37 @@ static bool current_domain_allowed(void) static const char *bbg_file_path(struct file *file, char *buf, int buflen) { char *p; - if (!file || !buf || buflen <= 0) return NULL; + + if (!file || !buf || buflen <= 0) + return NULL; + buf[0] = '\0'; p = d_path(&file->f_path, buf, buflen); + return IS_ERR(p) ? NULL : p; } static int bbg_get_cmdline(char *buf, int buflen) { int n, i; - if (!buf || buflen <= 0) return 0; + + if (!buf || buflen <= 0) + return 0; + n = get_cmdline(current, buf, buflen); - if (n <= 0) return 0; - for (i = 0; i < n - 1; i++) if (buf[i] == '\0') buf[i] = ' '; - if (n < buflen) buf[n] = '\0'; - else buf[buflen - 1] = '\0'; + if (n <= 0) + return 0; + + for (i = 0; i < n - 1; i++) { + if (buf[i] == '\0') + buf[i] = ' '; + } + + if (n < buflen) + buf[n] = '\0'; + else + buf[buflen - 1] = '\0'; + return n; } @@ -262,10 +328,8 @@ static void bbg_log_deny_detail(const char *why, struct file *file, unsigned int { const int PATH_BUFLEN = 256; const int CMD_BUFLEN = 256; - char *pathbuf = kmalloc(PATH_BUFLEN, GFP_ATOMIC); char *cmdbuf = kmalloc(CMD_BUFLEN, GFP_ATOMIC); - const char *path = pathbuf ? bbg_file_path(file, pathbuf, PATH_BUFLEN) : NULL; struct inode *inode = file ? file_inode(file) : NULL; dev_t dev = inode ? inode->i_rdev : 0; @@ -307,9 +371,13 @@ static void bbg_log_deny_detail(const char *why, struct file *file, unsigned int static int deny(const char *why, struct file *file, unsigned int cmd_opt) { - if (!BB_ENFORCING) return 0; + if (!BB_ENFORCING) + return 0; + bbg_log_deny_detail(why, file, cmd_opt); + bb_pr_rl("deny %s pid=%d comm=%s\n", why, current->pid, current->comm); + return -EPERM; } @@ -317,11 +385,15 @@ static int bb_file_permission(struct file *file, int mask) { struct inode *inode; - if (!(mask & MAY_WRITE)) return 0; - if (!file) return 0; + if (!(mask & MAY_WRITE)) + return 0; + + if (!file) + return 0; inode = file_inode(file); - if (likely(!S_ISBLK(inode->i_mode))) return 0; + if (likely(!S_ISBLK(inode->i_mode))) + return 0; if (likely(current_domain_allowed())) return 0; @@ -363,9 +435,12 @@ static int bb_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct inode *inode; - if (!file) return 0; + if (!file) + return 0; + inode = file_inode(file); - if (likely(!S_ISBLK(inode->i_mode))) return 0; + if (likely(!S_ISBLK(inode->i_mode))) + return 0; if (!is_destructive_ioctl(cmd)) return 0; @@ -414,7 +489,9 @@ DEFINE_LSM(baseband_guard) = { #ifdef CONFIG_SECURITY_SELINUX_DEVELOP int bbg_process_setpermissive(void) { #if BB_ANTI_SPOOF_NO_TRUST_PERMISSIVE_ONCE - if (!bbg_recently_permissive) bbg_recently_permissive = true; + if (!bbg_recently_permissive) + bbg_recently_permissive = true; + return 0; #elif BB_ANTI_SPOOF_DISABLE_PERMISSIVE return 1; diff --git a/kernel_compat.h b/kernel_compat.h index 8f4ba09..15b8d84 100644 --- a/kernel_compat.h +++ b/kernel_compat.h @@ -6,15 +6,16 @@ static inline int lookup_bdev_compat(char *path, dev_t *out) { struct block_device *bdev; - if (!path || !out) { + if (!path || !out) return 1; - } bdev = lookup_bdev(path); if (IS_ERR(bdev)) return 1; + *out = bdev->bd_dev; bdput(bdev); + return 0; } #else @@ -22,14 +23,15 @@ static inline int lookup_bdev_compat(char *path, dev_t *out) { dev_t dev; int ret; - if (!path || !out) { + if (!path || !out) return 1; - } ret = lookup_bdev(path, &dev); - if (ret) return ret; + if (ret) + return ret; *out = dev; + return 0; } #endif @@ -55,7 +57,6 @@ static inline void blkdev_put_compat(struct block_device *dev, fmode_t mode, voi #endif #ifdef CONFIG_SECURITY_SELINUX - #if LINUX_VERSION_CODE < KERNEL_VERSION(4,17,0) struct task_security_struct { u32 osid; /* SID prior to last execve */ @@ -65,23 +66,22 @@ struct task_security_struct { u32 keycreate_sid; /* keycreate SID */ u32 sockcreate_sid; /* fscreate SID */ }; -static inline void security_cred_getsecid_compat(const struct cred *c, u32 *secid) { +static inline void security_cred_getsecid_compat(const struct cred *c, u32 *secid) +{ const struct task_security_struct *tsec; - if (!c || !secid) { + if (!c || !secid) return; - } tsec = c->security; *secid = tsec->sid; } #else -static inline void security_cred_getsecid_compat(const struct cred *c, u32 *secid) { +static inline void security_cred_getsecid_compat(const struct cred *c, u32 *secid) +{ security_cred_getsecid(c, secid); } #endif - - #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) @@ -91,7 +91,8 @@ const struct lsm_id bbg_lsmid = { }; #endif -static inline void __init security_add_hooks_compat(struct security_hook_list *hooks, int count) { +static inline void security_add_hooks_compat(struct security_hook_list *hooks, int count) +{ #if LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) security_add_hooks(hooks, count, &bbg_lsmid); #elif LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,0) @@ -99,5 +100,4 @@ static inline void __init security_add_hooks_compat(struct security_hook_list *h #else security_add_hooks(hooks, count); #endif - }