Skip to content

Commit c6aeae4

Browse files
committed
Merge: ipc: align IPC core codebase with upstream v6.6 longterm release
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/6605 JIRA: https://issues.redhat.com/browse/RHEL-83456 Update RHEL-9 IPC subsystem to align it with upstream's v6.6 LTS level Signed-off-by: Rafael Aquini <raquini@redhat.com> Approved-by: Herton R. Krzesinski <herton@redhat.com> Approved-by: Phil Auld <pauld@redhat.com> Approved-by: Waiman Long <longman@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Augusto Caringi <acaringi@redhat.com>
2 parents 55ceae4 + 68f9fb8 commit c6aeae4

File tree

12 files changed

+370
-176
lines changed

12 files changed

+370
-176
lines changed

arch/arm/kernel/sys_oabi-compat.c

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
#include <linux/socket.h>
8181
#include <linux/net.h>
8282
#include <linux/ipc.h>
83+
#include <linux/ipc_namespace.h>
8384
#include <linux/uaccess.h>
8485
#include <linux/slab.h>
8586

@@ -321,46 +322,52 @@ struct oabi_sembuf {
321322
unsigned short __pad;
322323
};
323324

325+
#define sc_semopm sem_ctls[2]
326+
327+
#ifdef CONFIG_SYSVIPC
324328
asmlinkage long sys_oabi_semtimedop(int semid,
325329
struct oabi_sembuf __user *tsops,
326330
unsigned nsops,
327331
const struct old_timespec32 __user *timeout)
328332
{
333+
struct ipc_namespace *ns;
329334
struct sembuf *sops;
330-
struct old_timespec32 local_timeout;
331335
long err;
332336
int i;
333337

338+
ns = current->nsproxy->ipc_ns;
339+
if (nsops > ns->sc_semopm)
340+
return -E2BIG;
334341
if (nsops < 1 || nsops > SEMOPM)
335342
return -EINVAL;
336-
if (!access_ok(tsops, sizeof(*tsops) * nsops))
337-
return -EFAULT;
338-
sops = kmalloc_array(nsops, sizeof(*sops), GFP_KERNEL);
343+
sops = kvmalloc_array(nsops, sizeof(*sops), GFP_KERNEL);
339344
if (!sops)
340345
return -ENOMEM;
341346
err = 0;
342347
for (i = 0; i < nsops; i++) {
343348
struct oabi_sembuf osb;
344-
err |= __copy_from_user(&osb, tsops, sizeof(osb));
349+
err |= copy_from_user(&osb, tsops, sizeof(osb));
345350
sops[i].sem_num = osb.sem_num;
346351
sops[i].sem_op = osb.sem_op;
347352
sops[i].sem_flg = osb.sem_flg;
348353
tsops++;
349354
}
350-
if (timeout) {
351-
/* copy this as well before changing domain protection */
352-
err |= copy_from_user(&local_timeout, timeout, sizeof(*timeout));
353-
timeout = &local_timeout;
354-
}
355355
if (err) {
356356
err = -EFAULT;
357-
} else {
358-
mm_segment_t fs = get_fs();
359-
set_fs(KERNEL_DS);
360-
err = sys_semtimedop_time32(semid, sops, nsops, timeout);
361-
set_fs(fs);
357+
goto out;
362358
}
363-
kfree(sops);
359+
360+
if (timeout) {
361+
struct timespec64 ts;
362+
err = get_old_timespec32(&ts, timeout);
363+
if (err)
364+
goto out;
365+
err = __do_semtimedop(semid, sops, nsops, &ts, ns);
366+
goto out;
367+
}
368+
err = __do_semtimedop(semid, sops, nsops, NULL, ns);
369+
out:
370+
kvfree(sops);
364371
return err;
365372
}
366373

@@ -387,6 +394,27 @@ asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third,
387394
return sys_ipc(call, first, second, third, ptr, fifth);
388395
}
389396
}
397+
#else
398+
asmlinkage long sys_oabi_semtimedop(int semid,
399+
struct oabi_sembuf __user *tsops,
400+
unsigned nsops,
401+
const struct old_timespec32 __user *timeout)
402+
{
403+
return -ENOSYS;
404+
}
405+
406+
asmlinkage long sys_oabi_semop(int semid, struct oabi_sembuf __user *tsops,
407+
unsigned nsops)
408+
{
409+
return -ENOSYS;
410+
}
411+
412+
asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third,
413+
void __user *ptr, long fifth)
414+
{
415+
return -ENOSYS;
416+
}
417+
#endif
390418

391419
asmlinkage long sys_oabi_bind(int fd, struct sockaddr __user *addr, int addrlen)
392420
{

fs/namespace.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,6 +1237,17 @@ struct vfsmount *mntget(struct vfsmount *mnt)
12371237
}
12381238
EXPORT_SYMBOL(mntget);
12391239

1240+
/*
1241+
* Make a mount point inaccessible to new lookups.
1242+
* Because there may still be current users, the caller MUST WAIT
1243+
* for an RCU grace period before destroying the mount point.
1244+
*/
1245+
void mnt_make_shortterm(struct vfsmount *mnt)
1246+
{
1247+
if (mnt)
1248+
real_mount(mnt)->mnt_ns = NULL;
1249+
}
1250+
12401251
/**
12411252
* path_is_mountpoint() - Check if path is a mount in the current namespace.
12421253
* @path: path to check
@@ -4334,8 +4345,8 @@ EXPORT_SYMBOL_GPL(kern_mount);
43344345
void kern_unmount(struct vfsmount *mnt)
43354346
{
43364347
/* release long term mount so mount point can be released */
4337-
if (!IS_ERR_OR_NULL(mnt)) {
4338-
real_mount(mnt)->mnt_ns = NULL;
4348+
if (!IS_ERR(mnt)) {
4349+
mnt_make_shortterm(mnt);
43394350
synchronize_rcu(); /* yecchhh... */
43404351
mntput(mnt);
43414352
}
@@ -4347,8 +4358,7 @@ void kern_unmount_array(struct vfsmount *mnt[], unsigned int num)
43474358
unsigned int i;
43484359

43494360
for (i = 0; i < num; i++)
4350-
if (mnt[i])
4351-
real_mount(mnt[i])->mnt_ns = NULL;
4361+
mnt_make_shortterm(mnt[i]);
43524362
synchronize_rcu_expedited();
43534363
for (i = 0; i < num; i++)
43544364
mntput(mnt[i]);

include/linux/ipc_namespace.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,16 @@ static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
139139
return ns;
140140
}
141141

142+
static inline struct ipc_namespace *get_ipc_ns_not_zero(struct ipc_namespace *ns)
143+
{
144+
if (ns) {
145+
if (refcount_inc_not_zero(&ns->ns.count))
146+
return ns;
147+
}
148+
149+
return NULL;
150+
}
151+
142152
extern void put_ipc_ns(struct ipc_namespace *ns);
143153
#else
144154
static inline struct ipc_namespace *copy_ipcs(unsigned long flags,
@@ -155,6 +165,11 @@ static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
155165
return ns;
156166
}
157167

168+
static inline struct ipc_namespace *get_ipc_ns_not_zero(struct ipc_namespace *ns)
169+
{
170+
return ns;
171+
}
172+
158173
static inline void put_ipc_ns(struct ipc_namespace *ns)
159174
{
160175
}

include/linux/mount.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ extern void mnt_drop_write(struct vfsmount *mnt);
8686
extern void mnt_drop_write_file(struct file *file);
8787
extern void mntput(struct vfsmount *mnt);
8888
extern struct vfsmount *mntget(struct vfsmount *mnt);
89+
extern void mnt_make_shortterm(struct vfsmount *mnt);
8990
extern struct vfsmount *mnt_clone_internal(const struct path *path);
9091
extern bool __mnt_is_readonly(struct vfsmount *mnt);
9192
extern bool mnt_may_suid(struct vfsmount *mnt);

include/linux/sched/task.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ static inline struct vm_struct *task_stack_vm_area(const struct task_struct *t)
193193
* Protects ->fs, ->files, ->mm, ->group_info, ->comm, keyring
194194
* subscriptions and synchronises with wait4(). Also used in procfs. Also
195195
* pins the final release of task.io_context. Also protects ->cpuset and
196-
* ->cgroup.subsys[]. And ->vfork_done.
196+
* ->cgroup.subsys[]. And ->vfork_done. And ->sysvshm.shm_clist.
197197
*
198198
* Nests both inside and outside of read_lock(&tasklist_lock).
199199
* It must not be nested with write_lock_irq(&tasklist_lock),

include/linux/syscalls.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,6 +1286,9 @@ long ksys_old_shmctl(int shmid, int cmd, struct shmid_ds __user *buf);
12861286
long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems,
12871287
unsigned int nsops,
12881288
const struct old_timespec32 __user *timeout);
1289+
long __do_semtimedop(int semid, struct sembuf *tsems, unsigned int nsops,
1290+
const struct timespec64 *timeout,
1291+
struct ipc_namespace *ns);
12891292

12901293
int __sys_getsockopt(int fd, int level, int optname, char __user *optval,
12911294
int __user *optlen);

ipc/mqueue.c

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
302302
inode->i_mode = mode;
303303
inode->i_uid = current_fsuid();
304304
inode->i_gid = current_fsgid();
305-
inode->i_mtime = inode->i_ctime = inode->i_atime = current_time(inode);
305+
inode->i_mtime = inode->i_atime = inode_set_ctime_current(inode);
306306

307307
if (S_ISREG(mode)) {
308308
struct mqueue_inode_info *info;
@@ -489,7 +489,7 @@ static struct vfsmount *mq_create_mount(struct ipc_namespace *ns)
489489

490490
static void init_once(void *foo)
491491
{
492-
struct mqueue_inode_info *p = (struct mqueue_inode_info *) foo;
492+
struct mqueue_inode_info *p = foo;
493493

494494
inode_init_once(&p->vfs_inode);
495495
}
@@ -596,7 +596,7 @@ static int mqueue_create_attr(struct dentry *dentry, umode_t mode, void *arg)
596596

597597
put_ipc_ns(ipc_ns);
598598
dir->i_size += DIRENT_SIZE;
599-
dir->i_ctime = dir->i_mtime = dir->i_atime = current_time(dir);
599+
dir->i_mtime = dir->i_atime = inode_set_ctime_current(dir);
600600

601601
d_instantiate(dentry, inode);
602602
dget(dentry);
@@ -618,7 +618,7 @@ static int mqueue_unlink(struct inode *dir, struct dentry *dentry)
618618
{
619619
struct inode *inode = d_inode(dentry);
620620

621-
dir->i_ctime = dir->i_mtime = dir->i_atime = current_time(dir);
621+
dir->i_mtime = dir->i_atime = inode_set_ctime_current(dir);
622622
dir->i_size -= DIRENT_SIZE;
623623
drop_nlink(inode);
624624
dput(dentry);
@@ -635,7 +635,8 @@ static int mqueue_unlink(struct inode *dir, struct dentry *dentry)
635635
static ssize_t mqueue_read_file(struct file *filp, char __user *u_data,
636636
size_t count, loff_t *off)
637637
{
638-
struct mqueue_inode_info *info = MQUEUE_I(file_inode(filp));
638+
struct inode *inode = file_inode(filp);
639+
struct mqueue_inode_info *info = MQUEUE_I(inode);
639640
char buffer[FILENT_SIZE];
640641
ssize_t ret;
641642

@@ -656,7 +657,7 @@ static ssize_t mqueue_read_file(struct file *filp, char __user *u_data,
656657
if (ret <= 0)
657658
return ret;
658659

659-
file_inode(filp)->i_atime = file_inode(filp)->i_ctime = current_time(file_inode(filp));
660+
inode->i_atime = inode_set_ctime_current(inode);
660661
return ret;
661662
}
662663

@@ -986,8 +987,7 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
986987

987988
out_unlock:
988989
inode_unlock(d_inode(mnt->mnt_root));
989-
if (inode)
990-
iput(inode);
990+
iput(inode);
991991
mnt_drop_write(mnt);
992992
out_name:
993993
putname(name);
@@ -1163,8 +1163,7 @@ static int do_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
11631163
goto out_unlock;
11641164
__do_notify(info);
11651165
}
1166-
inode->i_atime = inode->i_mtime = inode->i_ctime =
1167-
current_time(inode);
1166+
inode->i_atime = inode->i_mtime = inode_set_ctime_current(inode);
11681167
}
11691168
out_unlock:
11701169
spin_unlock(&info->lock);
@@ -1258,8 +1257,7 @@ static int do_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
12581257

12591258
msg_ptr = msg_get(info);
12601259

1261-
inode->i_atime = inode->i_mtime = inode->i_ctime =
1262-
current_time(inode);
1260+
inode->i_atime = inode->i_mtime = inode_set_ctime_current(inode);
12631261

12641262
/* There is now free space in queue. */
12651263
pipelined_receive(&wake_q, info);
@@ -1397,7 +1395,7 @@ static int do_mq_notify(mqd_t mqdes, const struct sigevent *notification)
13971395
if (notification == NULL) {
13981396
if (info->notify_owner == task_tgid(current)) {
13991397
remove_notification(info);
1400-
inode->i_atime = inode->i_ctime = current_time(inode);
1398+
inode->i_atime = inode_set_ctime_current(inode);
14011399
}
14021400
} else if (info->notify_owner != NULL) {
14031401
ret = -EBUSY;
@@ -1423,7 +1421,7 @@ static int do_mq_notify(mqd_t mqdes, const struct sigevent *notification)
14231421

14241422
info->notify_owner = get_pid(task_tgid(current));
14251423
info->notify_user_ns = get_user_ns(current_user_ns());
1426-
inode->i_atime = inode->i_ctime = current_time(inode);
1424+
inode->i_atime = inode_set_ctime_current(inode);
14271425
}
14281426
spin_unlock(&info->lock);
14291427
out_fput:
@@ -1486,7 +1484,7 @@ static int do_mq_getsetattr(int mqdes, struct mq_attr *new, struct mq_attr *old)
14861484
f.file->f_flags &= ~O_NONBLOCK;
14871485
spin_unlock(&f.file->f_lock);
14881486

1489-
inode->i_atime = inode->i_ctime = current_time(inode);
1487+
inode->i_atime = inode_set_ctime_current(inode);
14901488
}
14911489

14921490
spin_unlock(&info->lock);
@@ -1710,11 +1708,6 @@ void mq_clear_sbinfo(struct ipc_namespace *ns)
17101708
ns->mq_mnt->mnt_sb->s_fs_info = NULL;
17111709
}
17121710

1713-
void mq_put_mnt(struct ipc_namespace *ns)
1714-
{
1715-
kern_unmount(ns->mq_mnt);
1716-
}
1717-
17181711
static int __init init_mqueue_fs(void)
17191712
{
17201713
int error;

0 commit comments

Comments
 (0)