Import of kernel-4.18.0-553.111.1.el8_10

This commit is contained in:
almalinux-bot-kernel 2026-03-12 04:35:23 +00:00
parent 815b0a2cc8
commit 4248d3d5bb
9 changed files with 84 additions and 17 deletions

View File

@ -12,7 +12,7 @@ RHEL_MINOR = 10
#
# Use this spot to avoid future merge conflicts.
# Do not trim this comment.
RHEL_RELEASE = 553.109.1
RHEL_RELEASE = 553.111.1
#
# ZSTREAM

View File

@ -62,7 +62,7 @@ struct macvlan_port {
struct macvlan_source_entry {
struct hlist_node hlist;
struct macvlan_dev *vlan;
struct macvlan_dev __rcu *vlan;
unsigned char addr[6+2] __aligned(sizeof(u16));
struct rcu_head rcu;
};
@ -150,7 +150,7 @@ static struct macvlan_source_entry *macvlan_hash_lookup_source(
hlist_for_each_entry_rcu(entry, h, hlist, lockdep_rtnl_is_held()) {
if (ether_addr_equal_64bits(entry->addr, addr) &&
entry->vlan == vlan)
rcu_access_pointer(entry->vlan) == vlan)
return entry;
}
return NULL;
@ -172,7 +172,7 @@ static int macvlan_hash_add_source(struct macvlan_dev *vlan,
return -ENOMEM;
ether_addr_copy(entry->addr, addr);
entry->vlan = vlan;
RCU_INIT_POINTER(entry->vlan, vlan);
h = &port->vlan_source_hash[macvlan_eth_hash(addr)];
hlist_add_head_rcu(&entry->hlist, h);
vlan->macaddr_count++;
@ -191,6 +191,7 @@ static void macvlan_hash_add(struct macvlan_dev *vlan)
static void macvlan_hash_del_source(struct macvlan_source_entry *entry)
{
RCU_INIT_POINTER(entry->vlan, NULL);
hlist_del_rcu(&entry->hlist);
kfree_rcu(entry, rcu);
}
@ -402,7 +403,7 @@ static void macvlan_flush_sources(struct macvlan_port *port,
entry = hlist_entry(h, struct macvlan_source_entry,
hlist);
if (entry->vlan == vlan)
if (rcu_access_pointer(entry->vlan) == vlan)
macvlan_hash_del_source(entry);
}
}
@ -444,8 +445,14 @@ static void macvlan_forward_source(struct sk_buff *skb,
struct hlist_head *h = &port->vlan_source_hash[idx];
hlist_for_each_entry_rcu(entry, h, hlist) {
if (ether_addr_equal_64bits(entry->addr, addr))
macvlan_forward_source_one(skb, entry->vlan);
if (ether_addr_equal_64bits(entry->addr, addr)) {
struct macvlan_dev *vlan = rcu_dereference(entry->vlan);
if (!vlan)
continue;
macvlan_forward_source_one(skb, vlan);
}
}
}
@ -1677,7 +1684,7 @@ static int macvlan_fill_info_macaddr(struct sk_buff *skb,
struct macvlan_source_entry *entry;
hlist_for_each_entry_rcu(entry, h, hlist, lockdep_rtnl_is_held()) {
if (entry->vlan != vlan)
if (rcu_access_pointer(entry->vlan) != vlan)
continue;
if (nla_put(skb, IFLA_MACVLAN_MACADDR, ETH_ALEN, entry->addr))
return 1;

View File

@ -1016,6 +1016,7 @@ static void fbcon_init(struct vc_data *vc, int init)
fvc->vc_font.data);
vc->vc_font.width = fvc->vc_font.width;
vc->vc_font.height = fvc->vc_font.height;
vc->vc_font.charcount = fvc->vc_font.charcount;
p->userfont = t->userfont;
if (p->userfont)
@ -1346,6 +1347,7 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
vc->vc_font.data = (void *)(p->fontdata = t->fontdata);
vc->vc_font.width = (*default_mode)->vc_font.width;
vc->vc_font.height = (*default_mode)->vc_font.height;
vc->vc_font.charcount = (*default_mode)->vc_font.charcount;
p->userfont = t->userfont;
if (p->userfont)
REFCOUNT(p->fontdata)++;
@ -2397,6 +2399,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
REFCOUNT(data)++;
vc->vc_font.width = w;
vc->vc_font.height = h;
vc->vc_font.charcount = cnt;
if (vc->vc_hi_font_mask && cnt == 256)
set_vc_hi_font(vc, false);
else if (!vc->vc_hi_font_mask && cnt == 512)

View File

@ -35,17 +35,21 @@ void set_fs_root(struct fs_struct *fs, const struct path *path)
void set_fs_pwd(struct fs_struct *fs, const struct path *path)
{
struct path old_pwd;
int count;
path_get(path);
spin_lock(&fs->lock);
write_seqcount_begin(&fs->seq);
old_pwd = fs->pwd;
fs->pwd = *path;
count = fs->pwd_refs + 1;
fs->pwd_refs = 0;
write_seqcount_end(&fs->seq);
spin_unlock(&fs->lock);
if (old_pwd.dentry)
path_put(&old_pwd);
while (count--)
path_put(&old_pwd);
}
static inline int replace_path(struct path *p, const struct path *old, const struct path *new)
@ -67,11 +71,16 @@ void chroot_fs_refs(const struct path *old_root, const struct path *new_root)
task_lock(p);
fs = p->fs;
if (fs) {
int hits = 0;
int hits;
spin_lock(&fs->lock);
write_seqcount_begin(&fs->seq);
hits = replace_path(&fs->pwd, old_root, new_root);
if (hits && fs->pwd_refs) {
count += fs->pwd_refs;
fs->pwd_refs = 0;
}
hits += replace_path(&fs->root, old_root, new_root);
hits += replace_path(&fs->pwd, old_root, new_root);
write_seqcount_end(&fs->seq);
while (hits--) {
count++;
@ -88,8 +97,11 @@ void chroot_fs_refs(const struct path *old_root, const struct path *new_root)
void free_fs_struct(struct fs_struct *fs)
{
int count = fs->pwd_refs + 1;
path_put(&fs->root);
path_put(&fs->pwd);
while (count--)
path_put(&fs->pwd);
kmem_cache_free(fs_cachep, fs);
}
@ -117,6 +129,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
if (fs) {
fs->users = 1;
fs->in_exec = 0;
fs->pwd_refs = 0;
spin_lock_init(&fs->lock);
seqcount_init(&fs->seq);
fs->umask = old->umask;
@ -125,7 +138,10 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
fs->root = old->root;
path_get(&fs->root);
fs->pwd = old->pwd;
path_get(&fs->pwd);
if (old->pwd_refs)
old->pwd_refs--;
else
path_get(&fs->pwd);
spin_unlock(&old->lock);
}
return fs;

View File

@ -3302,6 +3302,14 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
* as belonging to new namespace. We have already acquired a private
* fs_struct, so tsk->fs->lock is not needed.
*/
if (new_fs)
WARN_ON_ONCE(new_fs->users != 1);
/* Release the extra pwd references of new_fs, if present. */
while (new_fs && new_fs->pwd_refs) {
path_put(&new_fs->pwd);
new_fs->pwd_refs--;
}
p = old;
q = new;
while (p) {

View File

@ -464,7 +464,8 @@ pnfs_mark_layout_stateid_invalid(struct pnfs_layout_hdr *lo,
};
struct pnfs_layout_segment *lseg, *next;
set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags);
if (test_and_set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags))
return !list_empty(&lo->plh_segs);
clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(lo->plh_inode)->flags);
list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list)
pnfs_clear_lseg_state(lseg, lseg_list);

View File

@ -12,6 +12,7 @@ struct fs_struct {
seqcount_t seq;
int umask;
int in_exec;
RH_KABI_FILL_HOLE(int pwd_refs) /* A pool of extra pwd references */
struct path root, pwd;
} __randomize_layout;
@ -40,6 +41,33 @@ static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd)
spin_unlock(&fs->lock);
}
/* Acquire a pwd reference from the pwd_refs pool, if available */
static inline void get_fs_pwd_pool(struct fs_struct *fs, struct path *pwd)
{
spin_lock(&fs->lock);
*pwd = fs->pwd;
if (fs->pwd_refs)
fs->pwd_refs--;
else
path_get(pwd);
spin_unlock(&fs->lock);
}
/* Release a pwd reference back to the pwd_refs pool, if appropriate */
static inline void put_fs_pwd_pool(struct fs_struct *fs, struct path *pwd)
{
bool put = false;
spin_lock(&fs->lock);
if ((fs->pwd.dentry == pwd->dentry) && (fs->pwd.mnt == pwd->mnt))
fs->pwd_refs++;
else
put = true;
spin_unlock(&fs->lock);
if (put)
path_put(pwd);
}
extern bool current_chrooted(void);
#endif /* _LINUX_FS_STRUCT_H */

View File

@ -887,6 +887,9 @@ static inline void audit_free_names(struct audit_context *context)
{
struct audit_names *n, *next;
if (!context->name_count)
return; /* audit_alloc_name() has not been called */
list_for_each_entry_safe(n, next, &context->names_list, list) {
list_del(&n->list);
if (n->name)
@ -895,7 +898,7 @@ static inline void audit_free_names(struct audit_context *context)
kfree(n);
}
context->name_count = 0;
path_put(&context->pwd);
put_fs_pwd_pool(current->fs, &context->pwd);
context->pwd.dentry = NULL;
context->pwd.mnt = NULL;
}
@ -2000,7 +2003,7 @@ static struct audit_names *audit_alloc_name(struct audit_context *context,
context->name_count++;
if (!context->pwd.dentry)
get_fs_pwd(current->fs, &context->pwd);
get_fs_pwd_pool(current->fs, &context->pwd);
return aname;
}

View File

@ -1336,7 +1336,8 @@ static int calipso_skbuff_setattr(struct sk_buff *skb,
/* At this point new_end aligns to 4n, so (new_end & 4) pads to 8n */
pad = ((new_end & 4) + (end & 7)) & 7;
len_delta = new_end - (int)end + pad;
ret_val = skb_cow(skb, skb_headroom(skb) + len_delta);
ret_val = skb_cow(skb,
skb_headroom(skb) + (len_delta > 0 ? len_delta : 0));
if (ret_val < 0)
return ret_val;