]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
tty/vt: use guard()s in con_font_set/get() and con_{set,get}_unimap()
authorJiri Slaby (SUSE) <jirislaby@kernel.org>
Thu, 14 Aug 2025 07:24:54 +0000 (09:24 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 17 Aug 2025 10:46:26 +0000 (12:46 +0200)
Having all the new guards, use them in the 8250_rsa code. This improves
readability, makes error handling easier, and marks locked portions of
code explicit.

The new __free()-annotated declarations are moved to the allocation points
as is preferred:
https://lore.kernel.org/all/CAHk-=wjvh_LUpa=864joG2JJXs3+viO-kLzLidR2JLyMr4MNwA@mail.gmail.com/

Except font_data in con_font_get(). The scope in there would not match
the expected lifetime. But the declaration is moved closer.

Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
Link: https://lore.kernel.org/r/20250814072456.182853-15-jirislaby@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/vt/consolemap.c
drivers/tty/vt/vt.c

index bb4bb272ebec566ec90b4dc5a89519116490d3d3..8eb9d745a868584f68ebc7d23b5d08e6b28d8f59 100644 (file)
@@ -637,32 +637,28 @@ static struct uni_pagedict *con_unshare_unimap(struct vc_data *vc,
 
 int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
 {
-       int err = 0, err1;
        struct uni_pagedict *dict;
-       struct unipair *unilist, *plist;
+       struct unipair *plist;
+       int err = 0;
 
        if (!ct)
                return 0;
 
-       unilist = vmemdup_array_user(list, ct, sizeof(*unilist));
+       struct unipair *unilist __free(kvfree) = vmemdup_array_user(list, ct, sizeof(*unilist));
        if (IS_ERR(unilist))
                return PTR_ERR(unilist);
 
-       console_lock();
+       guard(console_lock)();
 
        /* Save original vc_unipagdir_loc in case we allocate a new one */
        dict = *vc->uni_pagedict_loc;
-       if (!dict) {
-               err = -EINVAL;
-               goto out_unlock;
-       }
+       if (!dict)
+               return -EINVAL;
 
        if (dict->refcount > 1) {
                dict = con_unshare_unimap(vc, dict);
-               if (IS_ERR(dict)) {
-                       err = PTR_ERR(dict);
-                       goto out_unlock;
-               }
+               if (IS_ERR(dict))
+                       return PTR_ERR(dict);
        } else if (dict == dflt) {
                dflt = NULL;
        }
@@ -671,7 +667,7 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
         * Insert user specified unicode pairs into new table.
         */
        for (plist = unilist; ct; ct--, plist++) {
-               err1 = con_insert_unipair(dict, plist->unicode, plist->fontpos);
+               int err1 = con_insert_unipair(dict, plist->unicode, plist->fontpos);
                if (err1)
                        err = err1;
        }
@@ -680,15 +676,12 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
         * Merge with fontmaps of any other virtual consoles.
         */
        if (con_unify_unimap(vc, dict))
-               goto out_unlock;
+               return err;
 
        for (enum translation_map m = FIRST_MAP; m <= LAST_MAP; m++)
                set_inverse_transl(vc, dict, m);
        set_inverse_trans_unicode(dict);
 
-out_unlock:
-       console_unlock();
-       kvfree(unilist);
        return err;
 }
 
@@ -787,50 +780,49 @@ int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct,
 {
        ushort ect;
        struct uni_pagedict *dict;
-       struct unipair *unilist;
        unsigned int d, r, g;
-       int ret = 0;
 
-       unilist = kvmalloc_array(ct, sizeof(*unilist), GFP_KERNEL);
+       struct unipair *unilist __free(kvfree) = kvmalloc_array(ct, sizeof(*unilist), GFP_KERNEL);
        if (!unilist)
                return -ENOMEM;
 
-       console_lock();
-
-       ect = 0;
-       dict = *vc->uni_pagedict_loc;
-       if (!dict)
-               goto unlock;
-
-       for (d = 0; d < UNI_DIRS; d++) {
-               u16 **dir = dict->uni_pgdir[d];
-               if (!dir)
-                       continue;
+       scoped_guard(console_lock) {
+               ect = 0;
+               dict = *vc->uni_pagedict_loc;
+               if (!dict)
+                       break;
 
-               for (r = 0; r < UNI_DIR_ROWS; r++) {
-                       u16 *row = dir[r];
-                       if (!row)
+               for (d = 0; d < UNI_DIRS; d++) {
+                       u16 **dir = dict->uni_pgdir[d];
+                       if (!dir)
                                continue;
 
-                       for (g = 0; g < UNI_ROW_GLYPHS; g++, row++) {
-                               if (*row >= MAX_GLYPH)
+                       for (r = 0; r < UNI_DIR_ROWS; r++) {
+                               u16 *row = dir[r];
+                               if (!row)
                                        continue;
-                               if (ect < ct) {
-                                       unilist[ect].unicode = UNI(d, r, g);
-                                       unilist[ect].fontpos = *row;
+
+                               for (g = 0; g < UNI_ROW_GLYPHS; g++, row++) {
+                                       if (*row >= MAX_GLYPH)
+                                               continue;
+                                       if (ect < ct) {
+                                               unilist[ect].unicode = UNI(d, r, g);
+                                               unilist[ect].fontpos = *row;
+                                       }
+                                       ect++;
                                }
-                               ect++;
                        }
                }
        }
-unlock:
-       console_unlock();
+
        if (copy_to_user(list, unilist, min(ect, ct) * sizeof(*unilist)))
-               ret = -EFAULT;
+               return -EFAULT;
        if (put_user(ect, uct))
-               ret = -EFAULT;
-       kvfree(unilist);
-       return ret ? ret : (ect <= ct) ? 0 : -ENOMEM;
+               return -EFAULT;
+       if (ect > ct)
+               return -ENOMEM;
+
+       return 0;
 }
 
 /*
index 62049ceb34de6f164b35dce7212731c81d06f1a9..100d6cb26887ec6fdb98317c91517e52399106e5 100644 (file)
@@ -4801,57 +4801,51 @@ void reset_palette(struct vc_data *vc)
 static int con_font_get(struct vc_data *vc, struct console_font_op *op)
 {
        struct console_font font;
-       int rc = -EINVAL;
        int c;
        unsigned int vpitch = op->op == KD_FONT_OP_GET_TALL ? op->height : 32;
 
        if (vpitch > max_font_height)
                return -EINVAL;
 
+       void *font_data __free(kvfree) = NULL;
        if (op->data) {
-               font.data = kvzalloc(max_font_size, GFP_KERNEL);
+               font.data = font_data = kvzalloc(max_font_size, GFP_KERNEL);
                if (!font.data)
                        return -ENOMEM;
        } else
                font.data = NULL;
 
-       console_lock();
-       if (vc->vc_mode != KD_TEXT)
-               rc = -EINVAL;
-       else if (vc->vc_sw->con_font_get)
-               rc = vc->vc_sw->con_font_get(vc, &font, vpitch);
-       else
-               rc = -ENOSYS;
-       console_unlock();
+       scoped_guard(console_lock) {
+               if (vc->vc_mode != KD_TEXT)
+                       return -EINVAL;
+               if (!vc->vc_sw->con_font_get)
+                       return -ENOSYS;
 
-       if (rc)
-               goto out;
+               int ret = vc->vc_sw->con_font_get(vc, &font, vpitch);
+               if (ret)
+                       return ret;
+       }
 
        c = (font.width+7)/8 * vpitch * font.charcount;
 
        if (op->data && font.charcount > op->charcount)
-               rc = -ENOSPC;
+               return -ENOSPC;
        if (font.width > op->width || font.height > op->height)
-               rc = -ENOSPC;
-       if (rc)
-               goto out;
+               return -ENOSPC;
 
        op->height = font.height;
        op->width = font.width;
        op->charcount = font.charcount;
 
        if (op->data && copy_to_user(op->data, font.data, c))
-               rc = -EFAULT;
+               return -EFAULT;
 
-out:
-       kvfree(font.data);
-       return rc;
+       return 0;
 }
 
 static int con_font_set(struct vc_data *vc, const struct console_font_op *op)
 {
        struct console_font font;
-       int rc = -EINVAL;
        int size;
        unsigned int vpitch = op->op == KD_FONT_OP_SET_TALL ? op->height : 32;
 
@@ -4870,7 +4864,7 @@ static int con_font_set(struct vc_data *vc, const struct console_font_op *op)
        if (size > max_font_size)
                return -ENOSPC;
 
-       font.data = memdup_user(op->data, size);
+       void *font_data __free(kfree) = font.data = memdup_user(op->data, size);
        if (IS_ERR(font.data))
                return PTR_ERR(font.data);
 
@@ -4878,18 +4872,17 @@ static int con_font_set(struct vc_data *vc, const struct console_font_op *op)
        font.width = op->width;
        font.height = op->height;
 
-       console_lock();
+       guard(console_lock)();
+
        if (vc->vc_mode != KD_TEXT)
-               rc = -EINVAL;
-       else if (vc->vc_sw->con_font_set) {
-               if (vc_is_sel(vc))
-                       clear_selection();
-               rc = vc->vc_sw->con_font_set(vc, &font, vpitch, op->flags);
-       } else
-               rc = -ENOSYS;
-       console_unlock();
-       kfree(font.data);
-       return rc;
+               return -EINVAL;
+       if (!vc->vc_sw->con_font_set)
+               return -ENOSYS;
+
+       if (vc_is_sel(vc))
+               clear_selection();
+
+       return vc->vc_sw->con_font_set(vc, &font, vpitch, op->flags);
 }
 
 static int con_font_default(struct vc_data *vc, struct console_font_op *op)
@@ -4897,8 +4890,6 @@ static int con_font_default(struct vc_data *vc, struct console_font_op *op)
        struct console_font font = {.width = op->width, .height = op->height};
        char name[MAX_FONT_NAME];
        char *s = name;
-       int rc;
-
 
        if (!op->data)
                s = NULL;
@@ -4907,23 +4898,23 @@ static int con_font_default(struct vc_data *vc, struct console_font_op *op)
        else
                name[MAX_FONT_NAME - 1] = 0;
 
-       console_lock();
-       if (vc->vc_mode != KD_TEXT) {
-               console_unlock();
-               return -EINVAL;
-       }
-       if (vc->vc_sw->con_font_default) {
+       scoped_guard(console_lock) {
+               if (vc->vc_mode != KD_TEXT)
+                       return -EINVAL;
+               if (!vc->vc_sw->con_font_default)
+                       return -ENOSYS;
+
                if (vc_is_sel(vc))
                        clear_selection();
-               rc = vc->vc_sw->con_font_default(vc, &font, s);
-       } else
-               rc = -ENOSYS;
-       console_unlock();
-       if (!rc) {
-               op->width = font.width;
-               op->height = font.height;
+               int ret = vc->vc_sw->con_font_default(vc, &font, s);
+               if (ret)
+                       return ret;
        }
-       return rc;
+
+       op->width = font.width;
+       op->height = font.height;
+
+       return 0;
 }
 
 int con_font_op(struct vc_data *vc, struct console_font_op *op)