(root)/
strace-6.5/
tests-mx32/
quotactl-xfs.c
       1  /*
       2   * Check decoding of quotactl xfs subcommands.
       3   *
       4   * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
       5   * Copyright (c) 2016 Dmitry V. Levin <ldv@strace.io>
       6   * Copyright (c) 2016-2021 The strace developers.
       7   * All rights reserved.
       8   *
       9   * SPDX-License-Identifier: GPL-2.0-or-later
      10   */
      11  
      12  #include "tests.h"
      13  #include "scno.h"
      14  
      15  #include <stdio.h>
      16  #include <string.h>
      17  #include <unistd.h>
      18  
      19  #include <linux/dqblk_xfs.h>
      20  
      21  #include "quotactl.h"
      22  
      23  #include "xlat.h"
      24  #include "xlat/xfs_dqblk_flags.h"
      25  #if VERBOSE
      26  # include "xlat/xfs_quota_flags.h"
      27  #endif
      28  
      29  
      30  static void
      31  print_xdisk_quota(int rc, void *ptr, void *arg)
      32  {
      33  	struct fs_disk_quota *dq = ptr;
      34  	long out_arg = (long) arg;
      35  
      36  	if (((rc < 0) && out_arg) || (out_arg > 1)) {
      37  		printf("%p", dq);
      38  		return;
      39  	}
      40  
      41  	printf("{");
      42  	PRINT_FIELD_D(*dq, d_version);
      43  	printf(", d_flags=");
      44  	printflags(xfs_dqblk_flags, (uint8_t) dq->d_flags, "FS_???_QUOTA");
      45  
      46  	printf(", ");
      47  	PRINT_FIELD_X(*dq, d_fieldmask);
      48  	printf(", ");
      49  	PRINT_FIELD_U(*dq, d_id);
      50  	printf(", ");
      51  	PRINT_FIELD_U(*dq, d_blk_hardlimit);
      52  	printf(", ");
      53  	PRINT_FIELD_U(*dq, d_blk_softlimit);
      54  	printf(", ");
      55  	PRINT_FIELD_U(*dq, d_ino_hardlimit);
      56  	printf(", ");
      57  	PRINT_FIELD_U(*dq, d_ino_softlimit);
      58  	printf(", ");
      59  	PRINT_FIELD_U(*dq, d_bcount);
      60  	printf(", ");
      61  	PRINT_FIELD_U(*dq, d_icount);
      62  
      63  #if VERBOSE
      64  	printf(", ");
      65  	PRINT_FIELD_D(*dq, d_itimer);
      66  	printf(", ");
      67  	PRINT_FIELD_D(*dq, d_btimer);
      68  	printf(", ");
      69  	PRINT_FIELD_U(*dq, d_iwarns);
      70  	printf(", ");
      71  	PRINT_FIELD_U(*dq, d_bwarns);
      72  	printf(", ");
      73  	PRINT_FIELD_U(*dq, d_rtb_hardlimit);
      74  	printf(", ");
      75  	PRINT_FIELD_U(*dq, d_rtb_softlimit);
      76  	printf(", ");
      77  	PRINT_FIELD_U(*dq, d_rtbcount);
      78  	printf(", ");
      79  	PRINT_FIELD_D(*dq, d_rtbtimer);
      80  	printf(", ");
      81  	PRINT_FIELD_U(*dq, d_rtbwarns);
      82  #else
      83  	printf(", ...");
      84  #endif /* !VERBOSE */
      85  	printf("}");
      86  }
      87  
      88  static void
      89  print_xquota_stat(int rc, void *ptr, void *arg)
      90  {
      91  	struct fs_quota_stat *qs = ptr;
      92  	long out_arg = (long) arg;
      93  
      94  	if (((rc < 0) && out_arg) || (out_arg > 1)) {
      95  		printf("%p", qs);
      96  		return;
      97  	}
      98  
      99  	printf("{");
     100  	PRINT_FIELD_D(*qs, qs_version);
     101  
     102  #if VERBOSE
     103  	printf(", qs_flags=");
     104  	printflags(xfs_quota_flags, qs->qs_flags, "FS_QUOTA_???");
     105  	printf(", qs_uquota={");
     106  	PRINT_FIELD_U(qs->qs_uquota, qfs_ino);
     107  	printf(", ");
     108  	PRINT_FIELD_U(qs->qs_uquota, qfs_nblks);
     109  	printf(", ");
     110  	PRINT_FIELD_U(qs->qs_uquota, qfs_nextents);
     111  	printf("}, qs_gquota={");
     112  	PRINT_FIELD_U(qs->qs_gquota, qfs_ino);
     113  	printf(", ");
     114  	PRINT_FIELD_U(qs->qs_gquota, qfs_nblks);
     115  	printf(", ");
     116  	PRINT_FIELD_U(qs->qs_gquota, qfs_nextents);
     117  	printf("}, ");
     118  	PRINT_FIELD_U(*qs, qs_incoredqs);
     119  	printf(", ");
     120  	PRINT_FIELD_D(*qs, qs_btimelimit);
     121  	printf(", ");
     122  	PRINT_FIELD_D(*qs, qs_itimelimit);
     123  	printf(", ");
     124  	PRINT_FIELD_D(*qs, qs_rtbtimelimit);
     125  	printf(", ");
     126  	PRINT_FIELD_U(*qs, qs_bwarnlimit);
     127  	printf(", ");
     128  	PRINT_FIELD_U(*qs, qs_iwarnlimit);
     129  #else
     130  	printf(", ...");
     131  #endif /* !VERBOSE */
     132  	printf("}");
     133  }
     134  
     135  static void
     136  print_xquota_statv(int rc, void *ptr, void *arg)
     137  {
     138  	struct fs_quota_statv *qs = ptr;
     139  	long out_arg = (long) arg;
     140  
     141  	if (((rc < 0) && out_arg) || (out_arg > 1)) {
     142  		printf("%p", qs);
     143  		return;
     144  	}
     145  
     146  	printf("{");
     147  	PRINT_FIELD_D(*qs, qs_version);
     148  
     149  #if VERBOSE
     150  	printf(", qs_flags=");
     151  	printflags(xfs_quota_flags, qs->qs_flags, "FS_QUOTA_???");
     152  	printf(", ");
     153  	PRINT_FIELD_U(*qs, qs_incoredqs);
     154  	printf(", qs_uquota={");
     155  	PRINT_FIELD_U(qs->qs_uquota, qfs_ino);
     156  	printf(", ");
     157  	PRINT_FIELD_U(qs->qs_uquota, qfs_nblks);
     158  	printf(", ");
     159  	PRINT_FIELD_U(qs->qs_uquota, qfs_nextents);
     160  	printf("}, qs_gquota={");
     161  	PRINT_FIELD_U(qs->qs_gquota, qfs_ino);
     162  	printf(", ");
     163  	PRINT_FIELD_U(qs->qs_gquota, qfs_nblks);
     164  	printf(", ");
     165  	PRINT_FIELD_U(qs->qs_gquota, qfs_nextents);
     166  	printf("}, qs_pquota={");
     167  	PRINT_FIELD_U(qs->qs_pquota, qfs_ino);
     168  	printf(", ");
     169  	PRINT_FIELD_U(qs->qs_pquota, qfs_nblks);
     170  	printf(", ");
     171  	PRINT_FIELD_U(qs->qs_pquota, qfs_nextents);
     172  	printf("}, ");
     173  	PRINT_FIELD_D(*qs, qs_btimelimit);
     174  	printf(", ");
     175  	PRINT_FIELD_D(*qs, qs_itimelimit);
     176  	printf(", ");
     177  	PRINT_FIELD_D(*qs, qs_rtbtimelimit);
     178  	printf(", ");
     179  	PRINT_FIELD_U(*qs, qs_bwarnlimit);
     180  	printf(", ");
     181  	PRINT_FIELD_U(*qs, qs_iwarnlimit);
     182  #else
     183  	printf(", ...");
     184  #endif /* !VERBOSE */
     185  	printf("}");
     186  }
     187  
     188  int
     189  main(void)
     190  {
     191  	char *bogus_special = (char *) tail_alloc(1) + 1;
     192  	void *bogus_addr = (char *) tail_alloc(1) + 1;
     193  
     194  	char bogus_special_str[sizeof(void *) * 2 + sizeof("0x")];
     195  	char bogus_addr_str[sizeof(void *) * 2 + sizeof("0x")];
     196  	char unterminated_str[sizeof(void *) * 2 + sizeof("0x")];
     197  
     198  	static char invalid_cmd_str[1024];
     199  	TAIL_ALLOC_OBJECT_CONST_PTR(struct fs_disk_quota, xdq);
     200  	TAIL_ALLOC_OBJECT_CONST_PTR(struct fs_quota_stat, xqstat);
     201  	TAIL_ALLOC_OBJECT_CONST_PTR(struct fs_quota_statv, xqstatv);
     202  	TAIL_ALLOC_OBJECT_CONST_PTR(uint32_t, flags);
     203  	char *unterminated = tail_memdup(unterminated_data,
     204  					 sizeof(unterminated_data));
     205  
     206  	snprintf(bogus_special_str, sizeof(bogus_special_str), "%p",
     207  		 bogus_special);
     208  	snprintf(bogus_addr_str, sizeof(bogus_addr_str), "%p",
     209  		 bogus_addr);
     210  	snprintf(unterminated_str, sizeof(unterminated_str), "%p",
     211  		 unterminated);
     212  
     213  
     214  	/* Q_XQUOTAON */
     215  
     216  	*flags = 0xdeadbeef;
     217  
     218  	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
     219  		    ARG_STR(QCMD(Q_XQUOTAON, USRQUOTA)),
     220  		    ARG_STR("/dev/bogus/"), flags,
     221  		    "[FS_QUOTA_UDQ_ACCT|FS_QUOTA_UDQ_ENFD"
     222  		    "|FS_QUOTA_GDQ_ACCT|FS_QUOTA_GDQ_ENFD"
     223  		    "|FS_QUOTA_PDQ_ENFD|0xdeadbec0]");
     224  
     225  	snprintf(invalid_cmd_str, sizeof(invalid_cmd_str),
     226  		 "QCMD(Q_XQUOTAON, %#x /* ???QUOTA */)",
     227  		 QCMD_TYPE(QCMD(Q_XQUOTAON, 0xfacefeed)));
     228  	check_quota(CQF_ID_SKIP,
     229  		    QCMD(Q_XQUOTAON, 0xfacefeed), invalid_cmd_str,
     230  		    bogus_dev, bogus_dev_str, bogus_addr);
     231  
     232  
     233  	/* Q_XQUOTAOFF */
     234  
     235  	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
     236  		    ARG_STR(QCMD(Q_XQUOTAOFF, USRQUOTA)),
     237  		    bogus_special, bogus_special_str,
     238  		    bogus_addr, bogus_addr_str);
     239  	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
     240  		    ARG_STR(QCMD(Q_XQUOTAOFF, GRPQUOTA)),
     241  		    ARG_STR("/dev/bogus/"),
     242  		    ARG_STR(NULL));
     243  	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
     244  		    QCMD(Q_XQUOTAOFF, 3),
     245  		    "QCMD(Q_XQUOTAOFF, 0x3 /* ???QUOTA */)",
     246  		    ARG_STR("/dev/bogus/"), flags,
     247  		    "[FS_QUOTA_UDQ_ACCT|FS_QUOTA_UDQ_ENFD"
     248  		    "|FS_QUOTA_GDQ_ACCT|FS_QUOTA_GDQ_ENFD"
     249  		    "|FS_QUOTA_PDQ_ENFD|0xdeadbec0]");
     250  
     251  
     252  	/* Q_XGETQUOTA */
     253  
     254  	/* Trying our best to get successful result */
     255  	check_quota(CQF_ADDR_CB, ARG_STR(QCMD(Q_XGETQUOTA, USRQUOTA)),
     256  		    ARG_STR("/dev/sda1"), getuid(), xdq, print_xdisk_quota,
     257  		    (intptr_t) 1);
     258  
     259  	check_quota(CQF_ADDR_CB, ARG_STR(QCMD(Q_XGETQUOTA, GRPQUOTA)),
     260  		    ARG_STR(NULL), -1, xdq, print_xdisk_quota, (intptr_t) 1);
     261  
     262  
     263  	/* Q_XGETNEXTQUOTA */
     264  
     265  	check_quota(CQF_ADDR_CB, ARG_STR(QCMD(Q_XGETNEXTQUOTA, USRQUOTA)),
     266  		    ARG_STR("/dev/sda1"), 0, xdq, print_xdisk_quota,
     267  		    (intptr_t) 1);
     268  
     269  
     270  	/* Q_XSETQLIM */
     271  
     272  	check_quota(CQF_NONE, ARG_STR(QCMD(Q_XSETQLIM, PRJQUOTA)),
     273  		    bogus_special, bogus_special_str, 0, bogus_addr);
     274  
     275  	fill_memory_ex(xdq, sizeof(*xdq), 0x8e, 0x80);
     276  
     277  	check_quota(CQF_ADDR_CB, ARG_STR(QCMD(Q_XSETQLIM, PRJQUOTA)),
     278  		    bogus_dev, bogus_dev_str, 3141592653U,
     279  		    xdq, print_xdisk_quota, (intptr_t) 0);
     280  
     281  
     282  	/* Q_XGETQSTAT */
     283  
     284  	check_quota(CQF_ID_SKIP | CQF_ADDR_CB,
     285  		    ARG_STR(QCMD(Q_XGETQSTAT, USRQUOTA)),
     286  		    ARG_STR("/dev/sda1"), xqstat, print_xquota_stat, (intptr_t) 1);
     287  
     288  	check_quota(CQF_ID_SKIP | CQF_ADDR_CB,
     289  		    ARG_STR(QCMD(Q_XGETQSTAT, USRQUOTA)),
     290  		    ARG_STR("NULL"), xqstat, print_xquota_stat, (intptr_t) 1);
     291  
     292  	check_quota(CQF_ID_SKIP,
     293  		    ARG_STR(QCMD(Q_XGETQSTAT, PRJQUOTA)),
     294  		    unterminated, unterminated_str,
     295  		    xqstat + 1);
     296  
     297  
     298  	/* Q_XGETQSTATV */
     299  
     300  	check_quota(CQF_ID_SKIP | CQF_ADDR_CB,
     301  		    ARG_STR(QCMD(Q_XGETQSTATV, USRQUOTA)),
     302  		    ARG_STR("/dev/sda1"), xqstatv, print_xquota_statv, (intptr_t) 1);
     303  
     304  	check_quota(CQF_ID_SKIP | CQF_ADDR_CB,
     305  		    ARG_STR(QCMD(Q_XGETQSTATV, GRPQUOTA)),
     306  		    ARG_STR(NULL), xqstatv, print_xquota_statv, (intptr_t) 1);
     307  
     308  	check_quota(CQF_ID_SKIP,
     309  		    ARG_STR(QCMD(Q_XGETQSTATV, PRJQUOTA)),
     310  		    unterminated, unterminated_str,
     311  		    xqstatv + 1);
     312  
     313  
     314  	/* Q_XQUOTARM */
     315  
     316  	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
     317  		    ARG_STR(QCMD(Q_XQUOTARM, PRJQUOTA)),
     318  		    bogus_special, bogus_special_str, ARG_STR(NULL));
     319  	check_quota(CQF_ID_SKIP,
     320  		    ARG_STR(QCMD(Q_XQUOTARM, USRQUOTA)),
     321  		    unterminated, unterminated_str, flags + 1);
     322  
     323  	*flags = 0xdeadbeef;
     324  	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
     325  		    ARG_STR(QCMD(Q_XQUOTARM, GRPQUOTA)),
     326  		    ARG_STR(NULL), flags,
     327  		    "[FS_USER_QUOTA|FS_PROJ_QUOTA"
     328  		    "|FS_GROUP_QUOTA|0xdeadbee8]");
     329  
     330  
     331  	/* Q_XQUOTASYNC */
     332  
     333  	check_quota(CQF_ID_SKIP | CQF_ADDR_SKIP,
     334  		    ARG_STR(QCMD(Q_XQUOTASYNC, USRQUOTA)),
     335  		    bogus_special, bogus_special_str);
     336  	check_quota(CQF_ID_SKIP | CQF_ADDR_SKIP,
     337  		    QCMD(Q_XQUOTASYNC, 0xfff),
     338  		    "QCMD(Q_XQUOTASYNC, 0xff /* ???QUOTA */)",
     339  		    ARG_STR(NULL));
     340  
     341  	puts("+++ exited with 0 +++");
     342  
     343  	return 0;
     344  }